Loading sound/soc/codecs/wm8993.c +81 −18 Original line number Diff line number Diff line Loading @@ -218,6 +218,8 @@ struct wm8993_priv { struct snd_soc_codec codec; int master; int sysclk_source; int tdm_slots; int tdm_width; unsigned int mclk_rate; unsigned int sysclk_rate; unsigned int fs; Loading Loading @@ -1107,6 +1109,11 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, /* What BCLK do we need? */ wm8993->fs = params_rate(params); wm8993->bclk = 2 * wm8993->fs; if (wm8993->tdm_slots) { dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n", wm8993->tdm_slots, wm8993->tdm_width); wm8993->bclk *= wm8993->tdm_width * wm8993->tdm_slots; } else { switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: wm8993->bclk *= 16; Loading @@ -1126,6 +1133,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, default: return -EINVAL; } } dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk); Loading Loading @@ -1243,12 +1251,67 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } static int wm8993_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 wm8993_priv *wm8993 = codec->private_data; int aif1 = 0; int aif2 = 0; /* Don't need to validate anything if we're turning off TDM */ if (slots == 0) { wm8993->tdm_slots = 0; goto out; } /* Note that we allow configurations we can't handle ourselves - * for example, we can generate clocks for slots 2 and up even if * we can't use those slots ourselves. */ aif1 |= WM8993_AIFADC_TDM; aif2 |= WM8993_AIFDAC_TDM; switch (rx_mask) { case 3: break; case 0xc: aif1 |= WM8993_AIFADC_TDM_CHAN; break; default: return -EINVAL; } switch (tx_mask) { case 3: break; case 0xc: aif2 |= WM8993_AIFDAC_TDM_CHAN; break; default: return -EINVAL; } out: wm8993->tdm_width = slot_width; wm8993->tdm_slots = slots / 2; snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_1, WM8993_AIFADC_TDM | WM8993_AIFADC_TDM_CHAN, aif1); snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_2, WM8993_AIFDAC_TDM | WM8993_AIFDAC_TDM_CHAN, aif2); return 0; } static struct snd_soc_dai_ops wm8993_ops = { .set_sysclk = wm8993_set_sysclk, .set_fmt = wm8993_set_dai_fmt, .hw_params = wm8993_hw_params, .digital_mute = wm8993_digital_mute, .set_pll = wm8993_set_fll, .set_tdm_slot = wm8993_set_tdm_slot, }; #define WM8993_RATES SNDRV_PCM_RATE_8000_48000 Loading Loading
sound/soc/codecs/wm8993.c +81 −18 Original line number Diff line number Diff line Loading @@ -218,6 +218,8 @@ struct wm8993_priv { struct snd_soc_codec codec; int master; int sysclk_source; int tdm_slots; int tdm_width; unsigned int mclk_rate; unsigned int sysclk_rate; unsigned int fs; Loading Loading @@ -1107,6 +1109,11 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, /* What BCLK do we need? */ wm8993->fs = params_rate(params); wm8993->bclk = 2 * wm8993->fs; if (wm8993->tdm_slots) { dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n", wm8993->tdm_slots, wm8993->tdm_width); wm8993->bclk *= wm8993->tdm_width * wm8993->tdm_slots; } else { switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: wm8993->bclk *= 16; Loading @@ -1126,6 +1133,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, default: return -EINVAL; } } dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk); Loading Loading @@ -1243,12 +1251,67 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } static int wm8993_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 wm8993_priv *wm8993 = codec->private_data; int aif1 = 0; int aif2 = 0; /* Don't need to validate anything if we're turning off TDM */ if (slots == 0) { wm8993->tdm_slots = 0; goto out; } /* Note that we allow configurations we can't handle ourselves - * for example, we can generate clocks for slots 2 and up even if * we can't use those slots ourselves. */ aif1 |= WM8993_AIFADC_TDM; aif2 |= WM8993_AIFDAC_TDM; switch (rx_mask) { case 3: break; case 0xc: aif1 |= WM8993_AIFADC_TDM_CHAN; break; default: return -EINVAL; } switch (tx_mask) { case 3: break; case 0xc: aif2 |= WM8993_AIFDAC_TDM_CHAN; break; default: return -EINVAL; } out: wm8993->tdm_width = slot_width; wm8993->tdm_slots = slots / 2; snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_1, WM8993_AIFADC_TDM | WM8993_AIFADC_TDM_CHAN, aif1); snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_2, WM8993_AIFDAC_TDM | WM8993_AIFDAC_TDM_CHAN, aif2); return 0; } static struct snd_soc_dai_ops wm8993_ops = { .set_sysclk = wm8993_set_sysclk, .set_fmt = wm8993_set_dai_fmt, .hw_params = wm8993_hw_params, .digital_mute = wm8993_digital_mute, .set_pll = wm8993_set_fll, .set_tdm_slot = wm8993_set_tdm_slot, }; #define WM8993_RATES SNDRV_PCM_RATE_8000_48000 Loading