Skip to content

Commit 8eb7be4

Browse files
marcanjannau
authored andcommitted
ASoC: tas2770: Power cycle amp on ISENSE/VSENSE change
The ISENSE/VSENSE blocks are only powered up when the amplifier transitions from shutdown to active. This means that if those controls are flipped on while the amplifier is already playing back audio, they will have no effect. Fix this by forcing a power cycle around transitions in those controls. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 1631d33 commit 8eb7be4

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

sound/soc/codecs/tas2770.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,41 @@ static const struct snd_kcontrol_new isense_switch =
165165
static const struct snd_kcontrol_new vsense_switch =
166166
SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 2, 1, 1);
167167

168+
static int sense_event(struct snd_soc_dapm_widget *w,
169+
struct snd_kcontrol *kcontrol, int event)
170+
{
171+
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
172+
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
173+
int ret = 0;
174+
175+
/*
176+
* Powering up ISENSE/VSENSE requires a trip through the shutdown state.
177+
* Do that here to ensure that our changes are applied properly, otherwise
178+
* we might end up with non-functional IVSENSE if playback started earlier,
179+
* which would break software speaker protection.
180+
*/
181+
182+
switch (event) {
183+
case SND_SOC_DAPM_PRE_REG:
184+
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
185+
TAS2770_PWR_CTRL_MASK,
186+
TAS2770_PWR_CTRL_SHUTDOWN);
187+
break;
188+
case SND_SOC_DAPM_POST_REG:
189+
ret = tas2770_update_pwr_ctrl(tas2770);
190+
break;
191+
}
192+
193+
return 0;
194+
}
195+
168196
static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = {
169197
SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
170198
SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2770_asi1_mux),
171-
SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch),
172-
SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch),
199+
SND_SOC_DAPM_SWITCH_E("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch,
200+
sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
201+
SND_SOC_DAPM_SWITCH_E("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch,
202+
sense_event, SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
173203
SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event,
174204
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
175205
SND_SOC_DAPM_OUTPUT("OUT"),

0 commit comments

Comments
 (0)