summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-13 13:22:39 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-21 18:55:13 +0100
commitf4a76e7cc6d1c402e990e2111fb94afb305fb974 (patch)
tree8911bf1533aa50f3340202df87cb014bf8f61c1c /sound
parentASoC: arizona: Log thermal events (diff)
downloadlinux-f4a76e7cc6d1c402e990e2111fb94afb305fb974.tar.xz
linux-f4a76e7cc6d1c402e990e2111fb94afb305fb974.zip
ASoC: arizona: Suppress speaker enable if thermal shutdown is flagged
Ensure that the device state does not diverge from the state we have set in the register map in order to make the behaviour clearer. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/arizona.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 895ddf007de2..6c773804ffe0 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -75,6 +75,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
bool manual_ena = false;
+ int val;
switch (arizona->type) {
case WM5102:
@@ -97,6 +98,16 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
}
break;
case SND_SOC_DAPM_POST_PMU:
+ val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
+ if (val & ARIZONA_SPK_SHUTDOWN_STS) {
+ dev_crit(arizona->dev,
+ "Speaker not enabled due to temperature\n");
+ return -EBUSY;
+ }
+
+ snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
+ 1 << w->shift, 1 << w->shift);
+
if (priv->spk_ena_pending) {
msleep(75);
snd_soc_write(codec, 0x4f5, 0xda);
@@ -110,6 +121,9 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
if (!priv->spk_ena)
snd_soc_write(codec, 0x4f5, 0x25a);
}
+
+ snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
+ 1 << w->shift, 0);
break;
case SND_SOC_DAPM_POST_PMD:
if (manual_ena) {
@@ -153,18 +167,26 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
ret);
} else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
dev_crit(arizona->dev, "Thermal shutdown\n");
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_OUTPUT_ENABLES_1,
+ ARIZONA_OUT4L_ENA |
+ ARIZONA_OUT4R_ENA, 0);
+ if (ret != 0)
+ dev_crit(arizona->dev,
+ "Failed to disable speaker outputs: %d\n",
+ ret);
}
return IRQ_HANDLED;
}
static const struct snd_soc_dapm_widget arizona_spkl =
- SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
+ SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
static const struct snd_soc_dapm_widget arizona_spkr =
- SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
+ SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);