Commit e0026bea authored by Mark Brown's avatar Mark Brown

ASoC: Update WM9081 for tdm_slot() API change

Store the TDM slot width then if it's set use that rather than the
sample size to calculate BCLK. Leave imposing constraints to the
core (which should do this but doesn't yet) or machine driver.

Also allow 0 TDM slots to be configure (for use when disabling TDM).
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 1921bab2
...@@ -165,6 +165,7 @@ struct wm9081_priv { ...@@ -165,6 +165,7 @@ struct wm9081_priv {
int master; int master;
int fll_fref; int fll_fref;
int fll_fout; int fll_fout;
int tdm_width;
struct wm9081_retune_mobile_config *retune; struct wm9081_retune_mobile_config *retune;
}; };
...@@ -981,33 +982,37 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream, ...@@ -981,33 +982,37 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4); aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
aif4 &= ~WM9081_LRCLK_RATE_MASK; aif4 &= ~WM9081_LRCLK_RATE_MASK;
/* What BCLK do we need? */
wm9081->fs = params_rate(params); wm9081->fs = params_rate(params);
wm9081->bclk = 2 * wm9081->fs;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
wm9081->bclk *= 16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
wm9081->bclk *= 20;
aif2 |= 0x4;
break;
case SNDRV_PCM_FORMAT_S24_LE:
wm9081->bclk *= 24;
aif2 |= 0x8;
break;
case SNDRV_PCM_FORMAT_S32_LE:
wm9081->bclk *= 32;
aif2 |= 0xc;
break;
default:
return -EINVAL;
}
if (aif1 & WM9081_AIFDAC_TDM_MODE_MASK) { if (wm9081->tdm_width) {
/* If TDM is set up then that fixes our BCLK. */
int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >>
WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; WM9081_AIFDAC_TDM_MODE_SHIFT) + 1;
wm9081->bclk *= slots;
wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots;
} else {
/* Otherwise work out a BCLK from the sample size */
wm9081->bclk = 2 * wm9081->fs;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
wm9081->bclk *= 16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
wm9081->bclk *= 20;
aif2 |= 0x4;
break;
case SNDRV_PCM_FORMAT_S24_LE:
wm9081->bclk *= 24;
aif2 |= 0x8;
break;
case SNDRV_PCM_FORMAT_S32_LE:
wm9081->bclk *= 32;
aif2 |= 0xc;
break;
default:
return -EINVAL;
}
} }
dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk); dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk);
...@@ -1149,18 +1154,23 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, ...@@ -1149,18 +1154,23 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
return 0; return 0;
} }
/* FIXME: Needs to handle slot_width */
static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct wm9081_priv *wm9081 = codec->private_data;
unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1); unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
if (slots < 1 || slots > 4) if (slots < 0 || slots > 4)
return -EINVAL; return -EINVAL;
wm9081->tdm_width = slot_width;
if (slots == 0)
slots = 1;
aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT;
switch (rx_mask) { switch (rx_mask) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment