aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-22 13:36:53 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-26 11:45:25 -0400
commitf607e31ce3963327f749b56c65dfec2642aa623c (patch)
tree162bbbdde8a4b108dd9399f244da51c207bdebd6
parent03409071ce2751ca124f35edebe4bcad52de22c2 (diff)
ASoC: arizona: Fix interaction between headphone outputs and identification
Running HPDET while the headphone outputs are enabled can disrupt the operation of HPDET. In order to avoid this HPDET needs to disable the headphone outputs and ASoC needs to not enable them while HPDET is running. Do the ASoC side of this by storing the enable state in the core driver structure and only writing to the device if a flag indicating that the accessory detection side is in a state where it can have the headphone output stage enabled. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--include/linux/mfd/arizona/core.h3
-rw-r--r--sound/soc/codecs/arizona.c33
-rw-r--r--sound/soc/codecs/arizona.h3
-rw-r--r--sound/soc/codecs/wm5102.c8
-rw-r--r--sound/soc/codecs/wm5110.c8
5 files changed, 47 insertions, 8 deletions
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index a710255528d7..cc281368dc55 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -100,6 +100,9 @@ struct arizona {
100 struct regmap_irq_chip_data *aod_irq_chip; 100 struct regmap_irq_chip_data *aod_irq_chip;
101 struct regmap_irq_chip_data *irq_chip; 101 struct regmap_irq_chip_data *irq_chip;
102 102
103 bool hpdet_magic;
104 unsigned int hp_ena;
105
103 struct mutex clk_lock; 106 struct mutex clk_lock;
104 int clk32k_ref; 107 int clk32k_ref;
105 108
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ac948a671ea6..e7d34711412c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -364,6 +364,39 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
364} 364}
365EXPORT_SYMBOL_GPL(arizona_out_ev); 365EXPORT_SYMBOL_GPL(arizona_out_ev);
366 366
367int arizona_hp_ev(struct snd_soc_dapm_widget *w,
368 struct snd_kcontrol *kcontrol,
369 int event)
370{
371 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
372 unsigned int mask = 1 << w->shift;
373 unsigned int val;
374
375 switch (event) {
376 case SND_SOC_DAPM_POST_PMU:
377 val = mask;
378 break;
379 case SND_SOC_DAPM_PRE_PMD:
380 val = 0;
381 break;
382 default:
383 return -EINVAL;
384 }
385
386 /* Store the desired state for the HP outputs */
387 priv->arizona->hp_ena &= ~mask;
388 priv->arizona->hp_ena |= val;
389
390 /* Force off if HPDET magic is active */
391 if (priv->arizona->hpdet_magic)
392 val = 0;
393
394 snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
395
396 return arizona_out_ev(w, kcontrol, event);
397}
398EXPORT_SYMBOL_GPL(arizona_hp_ev);
399
367static unsigned int arizona_sysclk_48k_rates[] = { 400static unsigned int arizona_sysclk_48k_rates[] = {
368 6144000, 401 6144000,
369 12288000, 402 12288000,
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 116372c91f5d..13dd2916b721 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -184,6 +184,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
184extern int arizona_out_ev(struct snd_soc_dapm_widget *w, 184extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
185 struct snd_kcontrol *kcontrol, 185 struct snd_kcontrol *kcontrol,
186 int event); 186 int event);
187extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
188 struct snd_kcontrol *kcontrol,
189 int event);
187 190
188extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 191extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
189 int source, unsigned int freq, int dir); 192 int source, unsigned int freq, int dir);
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index b82bbf584146..2657aad3f8b1 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1131,11 +1131,11 @@ ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
1131SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, 1131SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1132 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), 1132 ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
1133 1133
1134SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 1134SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
1135 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1135 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1136 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1136 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1137SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 1137SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
1138 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1138 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1139 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1140SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 1140SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
1141 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 1141 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index cdeb301da1f6..7841b42a819c 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -551,11 +551,11 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
551SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 551SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
552 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 552 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
553 553
554SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, 554SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
555 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 555 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
556 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 556 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
557SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, 557SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
558 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 558 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
559 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 559 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
560SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, 560SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
561 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, 561 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,