mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
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: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
1921bab217
commit
e0026beac0
@ -165,6 +165,7 @@ struct wm9081_priv {
|
||||
int master;
|
||||
int fll_fref;
|
||||
int fll_fout;
|
||||
int tdm_width;
|
||||
struct wm9081_retune_mobile_config *retune;
|
||||
};
|
||||
|
||||
@ -981,33 +982,37 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
|
||||
aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
|
||||
aif4 &= ~WM9081_LRCLK_RATE_MASK;
|
||||
|
||||
/* What BCLK do we need? */
|
||||
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) >>
|
||||
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);
|
||||
@ -1149,18 +1154,23 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: Needs to handle slot_width */
|
||||
static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
|
||||
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
|
||||
{
|
||||
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);
|
||||
|
||||
aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
|
||||
|
||||
if (slots < 1 || slots > 4)
|
||||
if (slots < 0 || slots > 4)
|
||||
return -EINVAL;
|
||||
|
||||
wm9081->tdm_width = slot_width;
|
||||
|
||||
if (slots == 0)
|
||||
slots = 1;
|
||||
|
||||
aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT;
|
||||
|
||||
switch (rx_mask) {
|
||||
|
Loading…
Reference in New Issue
Block a user