aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-arizona.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon/extcon-arizona.c')
-rw-r--r--drivers/extcon/extcon-arizona.c107
1 files changed, 52 insertions, 55 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index dc357a4051f6..b28927972128 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -100,6 +100,55 @@ static const char *arizona_cable[] = {
100 NULL, 100 NULL,
101}; 101};
102 102
103static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
104 unsigned int magic)
105{
106 struct arizona *arizona = info->arizona;
107 int ret;
108
109 mutex_lock(&arizona->dapm->card->dapm_mutex);
110
111 arizona->hpdet_magic = magic;
112
113 /* Keep the HP output stages disabled while doing the magic */
114 if (magic) {
115 ret = regmap_update_bits(arizona->regmap,
116 ARIZONA_OUTPUT_ENABLES_1,
117 ARIZONA_OUT1L_ENA |
118 ARIZONA_OUT1R_ENA, 0);
119 if (ret != 0)
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",
129 ret);
130
131 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
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);
143 if (ret != 0)
144 dev_warn(arizona->dev,
145 "Failed to restore headphone outputs: %d\n",
146 ret);
147 }
148
149 mutex_unlock(&arizona->dapm->card->dapm_mutex);
150}
151
103static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) 152static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
104{ 153{
105 struct arizona *arizona = info->arizona; 154 struct arizona *arizona = info->arizona;
@@ -484,7 +533,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
484 struct arizona *arizona = info->arizona; 533 struct arizona *arizona = info->arizona;
485 int id_gpio = arizona->pdata.hpdet_id_gpio; 534 int id_gpio = arizona->pdata.hpdet_id_gpio;
486 int report = ARIZONA_CABLE_HEADPHONE; 535 int report = ARIZONA_CABLE_HEADPHONE;
487 unsigned int val;
488 int ret, reading; 536 int ret, reading;
489 537
490 mutex_lock(&info->lock); 538 mutex_lock(&info->lock);
@@ -539,28 +587,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
539 dev_err(arizona->dev, "Failed to report HP/line: %d\n", 587 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
540 ret); 588 ret);
541 589
542 mutex_lock(&arizona->dapm->card->dapm_mutex); 590 arizona_extcon_do_magic(info, 0);
543
544 ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
545 if (ret != 0) {
546 dev_err(arizona->dev, "Failed to read output enables: %d\n",
547 ret);
548 val = 0;
549 }
550
551 if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
552 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0);
553 if (ret != 0)
554 dev_warn(arizona->dev, "Failed to undo magic: %d\n",
555 ret);
556
557 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0);
558 if (ret != 0)
559 dev_warn(arizona->dev, "Failed to undo magic: %d\n",
560 ret);
561 }
562
563 mutex_unlock(&arizona->dapm->card->dapm_mutex);
564 591
565done: 592done:
566 if (id_gpio) 593 if (id_gpio)
@@ -606,13 +633,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
606 if (info->mic) 633 if (info->mic)
607 arizona_stop_mic(info); 634 arizona_stop_mic(info);
608 635
609 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); 636 arizona_extcon_do_magic(info, 0x4000);
610 if (ret != 0)
611 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
612
613 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000);
614 if (ret != 0)
615 dev_warn(arizona->dev, "Failed to do magic: %d\n", ret);
616 637
617 ret = regmap_update_bits(arizona->regmap, 638 ret = regmap_update_bits(arizona->regmap,
618 ARIZONA_ACCESSORY_DETECT_MODE_1, 639 ARIZONA_ACCESSORY_DETECT_MODE_1,
@@ -653,7 +674,6 @@ err:
653static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) 674static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
654{ 675{
655 struct arizona *arizona = info->arizona; 676 struct arizona *arizona = info->arizona;
656 unsigned int val;
657 int ret; 677 int ret;
658 678
659 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); 679 dev_dbg(arizona->dev, "Starting identification via HPDET\n");
@@ -665,30 +685,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
665 685
666 arizona_extcon_pulse_micbias(info); 686 arizona_extcon_pulse_micbias(info);
667 687
668 mutex_lock(&arizona->dapm->card->dapm_mutex); 688 arizona_extcon_do_magic(info, 0x4000);
669
670 ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val);
671 if (ret != 0) {
672 dev_err(arizona->dev, "Failed to read output enables: %d\n",
673 ret);
674 val = 0;
675 }
676
677 if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) {
678 ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
679 0x4000);
680 if (ret != 0)
681 dev_warn(arizona->dev, "Failed to do magic: %d\n",
682 ret);
683
684 ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
685 0x4000);
686 if (ret != 0)
687 dev_warn(arizona->dev, "Failed to do magic: %d\n",
688 ret);
689 }
690
691 mutex_unlock(&arizona->dapm->card->dapm_mutex);
692 689
693 ret = regmap_update_bits(arizona->regmap, 690 ret = regmap_update_bits(arizona->regmap,
694 ARIZONA_ACCESSORY_DETECT_MODE_1, 691 ARIZONA_ACCESSORY_DETECT_MODE_1,