diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 2ad0e4a35a23..cfd206c4797c 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -489,6 +489,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; int report = ARIZONA_CABLE_HEADPHONE; + unsigned int val; int ret, reading; mutex_lock(&info->lock); @@ -543,13 +544,28 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) dev_err(arizona->dev, "Failed to report HP/line: %d\n", ret); - ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); - if (ret != 0) - dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret); + mutex_lock(&arizona->dapm->card->dapm_mutex); - ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); - if (ret != 0) - dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret); + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read output enables: %d\n", + ret); + val = 0; + } + + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); + if (ret != 0) + dev_warn(arizona->dev, "Failed to undo magic: %d\n", + ret); + + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); + if (ret != 0) + dev_warn(arizona->dev, "Failed to undo magic: %d\n", + ret); + } + + mutex_unlock(&arizona->dapm->card->dapm_mutex); done: if (id_gpio) @@ -637,6 +653,7 @@ err: static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) { struct arizona *arizona = info->arizona; + unsigned int val; int ret; dev_dbg(arizona->dev, "Starting identification via HPDET\n"); @@ -648,13 +665,30 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) arizona_extcon_pulse_micbias(info); - ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); + mutex_lock(&arizona->dapm->card->dapm_mutex); - ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000); - if (ret != 0) - dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read output enables: %d\n", + ret); + val = 0; + } + + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, + 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", + ret); + + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, + 0x4000); + if (ret != 0) + dev_warn(arizona->dev, "Failed to do magic: %d\n", + ret); + } + + mutex_unlock(&arizona->dapm->card->dapm_mutex); ret = regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,