aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
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) {