diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-08-11 11:28:39 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-08-11 11:29:21 -0400 |
commit | e0026beac0f1a6253488478b3f022ff243b012b9 (patch) | |
tree | a4d9eb2eb02ea90cdfe5e0074545c0887e3c4e4e /sound/soc/codecs | |
parent | 1921bab217c2c21e4b8dc78332f6ae11515fc014 (diff) |
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>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/wm9081.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index c147f2b8723d..c64e55aa63b6 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -165,6 +165,7 @@ struct wm9081_priv { | |||
165 | int master; | 165 | int master; |
166 | int fll_fref; | 166 | int fll_fref; |
167 | int fll_fout; | 167 | int fll_fout; |
168 | int tdm_width; | ||
168 | struct wm9081_retune_mobile_config *retune; | 169 | struct wm9081_retune_mobile_config *retune; |
169 | }; | 170 | }; |
170 | 171 | ||
@@ -981,33 +982,37 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream, | |||
981 | aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4); | 982 | aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4); |
982 | aif4 &= ~WM9081_LRCLK_RATE_MASK; | 983 | aif4 &= ~WM9081_LRCLK_RATE_MASK; |
983 | 984 | ||
984 | /* What BCLK do we need? */ | ||
985 | wm9081->fs = params_rate(params); | 985 | wm9081->fs = params_rate(params); |
986 | wm9081->bclk = 2 * wm9081->fs; | ||
987 | switch (params_format(params)) { | ||
988 | case SNDRV_PCM_FORMAT_S16_LE: | ||
989 | wm9081->bclk *= 16; | ||
990 | break; | ||
991 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
992 | wm9081->bclk *= 20; | ||
993 | aif2 |= 0x4; | ||
994 | break; | ||
995 | case SNDRV_PCM_FORMAT_S24_LE: | ||
996 | wm9081->bclk *= 24; | ||
997 | aif2 |= 0x8; | ||
998 | break; | ||
999 | case SNDRV_PCM_FORMAT_S32_LE: | ||
1000 | wm9081->bclk *= 32; | ||
1001 | aif2 |= 0xc; | ||
1002 | break; | ||
1003 | default: | ||
1004 | return -EINVAL; | ||
1005 | } | ||
1006 | 986 | ||
1007 | if (aif1 & WM9081_AIFDAC_TDM_MODE_MASK) { | 987 | if (wm9081->tdm_width) { |
988 | /* If TDM is set up then that fixes our BCLK. */ | ||
1008 | int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> | 989 | int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> |
1009 | WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; | 990 | WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; |
1010 | wm9081->bclk *= slots; | 991 | |
992 | wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots; | ||
993 | } else { | ||
994 | /* Otherwise work out a BCLK from the sample size */ | ||
995 | wm9081->bclk = 2 * wm9081->fs; | ||
996 | |||
997 | switch (params_format(params)) { | ||
998 | case SNDRV_PCM_FORMAT_S16_LE: | ||
999 | wm9081->bclk *= 16; | ||
1000 | break; | ||
1001 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
1002 | wm9081->bclk *= 20; | ||
1003 | aif2 |= 0x4; | ||
1004 | break; | ||
1005 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1006 | wm9081->bclk *= 24; | ||
1007 | aif2 |= 0x8; | ||
1008 | break; | ||
1009 | case SNDRV_PCM_FORMAT_S32_LE: | ||
1010 | wm9081->bclk *= 32; | ||
1011 | aif2 |= 0xc; | ||
1012 | break; | ||
1013 | default: | ||
1014 | return -EINVAL; | ||
1015 | } | ||
1011 | } | 1016 | } |
1012 | 1017 | ||
1013 | dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk); | 1018 | 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 | return 0; | 1154 | return 0; |
1150 | } | 1155 | } |
1151 | 1156 | ||
1152 | /* FIXME: Needs to handle slot_width */ | ||
1153 | static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, | 1157 | static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, |
1154 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) | 1158 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
1155 | { | 1159 | { |
1156 | struct snd_soc_codec *codec = dai->codec; | 1160 | struct snd_soc_codec *codec = dai->codec; |
1161 | struct wm9081_priv *wm9081 = codec->private_data; | ||
1157 | unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1); | 1162 | unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1); |
1158 | 1163 | ||
1159 | aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); | 1164 | aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); |
1160 | 1165 | ||
1161 | if (slots < 1 || slots > 4) | 1166 | if (slots < 0 || slots > 4) |
1162 | return -EINVAL; | 1167 | return -EINVAL; |
1163 | 1168 | ||
1169 | wm9081->tdm_width = slot_width; | ||
1170 | |||
1171 | if (slots == 0) | ||
1172 | slots = 1; | ||
1173 | |||
1164 | aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; | 1174 | aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; |
1165 | 1175 | ||
1166 | switch (rx_mask) { | 1176 | switch (rx_mask) { |