ASoC: cs42l51: add support of master mode

Add support of master mode for cs42l51 cirrus audio codec.

Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Olivier Moysan 2019-04-03 15:23:34 +02:00 committed by Mark Brown
parent 11b9cd748e
commit 2f7c4ce09a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -340,6 +340,19 @@ static struct cs42l51_ratios slave_auto_ratios[] = {
{ 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 }, { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
}; };
/*
* Master mode mclk/fs ratios.
* Recommended configurations are SSM for 4-50khz and DSM for 50-100kHz ranges
* The table below provides support of following ratios:
* 128: SSM (%128) with div2 disabled
* 256: SSM (%128) with div2 enabled
* In both cases, if sampling rate is above 50kHz, SSM is overridden
* with DSM (%128) configuration
*/
static struct cs42l51_ratios master_ratios[] = {
{ 128, CS42L51_SSM_MODE, 0 }, { 256, CS42L51_SSM_MODE, 1 },
};
static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir) int clk_id, unsigned int freq, int dir)
{ {
@ -362,11 +375,13 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
unsigned int ratio; unsigned int ratio;
struct cs42l51_ratios *ratios = NULL; struct cs42l51_ratios *ratios = NULL;
int nr_ratios = 0; int nr_ratios = 0;
int intf_ctl, power_ctl, fmt; int intf_ctl, power_ctl, fmt, mode;
switch (cs42l51->func) { switch (cs42l51->func) {
case MODE_MASTER: case MODE_MASTER:
return -EINVAL; ratios = master_ratios;
nr_ratios = ARRAY_SIZE(master_ratios);
break;
case MODE_SLAVE: case MODE_SLAVE:
ratios = slave_ratios; ratios = slave_ratios;
nr_ratios = ARRAY_SIZE(slave_ratios); nr_ratios = ARRAY_SIZE(slave_ratios);
@ -402,7 +417,16 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
switch (cs42l51->func) { switch (cs42l51->func) {
case MODE_MASTER: case MODE_MASTER:
intf_ctl |= CS42L51_INTF_CTL_MASTER; intf_ctl |= CS42L51_INTF_CTL_MASTER;
power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode); mode = ratios[i].speed_mode;
/* Force DSM mode if sampling rate is above 50kHz */
if (rate > 50000)
mode = CS42L51_DSM_MODE;
power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(mode);
/*
* Auto detect mode is not applicable for master mode and has to
* be disabled. Otherwise SPEED[1:0] bits will be ignored.
*/
power_ctl &= ~CS42L51_MIC_POWER_CTL_AUTO;
break; break;
case MODE_SLAVE: case MODE_SLAVE:
power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode); power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);