2 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
4 * Copyright (C) 2012 Wolfson Microelectronics plc
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/interrupt.h>
22 #include <linux/err.h>
23 #include <linux/gpio.h>
24 #include <linux/input.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/regulator/consumer.h>
28 #include <linux/extcon.h>
30 #include <sound/soc.h>
32 #include <linux/mfd/arizona/core.h>
33 #include <linux/mfd/arizona/pdata.h>
34 #include <linux/mfd/arizona/registers.h>
36 #define ARIZONA_MAX_MICD_RANGE 8
38 #define ARIZONA_ACCDET_MODE_MIC 0
39 #define ARIZONA_ACCDET_MODE_HPL 1
40 #define ARIZONA_ACCDET_MODE_HPR 2
42 #define ARIZONA_HPDET_MAX 10000
44 #define HPDET_DEBOUNCE 500
45 #define DEFAULT_MICD_TIMEOUT 2000
47 #define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
48 ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
49 ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
52 #define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
54 #define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
56 struct arizona_extcon_info
{
58 struct arizona
*arizona
;
60 struct regulator
*micvdd
;
61 struct input_dev
*input
;
66 const struct arizona_micd_config
*micd_modes
;
69 const struct arizona_micd_range
*micd_ranges
;
77 struct delayed_work hpdet_work
;
78 struct delayed_work micd_detect_work
;
79 struct delayed_work micd_timeout_work
;
86 unsigned int hpdet_res
[3];
94 struct extcon_dev edev
;
97 static const struct arizona_micd_config micd_default_modes
[] = {
98 { ARIZONA_ACCDET_SRC
, 1, 0 },
102 static const struct arizona_micd_range micd_default_ranges
[] = {
103 { .max
= 11, .key
= BTN_0
},
104 { .max
= 28, .key
= BTN_1
},
105 { .max
= 54, .key
= BTN_2
},
106 { .max
= 100, .key
= BTN_3
},
107 { .max
= 186, .key
= BTN_4
},
108 { .max
= 430, .key
= BTN_5
},
111 static const int arizona_micd_levels
[] = {
112 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
113 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
114 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
115 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
119 #define ARIZONA_CABLE_MECHANICAL 0
120 #define ARIZONA_CABLE_MICROPHONE 1
121 #define ARIZONA_CABLE_HEADPHONE 2
122 #define ARIZONA_CABLE_LINEOUT 3
124 static const char *arizona_cable
[] = {
132 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info
*info
);
134 static void arizona_extcon_do_magic(struct arizona_extcon_info
*info
,
137 struct arizona
*arizona
= info
->arizona
;
140 mutex_lock(&arizona
->dapm
->card
->dapm_mutex
);
142 arizona
->hpdet_magic
= magic
;
144 /* Keep the HP output stages disabled while doing the magic */
146 ret
= regmap_update_bits(arizona
->regmap
,
147 ARIZONA_OUTPUT_ENABLES_1
,
149 ARIZONA_OUT1R_ENA
, 0);
151 dev_warn(arizona
->dev
,
152 "Failed to disable headphone outputs: %d\n",
156 ret
= regmap_update_bits(arizona
->regmap
, 0x225, 0x4000,
159 dev_warn(arizona
->dev
, "Failed to do magic: %d\n",
162 ret
= regmap_update_bits(arizona
->regmap
, 0x226, 0x4000,
165 dev_warn(arizona
->dev
, "Failed to do magic: %d\n",
168 /* Restore the desired state while not doing the magic */
170 ret
= regmap_update_bits(arizona
->regmap
,
171 ARIZONA_OUTPUT_ENABLES_1
,
173 ARIZONA_OUT1R_ENA
, arizona
->hp_ena
);
175 dev_warn(arizona
->dev
,
176 "Failed to restore headphone outputs: %d\n",
180 mutex_unlock(&arizona
->dapm
->card
->dapm_mutex
);
183 static void arizona_extcon_set_mode(struct arizona_extcon_info
*info
, int mode
)
185 struct arizona
*arizona
= info
->arizona
;
187 mode
%= info
->micd_num_modes
;
189 if (arizona
->pdata
.micd_pol_gpio
> 0)
190 gpio_set_value_cansleep(arizona
->pdata
.micd_pol_gpio
,
191 info
->micd_modes
[mode
].gpio
);
192 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
193 ARIZONA_MICD_BIAS_SRC_MASK
,
194 info
->micd_modes
[mode
].bias
<<
195 ARIZONA_MICD_BIAS_SRC_SHIFT
);
196 regmap_update_bits(arizona
->regmap
, ARIZONA_ACCESSORY_DETECT_MODE_1
,
197 ARIZONA_ACCDET_SRC
, info
->micd_modes
[mode
].src
);
199 info
->micd_mode
= mode
;
201 dev_dbg(arizona
->dev
, "Set jack polarity to %d\n", mode
);
204 static const char *arizona_extcon_get_micbias(struct arizona_extcon_info
*info
)
206 switch (info
->micd_modes
[0].bias
) {
218 static void arizona_extcon_pulse_micbias(struct arizona_extcon_info
*info
)
220 struct arizona
*arizona
= info
->arizona
;
221 const char *widget
= arizona_extcon_get_micbias(info
);
222 struct snd_soc_dapm_context
*dapm
= arizona
->dapm
;
225 ret
= snd_soc_dapm_force_enable_pin(dapm
, widget
);
227 dev_warn(arizona
->dev
, "Failed to enable %s: %d\n",
230 snd_soc_dapm_sync(dapm
);
232 if (!arizona
->pdata
.micd_force_micbias
) {
233 ret
= snd_soc_dapm_disable_pin(arizona
->dapm
, widget
);
235 dev_warn(arizona
->dev
, "Failed to disable %s: %d\n",
238 snd_soc_dapm_sync(dapm
);
242 static void arizona_start_mic(struct arizona_extcon_info
*info
)
244 struct arizona
*arizona
= info
->arizona
;
248 /* Microphone detection can't use idle mode */
249 pm_runtime_get(info
->dev
);
251 if (info
->detecting
) {
252 ret
= regulator_allow_bypass(info
->micvdd
, false);
254 dev_err(arizona
->dev
,
255 "Failed to regulate MICVDD: %d\n",
260 ret
= regulator_enable(info
->micvdd
);
262 dev_err(arizona
->dev
, "Failed to enable MICVDD: %d\n",
266 if (info
->micd_reva
) {
267 regmap_write(arizona
->regmap
, 0x80, 0x3);
268 regmap_write(arizona
->regmap
, 0x294, 0);
269 regmap_write(arizona
->regmap
, 0x80, 0x0);
272 regmap_update_bits(arizona
->regmap
,
273 ARIZONA_ACCESSORY_DETECT_MODE_1
,
274 ARIZONA_ACCDET_MODE_MASK
, ARIZONA_ACCDET_MODE_MIC
);
276 arizona_extcon_pulse_micbias(info
);
278 regmap_update_bits_check(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
279 ARIZONA_MICD_ENA
, ARIZONA_MICD_ENA
,
282 regulator_disable(info
->micvdd
);
283 pm_runtime_put_autosuspend(info
->dev
);
287 static void arizona_stop_mic(struct arizona_extcon_info
*info
)
289 struct arizona
*arizona
= info
->arizona
;
290 const char *widget
= arizona_extcon_get_micbias(info
);
291 struct snd_soc_dapm_context
*dapm
= arizona
->dapm
;
295 regmap_update_bits_check(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
299 ret
= snd_soc_dapm_disable_pin(dapm
, widget
);
301 dev_warn(arizona
->dev
,
302 "Failed to disable %s: %d\n",
305 snd_soc_dapm_sync(dapm
);
307 if (info
->micd_reva
) {
308 regmap_write(arizona
->regmap
, 0x80, 0x3);
309 regmap_write(arizona
->regmap
, 0x294, 2);
310 regmap_write(arizona
->regmap
, 0x80, 0x0);
313 ret
= regulator_allow_bypass(info
->micvdd
, true);
315 dev_err(arizona
->dev
, "Failed to bypass MICVDD: %d\n",
320 regulator_disable(info
->micvdd
);
321 pm_runtime_mark_last_busy(info
->dev
);
322 pm_runtime_put_autosuspend(info
->dev
);
327 unsigned int factor_a
;
328 unsigned int factor_b
;
329 } arizona_hpdet_b_ranges
[] = {
338 } arizona_hpdet_c_ranges
[] = {
345 static int arizona_hpdet_read(struct arizona_extcon_info
*info
)
347 struct arizona
*arizona
= info
->arizona
;
348 unsigned int val
, range
;
351 ret
= regmap_read(arizona
->regmap
, ARIZONA_HEADPHONE_DETECT_2
, &val
);
353 dev_err(arizona
->dev
, "Failed to read HPDET status: %d\n",
358 switch (info
->hpdet_ip
) {
360 if (!(val
& ARIZONA_HP_DONE
)) {
361 dev_err(arizona
->dev
, "HPDET did not complete: %x\n",
366 val
&= ARIZONA_HP_LVL_MASK
;
370 if (!(val
& ARIZONA_HP_DONE_B
)) {
371 dev_err(arizona
->dev
, "HPDET did not complete: %x\n",
376 ret
= regmap_read(arizona
->regmap
, ARIZONA_HP_DACVAL
, &val
);
378 dev_err(arizona
->dev
, "Failed to read HP value: %d\n",
383 regmap_read(arizona
->regmap
, ARIZONA_HEADPHONE_DETECT_1
,
385 range
= (range
& ARIZONA_HP_IMPEDANCE_RANGE_MASK
)
386 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT
;
388 if (range
< ARRAY_SIZE(arizona_hpdet_b_ranges
) - 1 &&
389 (val
< 100 || val
>= 0x3fb)) {
391 dev_dbg(arizona
->dev
, "Moving to HPDET range %d\n",
393 regmap_update_bits(arizona
->regmap
,
394 ARIZONA_HEADPHONE_DETECT_1
,
395 ARIZONA_HP_IMPEDANCE_RANGE_MASK
,
397 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT
);
401 /* If we go out of range report top of range */
402 if (val
< 100 || val
>= 0x3fb) {
403 dev_dbg(arizona
->dev
, "Measurement out of range\n");
404 return ARIZONA_HPDET_MAX
;
407 dev_dbg(arizona
->dev
, "HPDET read %d in range %d\n",
410 val
= arizona_hpdet_b_ranges
[range
].factor_b
412 arizona_hpdet_b_ranges
[range
].factor_a
);
416 dev_warn(arizona
->dev
, "Unknown HPDET IP revision %d\n",
419 if (!(val
& ARIZONA_HP_DONE_B
)) {
420 dev_err(arizona
->dev
, "HPDET did not complete: %x\n",
425 val
&= ARIZONA_HP_LVL_B_MASK
;
426 /* Convert to ohms, the value is in 0.5 ohm increments */
429 regmap_read(arizona
->regmap
, ARIZONA_HEADPHONE_DETECT_1
,
431 range
= (range
& ARIZONA_HP_IMPEDANCE_RANGE_MASK
)
432 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT
;
434 /* Skip up a range, or report? */
435 if (range
< ARRAY_SIZE(arizona_hpdet_c_ranges
) - 1 &&
436 (val
>= arizona_hpdet_c_ranges
[range
].max
)) {
438 dev_dbg(arizona
->dev
, "Moving to HPDET range %d-%d\n",
439 arizona_hpdet_c_ranges
[range
].min
,
440 arizona_hpdet_c_ranges
[range
].max
);
441 regmap_update_bits(arizona
->regmap
,
442 ARIZONA_HEADPHONE_DETECT_1
,
443 ARIZONA_HP_IMPEDANCE_RANGE_MASK
,
445 ARIZONA_HP_IMPEDANCE_RANGE_SHIFT
);
449 if (range
&& (val
< arizona_hpdet_c_ranges
[range
].min
)) {
450 dev_dbg(arizona
->dev
, "Reporting range boundary %d\n",
451 arizona_hpdet_c_ranges
[range
].min
);
452 val
= arizona_hpdet_c_ranges
[range
].min
;
456 dev_dbg(arizona
->dev
, "HP impedance %d ohms\n", val
);
460 static int arizona_hpdet_do_id(struct arizona_extcon_info
*info
, int *reading
,
463 struct arizona
*arizona
= info
->arizona
;
464 int id_gpio
= arizona
->pdata
.hpdet_id_gpio
;
467 * If we're using HPDET for accessory identification we need
468 * to take multiple measurements, step through them in sequence.
470 if (arizona
->pdata
.hpdet_acc_id
) {
471 info
->hpdet_res
[info
->num_hpdet_res
++] = *reading
;
473 /* Only check the mic directly if we didn't already ID it */
474 if (id_gpio
&& info
->num_hpdet_res
== 1) {
475 dev_dbg(arizona
->dev
, "Measuring mic\n");
477 regmap_update_bits(arizona
->regmap
,
478 ARIZONA_ACCESSORY_DETECT_MODE_1
,
479 ARIZONA_ACCDET_MODE_MASK
|
481 ARIZONA_ACCDET_MODE_HPR
|
482 info
->micd_modes
[0].src
);
484 gpio_set_value_cansleep(id_gpio
, 1);
486 regmap_update_bits(arizona
->regmap
,
487 ARIZONA_HEADPHONE_DETECT_1
,
488 ARIZONA_HP_POLL
, ARIZONA_HP_POLL
);
492 /* OK, got both. Now, compare... */
493 dev_dbg(arizona
->dev
, "HPDET measured %d %d\n",
494 info
->hpdet_res
[0], info
->hpdet_res
[1]);
496 /* Take the headphone impedance for the main report */
497 *reading
= info
->hpdet_res
[0];
499 /* Sometimes we get false readings due to slow insert */
500 if (*reading
>= ARIZONA_HPDET_MAX
&& !info
->hpdet_retried
) {
501 dev_dbg(arizona
->dev
, "Retrying high impedance\n");
502 info
->num_hpdet_res
= 0;
503 info
->hpdet_retried
= true;
504 arizona_start_hpdet_acc_id(info
);
505 pm_runtime_put(info
->dev
);
510 * If we measure the mic as high impedance
512 if (!id_gpio
|| info
->hpdet_res
[1] > 50) {
513 dev_dbg(arizona
->dev
, "Detected mic\n");
515 info
->detecting
= true;
517 dev_dbg(arizona
->dev
, "Detected headphone\n");
520 /* Make sure everything is reset back to the real polarity */
521 regmap_update_bits(arizona
->regmap
,
522 ARIZONA_ACCESSORY_DETECT_MODE_1
,
524 info
->micd_modes
[0].src
);
530 static irqreturn_t
arizona_hpdet_irq(int irq
, void *data
)
532 struct arizona_extcon_info
*info
= data
;
533 struct arizona
*arizona
= info
->arizona
;
534 int id_gpio
= arizona
->pdata
.hpdet_id_gpio
;
535 int report
= ARIZONA_CABLE_HEADPHONE
;
539 mutex_lock(&info
->lock
);
541 /* If we got a spurious IRQ for some reason then ignore it */
542 if (!info
->hpdet_active
) {
543 dev_warn(arizona
->dev
, "Spurious HPDET IRQ\n");
544 mutex_unlock(&info
->lock
);
548 /* If the cable was removed while measuring ignore the result */
549 ret
= extcon_get_cable_state_(&info
->edev
, ARIZONA_CABLE_MECHANICAL
);
551 dev_err(arizona
->dev
, "Failed to check cable state: %d\n",
555 dev_dbg(arizona
->dev
, "Ignoring HPDET for removed cable\n");
559 ret
= arizona_hpdet_read(info
);
566 /* Reset back to starting range */
567 regmap_update_bits(arizona
->regmap
,
568 ARIZONA_HEADPHONE_DETECT_1
,
569 ARIZONA_HP_IMPEDANCE_RANGE_MASK
| ARIZONA_HP_POLL
,
572 ret
= arizona_hpdet_do_id(info
, &reading
, &mic
);
578 /* Report high impedence cables as line outputs */
580 report
= ARIZONA_CABLE_LINEOUT
;
582 report
= ARIZONA_CABLE_HEADPHONE
;
584 ret
= extcon_set_cable_state_(&info
->edev
, report
, true);
586 dev_err(arizona
->dev
, "Failed to report HP/line: %d\n",
590 /* Reset back to starting range */
591 regmap_update_bits(arizona
->regmap
,
592 ARIZONA_HEADPHONE_DETECT_1
,
593 ARIZONA_HP_IMPEDANCE_RANGE_MASK
| ARIZONA_HP_POLL
,
596 arizona_extcon_do_magic(info
, 0);
599 gpio_set_value_cansleep(id_gpio
, 0);
601 /* Revert back to MICDET mode */
602 regmap_update_bits(arizona
->regmap
,
603 ARIZONA_ACCESSORY_DETECT_MODE_1
,
604 ARIZONA_ACCDET_MODE_MASK
, ARIZONA_ACCDET_MODE_MIC
);
606 /* If we have a mic then reenable MICDET */
607 if (mic
|| info
->mic
)
608 arizona_start_mic(info
);
610 if (info
->hpdet_active
) {
611 pm_runtime_put_autosuspend(info
->dev
);
612 info
->hpdet_active
= false;
615 info
->hpdet_done
= true;
618 mutex_unlock(&info
->lock
);
623 static void arizona_identify_headphone(struct arizona_extcon_info
*info
)
625 struct arizona
*arizona
= info
->arizona
;
628 if (info
->hpdet_done
)
631 dev_dbg(arizona
->dev
, "Starting HPDET\n");
633 /* Make sure we keep the device enabled during the measurement */
634 pm_runtime_get(info
->dev
);
636 info
->hpdet_active
= true;
639 arizona_stop_mic(info
);
641 arizona_extcon_do_magic(info
, 0x4000);
643 ret
= regmap_update_bits(arizona
->regmap
,
644 ARIZONA_ACCESSORY_DETECT_MODE_1
,
645 ARIZONA_ACCDET_MODE_MASK
,
646 ARIZONA_ACCDET_MODE_HPL
);
648 dev_err(arizona
->dev
, "Failed to set HPDETL mode: %d\n", ret
);
652 ret
= regmap_update_bits(arizona
->regmap
, ARIZONA_HEADPHONE_DETECT_1
,
653 ARIZONA_HP_POLL
, ARIZONA_HP_POLL
);
655 dev_err(arizona
->dev
, "Can't start HPDETL measurement: %d\n",
663 regmap_update_bits(arizona
->regmap
, ARIZONA_ACCESSORY_DETECT_MODE_1
,
664 ARIZONA_ACCDET_MODE_MASK
, ARIZONA_ACCDET_MODE_MIC
);
666 /* Just report headphone */
667 ret
= extcon_update_state(&info
->edev
,
668 1 << ARIZONA_CABLE_HEADPHONE
,
669 1 << ARIZONA_CABLE_HEADPHONE
);
671 dev_err(arizona
->dev
, "Failed to report headphone: %d\n", ret
);
674 arizona_start_mic(info
);
676 info
->hpdet_active
= false;
679 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info
*info
)
681 struct arizona
*arizona
= info
->arizona
;
686 dev_dbg(arizona
->dev
, "Starting identification via HPDET\n");
688 /* Make sure we keep the device enabled during the measurement */
689 pm_runtime_get_sync(info
->dev
);
691 info
->hpdet_active
= true;
693 arizona_extcon_do_magic(info
, 0x4000);
695 ret
= regmap_update_bits(arizona
->regmap
,
696 ARIZONA_ACCESSORY_DETECT_MODE_1
,
697 ARIZONA_ACCDET_SRC
| ARIZONA_ACCDET_MODE_MASK
,
698 info
->micd_modes
[0].src
|
699 ARIZONA_ACCDET_MODE_HPL
);
701 dev_err(arizona
->dev
, "Failed to set HPDETL mode: %d\n", ret
);
705 if (arizona
->pdata
.hpdet_acc_id_line
) {
706 ret
= regmap_update_bits(arizona
->regmap
,
707 ARIZONA_HEADPHONE_DETECT_1
,
708 ARIZONA_HP_POLL
, ARIZONA_HP_POLL
);
710 dev_err(arizona
->dev
,
711 "Can't start HPDETL measurement: %d\n",
716 arizona_hpdet_do_id(info
, &hp_reading
, &mic
);
722 regmap_update_bits(arizona
->regmap
, ARIZONA_ACCESSORY_DETECT_MODE_1
,
723 ARIZONA_ACCDET_MODE_MASK
, ARIZONA_ACCDET_MODE_MIC
);
725 /* Just report headphone */
726 ret
= extcon_update_state(&info
->edev
,
727 1 << ARIZONA_CABLE_HEADPHONE
,
728 1 << ARIZONA_CABLE_HEADPHONE
);
730 dev_err(arizona
->dev
, "Failed to report headphone: %d\n", ret
);
732 info
->hpdet_active
= false;
735 static void arizona_micd_timeout_work(struct work_struct
*work
)
737 struct arizona_extcon_info
*info
= container_of(work
,
738 struct arizona_extcon_info
,
739 micd_timeout_work
.work
);
741 mutex_lock(&info
->lock
);
743 dev_dbg(info
->arizona
->dev
, "MICD timed out, reporting HP\n");
744 arizona_identify_headphone(info
);
746 info
->detecting
= false;
748 arizona_stop_mic(info
);
750 mutex_unlock(&info
->lock
);
753 static void arizona_micd_detect(struct work_struct
*work
)
755 struct arizona_extcon_info
*info
= container_of(work
,
756 struct arizona_extcon_info
,
757 micd_detect_work
.work
);
758 struct arizona
*arizona
= info
->arizona
;
759 unsigned int val
= 0, lvl
;
762 cancel_delayed_work_sync(&info
->micd_timeout_work
);
764 mutex_lock(&info
->lock
);
766 /* If the cable was removed while measuring ignore the result */
767 ret
= extcon_get_cable_state_(&info
->edev
, ARIZONA_CABLE_MECHANICAL
);
769 dev_err(arizona
->dev
, "Failed to check cable state: %d\n",
771 mutex_unlock(&info
->lock
);
774 dev_dbg(arizona
->dev
, "Ignoring MICDET for removed cable\n");
775 mutex_unlock(&info
->lock
);
779 for (i
= 0; i
< 10 && !(val
& MICD_LVL_0_TO_8
); i
++) {
780 ret
= regmap_read(arizona
->regmap
, ARIZONA_MIC_DETECT_3
, &val
);
782 dev_err(arizona
->dev
,
783 "Failed to read MICDET: %d\n", ret
);
784 mutex_unlock(&info
->lock
);
788 dev_dbg(arizona
->dev
, "MICDET: %x\n", val
);
790 if (!(val
& ARIZONA_MICD_VALID
)) {
791 dev_warn(arizona
->dev
,
792 "Microphone detection state invalid\n");
793 mutex_unlock(&info
->lock
);
798 if (i
== 10 && !(val
& MICD_LVL_0_TO_8
)) {
799 dev_err(arizona
->dev
, "Failed to get valid MICDET value\n");
800 mutex_unlock(&info
->lock
);
804 /* Due to jack detect this should never happen */
805 if (!(val
& ARIZONA_MICD_STS
)) {
806 dev_warn(arizona
->dev
, "Detected open circuit\n");
807 info
->detecting
= false;
811 /* If we got a high impedence we should have a headset, report it. */
812 if (info
->detecting
&& (val
& ARIZONA_MICD_LVL_8
)) {
813 arizona_identify_headphone(info
);
815 ret
= extcon_update_state(&info
->edev
,
816 1 << ARIZONA_CABLE_MICROPHONE
,
817 1 << ARIZONA_CABLE_MICROPHONE
);
820 dev_err(arizona
->dev
, "Headset report failed: %d\n",
823 /* Don't need to regulate for button detection */
824 ret
= regulator_allow_bypass(info
->micvdd
, false);
826 dev_err(arizona
->dev
, "Failed to bypass MICVDD: %d\n",
831 info
->detecting
= false;
835 /* If we detected a lower impedence during initial startup
836 * then we probably have the wrong polarity, flip it. Don't
837 * do this for the lowest impedences to speed up detection of
838 * plain headphones. If both polarities report a low
839 * impedence then give up and report headphones.
841 if (info
->detecting
&& (val
& MICD_LVL_1_TO_7
)) {
842 if (info
->jack_flips
>= info
->micd_num_modes
* 10) {
843 dev_dbg(arizona
->dev
, "Detected HP/line\n");
844 arizona_identify_headphone(info
);
846 info
->detecting
= false;
848 arizona_stop_mic(info
);
851 if (info
->micd_mode
== info
->micd_num_modes
)
853 arizona_extcon_set_mode(info
, info
->micd_mode
);
862 * If we're still detecting and we detect a short then we've
863 * got a headphone. Otherwise it's a button press.
865 if (val
& MICD_LVL_0_TO_7
) {
867 dev_dbg(arizona
->dev
, "Mic button detected\n");
869 lvl
= val
& ARIZONA_MICD_LVL_MASK
;
870 lvl
>>= ARIZONA_MICD_LVL_SHIFT
;
872 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
873 input_report_key(info
->input
,
874 info
->micd_ranges
[i
].key
, 0);
877 WARN_ON(ffs(lvl
) - 1 >= info
->num_micd_ranges
);
878 if (lvl
&& ffs(lvl
) - 1 < info
->num_micd_ranges
) {
879 key
= info
->micd_ranges
[ffs(lvl
) - 1].key
;
880 input_report_key(info
->input
, key
, 1);
881 input_sync(info
->input
);
884 } else if (info
->detecting
) {
885 dev_dbg(arizona
->dev
, "Headphone detected\n");
886 info
->detecting
= false;
887 arizona_stop_mic(info
);
889 arizona_identify_headphone(info
);
891 dev_warn(arizona
->dev
, "Button with no mic: %x\n",
895 dev_dbg(arizona
->dev
, "Mic button released\n");
896 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
897 input_report_key(info
->input
,
898 info
->micd_ranges
[i
].key
, 0);
899 input_sync(info
->input
);
900 arizona_extcon_pulse_micbias(info
);
905 queue_delayed_work(system_power_efficient_wq
,
906 &info
->micd_timeout_work
,
907 msecs_to_jiffies(info
->micd_timeout
));
909 pm_runtime_mark_last_busy(info
->dev
);
910 mutex_unlock(&info
->lock
);
913 static irqreturn_t
arizona_micdet(int irq
, void *data
)
915 struct arizona_extcon_info
*info
= data
;
916 struct arizona
*arizona
= info
->arizona
;
917 int debounce
= arizona
->pdata
.micd_detect_debounce
;
919 cancel_delayed_work_sync(&info
->micd_detect_work
);
920 cancel_delayed_work_sync(&info
->micd_timeout_work
);
922 mutex_lock(&info
->lock
);
923 if (!info
->detecting
)
925 mutex_unlock(&info
->lock
);
928 queue_delayed_work(system_power_efficient_wq
,
929 &info
->micd_detect_work
,
930 msecs_to_jiffies(debounce
));
932 arizona_micd_detect(&info
->micd_detect_work
.work
);
937 static void arizona_hpdet_work(struct work_struct
*work
)
939 struct arizona_extcon_info
*info
= container_of(work
,
940 struct arizona_extcon_info
,
943 mutex_lock(&info
->lock
);
944 arizona_start_hpdet_acc_id(info
);
945 mutex_unlock(&info
->lock
);
948 static irqreturn_t
arizona_jackdet(int irq
, void *data
)
950 struct arizona_extcon_info
*info
= data
;
951 struct arizona
*arizona
= info
->arizona
;
952 unsigned int val
, present
, mask
;
953 bool cancelled_hp
, cancelled_mic
;
956 cancelled_hp
= cancel_delayed_work_sync(&info
->hpdet_work
);
957 cancelled_mic
= cancel_delayed_work_sync(&info
->micd_timeout_work
);
959 pm_runtime_get_sync(info
->dev
);
961 mutex_lock(&info
->lock
);
963 if (arizona
->pdata
.jd_gpio5
) {
964 mask
= ARIZONA_MICD_CLAMP_STS
;
967 mask
= ARIZONA_JD1_STS
;
968 present
= ARIZONA_JD1_STS
;
971 ret
= regmap_read(arizona
->regmap
, ARIZONA_AOD_IRQ_RAW_STATUS
, &val
);
973 dev_err(arizona
->dev
, "Failed to read jackdet status: %d\n",
975 mutex_unlock(&info
->lock
);
976 pm_runtime_put_autosuspend(info
->dev
);
981 if (val
== info
->last_jackdet
) {
982 dev_dbg(arizona
->dev
, "Suppressing duplicate JACKDET\n");
984 queue_delayed_work(system_power_efficient_wq
,
986 msecs_to_jiffies(HPDET_DEBOUNCE
));
989 int micd_timeout
= info
->micd_timeout
;
991 queue_delayed_work(system_power_efficient_wq
,
992 &info
->micd_timeout_work
,
993 msecs_to_jiffies(micd_timeout
));
998 info
->last_jackdet
= val
;
1000 if (info
->last_jackdet
== present
) {
1001 dev_dbg(arizona
->dev
, "Detected jack\n");
1002 ret
= extcon_set_cable_state_(&info
->edev
,
1003 ARIZONA_CABLE_MECHANICAL
, true);
1006 dev_err(arizona
->dev
, "Mechanical report failed: %d\n",
1009 if (!arizona
->pdata
.hpdet_acc_id
) {
1010 info
->detecting
= true;
1012 info
->jack_flips
= 0;
1014 arizona_start_mic(info
);
1016 queue_delayed_work(system_power_efficient_wq
,
1018 msecs_to_jiffies(HPDET_DEBOUNCE
));
1021 regmap_update_bits(arizona
->regmap
,
1022 ARIZONA_JACK_DETECT_DEBOUNCE
,
1023 ARIZONA_MICD_CLAMP_DB
| ARIZONA_JD1_DB
, 0);
1025 dev_dbg(arizona
->dev
, "Detected jack removal\n");
1027 arizona_stop_mic(info
);
1029 info
->num_hpdet_res
= 0;
1030 for (i
= 0; i
< ARRAY_SIZE(info
->hpdet_res
); i
++)
1031 info
->hpdet_res
[i
] = 0;
1033 info
->hpdet_done
= false;
1034 info
->hpdet_retried
= false;
1036 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
1037 input_report_key(info
->input
,
1038 info
->micd_ranges
[i
].key
, 0);
1039 input_sync(info
->input
);
1041 ret
= extcon_update_state(&info
->edev
, 0xffffffff, 0);
1043 dev_err(arizona
->dev
, "Removal report failed: %d\n",
1046 regmap_update_bits(arizona
->regmap
,
1047 ARIZONA_JACK_DETECT_DEBOUNCE
,
1048 ARIZONA_MICD_CLAMP_DB
| ARIZONA_JD1_DB
,
1049 ARIZONA_MICD_CLAMP_DB
| ARIZONA_JD1_DB
);
1052 if (arizona
->pdata
.micd_timeout
)
1053 info
->micd_timeout
= arizona
->pdata
.micd_timeout
;
1055 info
->micd_timeout
= DEFAULT_MICD_TIMEOUT
;
1058 /* Clear trig_sts to make sure DCVDD is not forced up */
1059 regmap_write(arizona
->regmap
, ARIZONA_AOD_WKUP_AND_TRIG
,
1060 ARIZONA_MICD_CLAMP_FALL_TRIG_STS
|
1061 ARIZONA_MICD_CLAMP_RISE_TRIG_STS
|
1062 ARIZONA_JD1_FALL_TRIG_STS
|
1063 ARIZONA_JD1_RISE_TRIG_STS
);
1065 mutex_unlock(&info
->lock
);
1067 pm_runtime_mark_last_busy(info
->dev
);
1068 pm_runtime_put_autosuspend(info
->dev
);
1073 /* Map a level onto a slot in the register bank */
1074 static void arizona_micd_set_level(struct arizona
*arizona
, int index
,
1080 reg
= ARIZONA_MIC_DETECT_LEVEL_4
- (index
/ 2);
1089 /* Program the level itself */
1090 regmap_update_bits(arizona
->regmap
, reg
, mask
, level
);
1093 static int arizona_extcon_probe(struct platform_device
*pdev
)
1095 struct arizona
*arizona
= dev_get_drvdata(pdev
->dev
.parent
);
1096 struct arizona_pdata
*pdata
= &arizona
->pdata
;
1097 struct arizona_extcon_info
*info
;
1099 int jack_irq_fall
, jack_irq_rise
;
1100 int ret
, mode
, i
, j
;
1102 if (!arizona
->dapm
|| !arizona
->dapm
->card
)
1103 return -EPROBE_DEFER
;
1105 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
1107 dev_err(&pdev
->dev
, "Failed to allocate memory\n");
1112 info
->micvdd
= devm_regulator_get(arizona
->dev
, "MICVDD");
1113 if (IS_ERR(info
->micvdd
)) {
1114 ret
= PTR_ERR(info
->micvdd
);
1115 dev_err(arizona
->dev
, "Failed to get MICVDD: %d\n", ret
);
1119 mutex_init(&info
->lock
);
1120 info
->arizona
= arizona
;
1121 info
->dev
= &pdev
->dev
;
1122 info
->last_jackdet
= ~(ARIZONA_MICD_CLAMP_STS
| ARIZONA_JD1_STS
);
1123 INIT_DELAYED_WORK(&info
->hpdet_work
, arizona_hpdet_work
);
1124 INIT_DELAYED_WORK(&info
->micd_detect_work
, arizona_micd_detect
);
1125 INIT_DELAYED_WORK(&info
->micd_timeout_work
, arizona_micd_timeout_work
);
1126 platform_set_drvdata(pdev
, info
);
1128 switch (arizona
->type
) {
1130 switch (arizona
->rev
) {
1132 info
->micd_reva
= true;
1135 info
->micd_clamp
= true;
1141 switch (arizona
->rev
) {
1145 info
->micd_clamp
= true;
1154 info
->edev
.name
= "Headset Jack";
1155 info
->edev
.dev
.parent
= arizona
->dev
;
1156 info
->edev
.supported_cable
= arizona_cable
;
1158 ret
= extcon_dev_register(&info
->edev
);
1160 dev_err(arizona
->dev
, "extcon_dev_register() failed: %d\n",
1165 info
->input
= devm_input_allocate_device(&pdev
->dev
);
1167 dev_err(arizona
->dev
, "Can't allocate input dev\n");
1172 info
->input
->name
= "Headset";
1173 info
->input
->phys
= "arizona/extcon";
1174 info
->input
->dev
.parent
= &pdev
->dev
;
1176 if (pdata
->num_micd_configs
) {
1177 info
->micd_modes
= pdata
->micd_configs
;
1178 info
->micd_num_modes
= pdata
->num_micd_configs
;
1180 info
->micd_modes
= micd_default_modes
;
1181 info
->micd_num_modes
= ARRAY_SIZE(micd_default_modes
);
1184 if (arizona
->pdata
.micd_pol_gpio
> 0) {
1185 if (info
->micd_modes
[0].gpio
)
1186 mode
= GPIOF_OUT_INIT_HIGH
;
1188 mode
= GPIOF_OUT_INIT_LOW
;
1190 ret
= devm_gpio_request_one(&pdev
->dev
,
1191 arizona
->pdata
.micd_pol_gpio
,
1195 dev_err(arizona
->dev
, "Failed to request GPIO%d: %d\n",
1196 arizona
->pdata
.micd_pol_gpio
, ret
);
1201 if (arizona
->pdata
.hpdet_id_gpio
> 0) {
1202 ret
= devm_gpio_request_one(&pdev
->dev
,
1203 arizona
->pdata
.hpdet_id_gpio
,
1207 dev_err(arizona
->dev
, "Failed to request GPIO%d: %d\n",
1208 arizona
->pdata
.hpdet_id_gpio
, ret
);
1213 if (arizona
->pdata
.micd_bias_start_time
)
1214 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
1215 ARIZONA_MICD_BIAS_STARTTIME_MASK
,
1216 arizona
->pdata
.micd_bias_start_time
1217 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT
);
1219 if (arizona
->pdata
.micd_rate
)
1220 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
1221 ARIZONA_MICD_RATE_MASK
,
1222 arizona
->pdata
.micd_rate
1223 << ARIZONA_MICD_RATE_SHIFT
);
1225 if (arizona
->pdata
.micd_dbtime
)
1226 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_1
,
1227 ARIZONA_MICD_DBTIME_MASK
,
1228 arizona
->pdata
.micd_dbtime
1229 << ARIZONA_MICD_DBTIME_SHIFT
);
1231 BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels
) != 0x40);
1233 if (arizona
->pdata
.num_micd_ranges
) {
1234 info
->micd_ranges
= pdata
->micd_ranges
;
1235 info
->num_micd_ranges
= pdata
->num_micd_ranges
;
1237 info
->micd_ranges
= micd_default_ranges
;
1238 info
->num_micd_ranges
= ARRAY_SIZE(micd_default_ranges
);
1241 if (arizona
->pdata
.num_micd_ranges
> ARIZONA_MAX_MICD_RANGE
) {
1242 dev_err(arizona
->dev
, "Too many MICD ranges: %d\n",
1243 arizona
->pdata
.num_micd_ranges
);
1246 if (info
->num_micd_ranges
> 1) {
1247 for (i
= 1; i
< info
->num_micd_ranges
; i
++) {
1248 if (info
->micd_ranges
[i
- 1].max
>
1249 info
->micd_ranges
[i
].max
) {
1250 dev_err(arizona
->dev
,
1251 "MICD ranges must be sorted\n");
1258 /* Disable all buttons by default */
1259 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_2
,
1260 ARIZONA_MICD_LVL_SEL_MASK
, 0x81);
1262 /* Set up all the buttons the user specified */
1263 for (i
= 0; i
< info
->num_micd_ranges
; i
++) {
1264 for (j
= 0; j
< ARRAY_SIZE(arizona_micd_levels
); j
++)
1265 if (arizona_micd_levels
[j
] >= info
->micd_ranges
[i
].max
)
1268 if (j
== ARRAY_SIZE(arizona_micd_levels
)) {
1269 dev_err(arizona
->dev
, "Unsupported MICD level %d\n",
1270 info
->micd_ranges
[i
].max
);
1275 dev_dbg(arizona
->dev
, "%d ohms for MICD threshold %d\n",
1276 arizona_micd_levels
[j
], i
);
1278 arizona_micd_set_level(arizona
, i
, j
);
1279 input_set_capability(info
->input
, EV_KEY
,
1280 info
->micd_ranges
[i
].key
);
1282 /* Enable reporting of that range */
1283 regmap_update_bits(arizona
->regmap
, ARIZONA_MIC_DETECT_2
,
1287 /* Set all the remaining keys to a maximum */
1288 for (; i
< ARIZONA_MAX_MICD_RANGE
; i
++)
1289 arizona_micd_set_level(arizona
, i
, 0x3f);
1292 * If we have a clamp use it, activating in conjunction with
1293 * GPIO5 if that is connected for jack detect operation.
1295 if (info
->micd_clamp
) {
1296 if (arizona
->pdata
.jd_gpio5
) {
1297 /* Put the GPIO into input mode with optional pull */
1299 if (arizona
->pdata
.jd_gpio5_nopull
)
1300 val
&= ~ARIZONA_GPN_PU
;
1302 regmap_write(arizona
->regmap
, ARIZONA_GPIO5_CTRL
,
1305 regmap_update_bits(arizona
->regmap
,
1306 ARIZONA_MICD_CLAMP_CONTROL
,
1307 ARIZONA_MICD_CLAMP_MODE_MASK
, 0x9);
1309 regmap_update_bits(arizona
->regmap
,
1310 ARIZONA_MICD_CLAMP_CONTROL
,
1311 ARIZONA_MICD_CLAMP_MODE_MASK
, 0x4);
1314 regmap_update_bits(arizona
->regmap
,
1315 ARIZONA_JACK_DETECT_DEBOUNCE
,
1316 ARIZONA_MICD_CLAMP_DB
,
1317 ARIZONA_MICD_CLAMP_DB
);
1320 arizona_extcon_set_mode(info
, 0);
1322 pm_runtime_enable(&pdev
->dev
);
1323 pm_runtime_idle(&pdev
->dev
);
1324 pm_runtime_get_sync(&pdev
->dev
);
1326 if (arizona
->pdata
.jd_gpio5
) {
1327 jack_irq_rise
= ARIZONA_IRQ_MICD_CLAMP_RISE
;
1328 jack_irq_fall
= ARIZONA_IRQ_MICD_CLAMP_FALL
;
1330 jack_irq_rise
= ARIZONA_IRQ_JD_RISE
;
1331 jack_irq_fall
= ARIZONA_IRQ_JD_FALL
;
1334 ret
= arizona_request_irq(arizona
, jack_irq_rise
,
1335 "JACKDET rise", arizona_jackdet
, info
);
1337 dev_err(&pdev
->dev
, "Failed to get JACKDET rise IRQ: %d\n",
1342 ret
= arizona_set_irq_wake(arizona
, jack_irq_rise
, 1);
1344 dev_err(&pdev
->dev
, "Failed to set JD rise IRQ wake: %d\n",
1349 ret
= arizona_request_irq(arizona
, jack_irq_fall
,
1350 "JACKDET fall", arizona_jackdet
, info
);
1352 dev_err(&pdev
->dev
, "Failed to get JD fall IRQ: %d\n", ret
);
1356 ret
= arizona_set_irq_wake(arizona
, jack_irq_fall
, 1);
1358 dev_err(&pdev
->dev
, "Failed to set JD fall IRQ wake: %d\n",
1363 ret
= arizona_request_irq(arizona
, ARIZONA_IRQ_MICDET
,
1364 "MICDET", arizona_micdet
, info
);
1366 dev_err(&pdev
->dev
, "Failed to get MICDET IRQ: %d\n", ret
);
1370 ret
= arizona_request_irq(arizona
, ARIZONA_IRQ_HPDET
,
1371 "HPDET", arizona_hpdet_irq
, info
);
1373 dev_err(&pdev
->dev
, "Failed to get HPDET IRQ: %d\n", ret
);
1377 arizona_clk32k_enable(arizona
);
1378 regmap_update_bits(arizona
->regmap
, ARIZONA_JACK_DETECT_DEBOUNCE
,
1379 ARIZONA_JD1_DB
, ARIZONA_JD1_DB
);
1380 regmap_update_bits(arizona
->regmap
, ARIZONA_JACK_DETECT_ANALOGUE
,
1381 ARIZONA_JD1_ENA
, ARIZONA_JD1_ENA
);
1383 ret
= regulator_allow_bypass(info
->micvdd
, true);
1385 dev_warn(arizona
->dev
, "Failed to set MICVDD to bypass: %d\n",
1388 pm_runtime_put(&pdev
->dev
);
1390 ret
= input_register_device(info
->input
);
1392 dev_err(&pdev
->dev
, "Can't register input device: %d\n", ret
);
1399 arizona_free_irq(arizona
, ARIZONA_IRQ_HPDET
, info
);
1401 arizona_free_irq(arizona
, ARIZONA_IRQ_MICDET
, info
);
1403 arizona_set_irq_wake(arizona
, jack_irq_fall
, 0);
1405 arizona_free_irq(arizona
, jack_irq_fall
, info
);
1407 arizona_set_irq_wake(arizona
, jack_irq_rise
, 0);
1409 arizona_free_irq(arizona
, jack_irq_rise
, info
);
1412 pm_runtime_disable(&pdev
->dev
);
1413 extcon_dev_unregister(&info
->edev
);
1418 static int arizona_extcon_remove(struct platform_device
*pdev
)
1420 struct arizona_extcon_info
*info
= platform_get_drvdata(pdev
);
1421 struct arizona
*arizona
= info
->arizona
;
1422 int jack_irq_rise
, jack_irq_fall
;
1424 pm_runtime_disable(&pdev
->dev
);
1426 regmap_update_bits(arizona
->regmap
,
1427 ARIZONA_MICD_CLAMP_CONTROL
,
1428 ARIZONA_MICD_CLAMP_MODE_MASK
, 0);
1430 if (arizona
->pdata
.jd_gpio5
) {
1431 jack_irq_rise
= ARIZONA_IRQ_MICD_CLAMP_RISE
;
1432 jack_irq_fall
= ARIZONA_IRQ_MICD_CLAMP_FALL
;
1434 jack_irq_rise
= ARIZONA_IRQ_JD_RISE
;
1435 jack_irq_fall
= ARIZONA_IRQ_JD_FALL
;
1438 arizona_set_irq_wake(arizona
, jack_irq_rise
, 0);
1439 arizona_set_irq_wake(arizona
, jack_irq_fall
, 0);
1440 arizona_free_irq(arizona
, ARIZONA_IRQ_HPDET
, info
);
1441 arizona_free_irq(arizona
, ARIZONA_IRQ_MICDET
, info
);
1442 arizona_free_irq(arizona
, jack_irq_rise
, info
);
1443 arizona_free_irq(arizona
, jack_irq_fall
, info
);
1444 cancel_delayed_work_sync(&info
->hpdet_work
);
1445 regmap_update_bits(arizona
->regmap
, ARIZONA_JACK_DETECT_ANALOGUE
,
1446 ARIZONA_JD1_ENA
, 0);
1447 arizona_clk32k_disable(arizona
);
1448 extcon_dev_unregister(&info
->edev
);
1453 static struct platform_driver arizona_extcon_driver
= {
1455 .name
= "arizona-extcon",
1456 .owner
= THIS_MODULE
,
1458 .probe
= arizona_extcon_probe
,
1459 .remove
= arizona_extcon_remove
,
1462 module_platform_driver(arizona_extcon_driver
);
1464 MODULE_DESCRIPTION("Arizona Extcon driver");
1465 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1466 MODULE_LICENSE("GPL");
1467 MODULE_ALIAS("platform:extcon-arizona");