aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-13 08:22:39 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-21 13:55:13 -0400
commitf4a76e7cc6d1c402e990e2111fb94afb305fb974 (patch)
tree8911bf1533aa50f3340202df87cb014bf8f61c1c /sound
parent899817e27a58038546b53bc42eeaa4aae5a886cb (diff)
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,
75 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 75 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
76 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 76 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
77 bool manual_ena = false; 77 bool manual_ena = false;
78 int val;
78 79
79 switch (arizona->type) { 80 switch (arizona->type) {
80 case WM5102: 81 case WM5102:
@@ -97,6 +98,16 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
97 } 98 }
98 break; 99 break;
99 case SND_SOC_DAPM_POST_PMU: 100 case SND_SOC_DAPM_POST_PMU:
101 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
102 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
103 dev_crit(arizona->dev,
104 "Speaker not enabled due to temperature\n");
105 return -EBUSY;
106 }
107
108 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
109 1 << w->shift, 1 << w->shift);
110
100 if (priv->spk_ena_pending) { 111 if (priv->spk_ena_pending) {
101 msleep(75); 112 msleep(75);
102 snd_soc_write(codec, 0x4f5, 0xda); 113 snd_soc_write(codec, 0x4f5, 0xda);
@@ -110,6 +121,9 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
110 if (!priv->spk_ena) 121 if (!priv->spk_ena)
111 snd_soc_write(codec, 0x4f5, 0x25a); 122 snd_soc_write(codec, 0x4f5, 0x25a);
112 } 123 }
124
125 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
126 1 << w->shift, 0);
113 break; 127 break;
114 case SND_SOC_DAPM_POST_PMD: 128 case SND_SOC_DAPM_POST_PMD:
115 if (manual_ena) { 129 if (manual_ena) {
@@ -153,18 +167,26 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
153 ret); 167 ret);
154 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { 168 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
155 dev_crit(arizona->dev, "Thermal shutdown\n"); 169 dev_crit(arizona->dev, "Thermal shutdown\n");
170 ret = regmap_update_bits(arizona->regmap,
171 ARIZONA_OUTPUT_ENABLES_1,
172 ARIZONA_OUT4L_ENA |
173 ARIZONA_OUT4R_ENA, 0);
174 if (ret != 0)
175 dev_crit(arizona->dev,
176 "Failed to disable speaker outputs: %d\n",
177 ret);
156 } 178 }
157 179
158 return IRQ_HANDLED; 180 return IRQ_HANDLED;
159} 181}
160 182
161static const struct snd_soc_dapm_widget arizona_spkl = 183static const struct snd_soc_dapm_widget arizona_spkl =
162 SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, 184 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
163 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 185 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
164 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 186 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
165 187
166static const struct snd_soc_dapm_widget arizona_spkr = 188static const struct snd_soc_dapm_widget arizona_spkr =
167 SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, 189 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
168 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 190 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
169 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 191 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
170 192