diff options
Diffstat (limited to 'drivers/extcon/extcon-arizona.c')
-rw-r--r-- | drivers/extcon/extcon-arizona.c | 107 |
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 | ||
103 | static 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 | |||
103 | static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) | 152 | static 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 | ||
565 | done: | 592 | done: |
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: | |||
653 | static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) | 674 | static 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, |