diff options
author | Alexander Sverdlin <subaparts@yandex.ru> | 2011-03-07 20:29:45 +0300 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-03-09 16:08:16 +0300 |
commit | 5c3a12e96c9f3158602b2feac8583ae35c10b80e (patch) | |
tree | bb7ef9f5cd61d8f97a636bb668f772c9ce1f19a4 /sound/soc/codecs | |
parent | 15086ded21ee7f065ad290c1edfdc49cf18cf96e (diff) | |
download | linux-5c3a12e96c9f3158602b2feac8583ae35c10b80e.tar.xz |
ASoC: Manage mode and rate bits correctly for CS4271 CODEC.
Manage mode and rate bits correctly, according to datasheet in CS4271 CODEC.
This is done to make capture work properly.
Signed-off-by: Alexander Sverdlin <subaparts@yandex.ru>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/cs4271.c | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 538e814136d3..083aab96ca80 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -168,27 +168,6 @@ struct cs4271_private { int gpio_disable; }; -struct cs4271_clk_cfg { - unsigned int ratio; /* MCLK / sample rate */ - u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */ - u8 mclk_master; /* ratio bit mask for Master mode */ - u8 mclk_slave; /* ratio bit mask for Slave mode */ -}; - -static struct cs4271_clk_cfg cs4271_clk_tab[] = { - {64, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1}, - {96, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1}, - {128, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1}, - {192, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1}, - {256, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1}, - {384, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1}, - {512, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_2, CS4271_MODE1_DIV_1}, - {768, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3}, - {1024, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3} -}; - -#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab) - /* * @freq is the desired MCLK rate * MCLK rate should (c) be the sample rate, multiplied by one of the @@ -297,6 +276,45 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, return cs4271_set_deemph(codec); } +struct cs4271_clk_cfg { + bool master; /* codec mode */ + u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */ + unsigned short ratio; /* MCLK / sample rate */ + u8 ratio_mask; /* ratio bit mask for Master mode */ +}; + +static struct cs4271_clk_cfg cs4271_clk_tab[] = { + {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1}, + {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15}, + {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2}, + {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3}, + {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1}, + {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15}, + {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2}, + {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3}, + {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1}, + {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15}, + {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2}, + {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3}, + {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2}, + {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2}, + {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2}, + {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2}, + {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1}, + {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2}, + {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2}, +}; + +#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab) + static int cs4271_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -308,23 +326,28 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream, unsigned int ratio, val; cs4271->rate = params_rate(params); + + /* Configure DAC */ + if (cs4271->rate < 50000) + val = CS4271_MODE1_MODE_1X; + else if (cs4271->rate < 100000) + val = CS4271_MODE1_MODE_2X; + else + val = CS4271_MODE1_MODE_4X; + ratio = cs4271->mclk / cs4271->rate; for (i = 0; i < CS4171_NR_RATIOS; i++) - if (cs4271_clk_tab[i].ratio == ratio) + if ((cs4271_clk_tab[i].master == cs4271->master) && + (cs4271_clk_tab[i].speed_mode == val) && + (cs4271_clk_tab[i].ratio == ratio)) break; - if ((i == CS4171_NR_RATIOS) || ((ratio == 1024) && cs4271->master)) { + if (i == CS4171_NR_RATIOS) { dev_err(codec->dev, "Invalid sample rate\n"); return -EINVAL; } - /* Configure DAC */ - val = cs4271_clk_tab[i].speed_mode; - - if (cs4271->master) - val |= cs4271_clk_tab[i].mclk_master; - else - val |= cs4271_clk_tab[i].mclk_slave; + val |= cs4271_clk_tab[i].ratio_mask; ret = snd_soc_update_bits(codec, CS4271_MODE1, CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); |