aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-22 13:38:03 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-26 11:45:26 -0400
commitdf8c3dbee9e6f19ddb0ae8e05cdf76eb2d3b7f00 (patch)
treea2a434ff045668a9be5f23a36e24a096796a0965
parentf607e31ce3963327f749b56c65dfec2642aa623c (diff)
extcon: 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. For extcon instead of checking if the headphone output is enabled when doing magic application unconditionally disable the output and restore the state which ASoC wants set when undoing the magic. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--drivers/extcon/extcon-arizona.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 896a923546e0..b28927972128 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -104,29 +104,45 @@ static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
104 unsigned int magic) 104 unsigned int magic)
105{ 105{
106 struct arizona *arizona = info->arizona; 106 struct arizona *arizona = info->arizona;
107 unsigned int val;
108 int ret; 107 int ret;
109 108
110 mutex_lock(&arizona->dapm->card->dapm_mutex); 109 mutex_lock(&arizona->dapm->card->dapm_mutex);
111 110
112 ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); 111 arizona->hpdet_magic = magic;
113 if (ret != 0) {
114 dev_err(arizona->dev, "Failed to read output enables: %d\n",
115 ret);
116 val = 0;
117 }
118 112
119 if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { 113 /* Keep the HP output stages disabled while doing the magic */
120 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 114 if (magic) {
121 magic); 115 ret = regmap_update_bits(arizona->regmap,
116 ARIZONA_OUTPUT_ENABLES_1,
117 ARIZONA_OUT1L_ENA |
118 ARIZONA_OUT1R_ENA, 0);
122 if (ret != 0) 119 if (ret != 0)
123 dev_warn(arizona->dev, "Failed to do magic: %d\n", 120 dev_warn(arizona->dev,
121 "Failed to disable headphone outputs: %d\n",
122 ret);
123 }
124
125 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
126 magic);
127 if (ret != 0)
128 dev_warn(arizona->dev, "Failed to do magic: %d\n",
124 ret); 129 ret);
125 130
126 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 131 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
127 magic); 132 magic);
133 if (ret != 0)
134 dev_warn(arizona->dev, "Failed to do magic: %d\n",
135 ret);
136
137 /* Restore the desired state while not doing the magic */
138 if (!magic) {
139 ret = regmap_update_bits(arizona->regmap,
140 ARIZONA_OUTPUT_ENABLES_1,
141 ARIZONA_OUT1L_ENA |
142 ARIZONA_OUT1R_ENA, arizona->hp_ena);
128 if (ret != 0) 143 if (ret != 0)
129 dev_warn(arizona->dev, "Failed to do magic: %d\n", 144 dev_warn(arizona->dev,
145 "Failed to restore headphone outputs: %d\n",
130 ret); 146 ret);
131 } 147 }
132 148