ASoC: wm8994: Only enable extra BCLK cycles when required

Rather than always assuming the maximum possible BCLK rate will be
required generate BCLKs for stereo if either one or two channels is
enabled. In order to support this we also need to ensure that only
the relevant channels are enabled.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Mark Brown 2012-10-01 15:28:30 +01:00
parent 6f0c0580b7
commit 79748cdb39
2 changed files with 18 additions and 1 deletions

View file

@ -1045,6 +1045,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = codec->control_data;
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
int i;
@ -1063,6 +1064,10 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
/* Don't enable timeslot 2 if not in use */
if (wm8994->channels[0] <= 2)
mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
if ((val & WM8994_AIF1ADCL_SRC) &&
(val & WM8994_AIF1ADCR_SRC))
@ -2687,7 +2692,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
bclk_rate = params_rate(params) * 4;
bclk_rate = params_rate(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
bclk_rate *= 16;
@ -2708,6 +2713,17 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
wm8994->channels[id] = params_channels(params);
switch (params_channels(params)) {
case 1:
case 2:
bclk_rate *= 2;
break;
default:
bclk_rate *= 4;
break;
}
/* Try to find an appropriate sample rate; look for an exact match. */
for (i = 0; i < ARRAY_SIZE(srs); i++)
if (srs[i].rate == params_rate(params))

View file

@ -77,6 +77,7 @@ struct wm8994_priv {
int sysclk_rate[2];
int mclk[2];
int aifclk[2];
int channels[2];
struct wm8994_fll_config fll[2], fll_suspend[2];
struct completion fll_locked[2];
bool fll_locked_irq;