aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-11 11:28:39 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-11 11:29:21 -0400
commite0026beac0f1a6253488478b3f022ff243b012b9 (patch)
treea4d9eb2eb02ea90cdfe5e0074545c0887e3c4e4e /sound/soc/codecs
parent1921bab217c2c21e4b8dc78332f6ae11515fc014 (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.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index c147f2b8723..c64e55aa63b 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 */
1153static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, 1157static 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) {