ASoC: Manage mode and rate bits correctly for CS4271 CODEC.
Subsystems (3)
PATCH 2/6 ASoC: Manage mode and rate bits correctly for CS4271 CODEC.
From: Alexander Sverdlin <[email protected]>
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 <[email protected]>
--- sound/soc/codecs/cs4271.c | 83 ++++++++++++++++++++++++++++---------------- 1 files changed, 53 insertions(+), 30 deletions(-)
sound/soc/codecs/cs4271.c +53 -30
@@ -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);
Quoted 6 lines · Alexander Sverdlin
From: Alexander Sverdlin <[email protected]>
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 <[email protected]>
Applied the rest of these now, thanks.