Lines Matching +full:max +full:- +full:output +full:- +full:impedance

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
5 * Copyright (C) 2012-2014 Wolfson Microelectronics plc
26 #include <dt-bindings/mfd/arizona.h>
33 * The hardware supports 8 ranges / buttons, but the snd-jack interface
34 * only supports 6 buttons (button 0-5).
76 { .max = 11, .key = BTN_0 },
77 { .max = 28, .key = BTN_1 },
78 { .max = 54, .key = BTN_2 },
79 { .max = 100, .key = BTN_3 },
80 { .max = 186, .key = BTN_4 },
81 { .max = 430, .key = BTN_5 },
100 struct arizona *arizona = info->arizona; in arizona_extcon_hp_clamp()
105 switch (arizona->type) { in arizona_extcon_hp_clamp()
122 ret = regmap_update_bits(arizona->regmap, in arizona_extcon_hp_clamp()
127 dev_warn(arizona->dev, "Failed to set TST_CAP_SEL: %d\n", ret); in arizona_extcon_hp_clamp()
136 snd_soc_dapm_mutex_lock(arizona->dapm); in arizona_extcon_hp_clamp()
138 arizona->hpdet_clamp = clamp; in arizona_extcon_hp_clamp()
140 /* Keep the HP output stages disabled while doing the clamp */ in arizona_extcon_hp_clamp()
142 ret = regmap_update_bits(arizona->regmap, in arizona_extcon_hp_clamp()
147 dev_warn(arizona->dev, "Failed to disable headphone outputs: %d\n", ret); in arizona_extcon_hp_clamp()
151 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L, in arizona_extcon_hp_clamp()
154 dev_warn(arizona->dev, "Failed to do clamp: %d\n", ret); in arizona_extcon_hp_clamp()
156 ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R, in arizona_extcon_hp_clamp()
159 dev_warn(arizona->dev, "Failed to do clamp: %d\n", ret); in arizona_extcon_hp_clamp()
164 ret = regmap_update_bits(arizona->regmap, in arizona_extcon_hp_clamp()
167 ARIZONA_OUT1R_ENA, arizona->hp_ena); in arizona_extcon_hp_clamp()
169 dev_warn(arizona->dev, "Failed to restore headphone outputs: %d\n", ret); in arizona_extcon_hp_clamp()
172 snd_soc_dapm_mutex_unlock(arizona->dapm); in arizona_extcon_hp_clamp()
177 struct arizona *arizona = info->arizona; in arizona_extcon_set_mode()
179 mode %= info->micd_num_modes; in arizona_extcon_set_mode()
181 gpiod_set_value_cansleep(info->micd_pol_gpio, in arizona_extcon_set_mode()
182 info->micd_modes[mode].gpio); in arizona_extcon_set_mode()
184 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_extcon_set_mode()
186 info->micd_modes[mode].bias << in arizona_extcon_set_mode()
188 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, in arizona_extcon_set_mode()
189 ARIZONA_ACCDET_SRC, info->micd_modes[mode].src); in arizona_extcon_set_mode()
191 info->micd_mode = mode; in arizona_extcon_set_mode()
193 dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode); in arizona_extcon_set_mode()
198 switch (info->micd_modes[0].bias) { in arizona_extcon_get_micbias()
212 struct arizona *arizona = info->arizona; in arizona_extcon_pulse_micbias()
214 struct snd_soc_dapm_context *dapm = arizona->dapm; in arizona_extcon_pulse_micbias()
220 dev_warn(arizona->dev, "Failed to enable %s: %d\n", widget, ret); in arizona_extcon_pulse_micbias()
224 if (!arizona->pdata.micd_force_micbias) { in arizona_extcon_pulse_micbias()
227 dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret); in arizona_extcon_pulse_micbias()
235 struct arizona *arizona = info->arizona; in arizona_start_mic()
241 pm_runtime_get_sync(arizona->dev); in arizona_start_mic()
243 if (info->detecting) { in arizona_start_mic()
244 ret = regulator_allow_bypass(info->micvdd, false); in arizona_start_mic()
246 dev_err(arizona->dev, "Failed to regulate MICVDD: %d\n", ret); in arizona_start_mic()
249 ret = regulator_enable(info->micvdd); in arizona_start_mic()
251 dev_err(arizona->dev, "Failed to enable MICVDD: %d\n", ret); in arizona_start_mic()
253 if (info->micd_reva) { in arizona_start_mic()
260 regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva)); in arizona_start_mic()
263 if (info->detecting && arizona->pdata.micd_software_compare) in arizona_start_mic()
268 regmap_update_bits(arizona->regmap, in arizona_start_mic()
274 ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_start_mic()
278 dev_err(arizona->dev, "Failed to enable micd: %d\n", ret); in arizona_start_mic()
280 regulator_disable(info->micvdd); in arizona_start_mic()
281 pm_runtime_put_autosuspend(arizona->dev); in arizona_start_mic()
287 struct arizona *arizona = info->arizona; in arizona_stop_mic()
289 struct snd_soc_dapm_context *dapm = arizona->dapm; in arizona_stop_mic()
294 ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_stop_mic()
298 dev_err(arizona->dev, "Failed to disable micd: %d\n", ret); in arizona_stop_mic()
302 dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret); in arizona_stop_mic()
306 if (info->micd_reva) { in arizona_stop_mic()
313 regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva)); in arizona_stop_mic()
316 ret = regulator_allow_bypass(info->micvdd, true); in arizona_stop_mic()
318 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", ret); in arizona_stop_mic()
321 regulator_disable(info->micvdd); in arizona_stop_mic()
322 pm_runtime_put_autosuspend(arizona->dev); in arizona_stop_mic()
340 int max; member
350 struct arizona *arizona = info->arizona; in arizona_hpdet_read()
354 ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val); in arizona_hpdet_read()
356 dev_err(arizona->dev, "Failed to read HPDET status: %d\n", ret); in arizona_hpdet_read()
360 switch (info->hpdet_ip_version) { in arizona_hpdet_read()
363 dev_err(arizona->dev, "HPDET did not complete: %x\n", val); in arizona_hpdet_read()
364 return -EAGAIN; in arizona_hpdet_read()
372 dev_err(arizona->dev, "HPDET did not complete: %x\n", val); in arizona_hpdet_read()
373 return -EAGAIN; in arizona_hpdet_read()
376 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val); in arizona_hpdet_read()
378 dev_err(arizona->dev, "Failed to read HP value: %d\n", ret); in arizona_hpdet_read()
379 return -EAGAIN; in arizona_hpdet_read()
382 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, in arizona_hpdet_read()
387 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 && in arizona_hpdet_read()
391 dev_dbg(arizona->dev, "Moving to HPDET range %d\n", range); in arizona_hpdet_read()
392 regmap_update_bits(arizona->regmap, in arizona_hpdet_read()
397 return -EAGAIN; in arizona_hpdet_read()
403 dev_dbg(arizona->dev, "Measurement out of range\n"); in arizona_hpdet_read()
407 dev_dbg(arizona->dev, "HPDET read %d in range %d\n", val, range); in arizona_hpdet_read()
410 / ((val * 100) - in arizona_hpdet_read()
416 dev_err(arizona->dev, "HPDET did not complete: %x\n", val); in arizona_hpdet_read()
417 return -EAGAIN; in arizona_hpdet_read()
424 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, in arizona_hpdet_read()
430 if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 && in arizona_hpdet_read()
431 (val >= arizona_hpdet_c_ranges[range].max)) { in arizona_hpdet_read()
433 dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n", in arizona_hpdet_read()
435 arizona_hpdet_c_ranges[range].max); in arizona_hpdet_read()
436 regmap_update_bits(arizona->regmap, in arizona_hpdet_read()
441 return -EAGAIN; in arizona_hpdet_read()
445 dev_dbg(arizona->dev, "Reporting range boundary %d\n", in arizona_hpdet_read()
452 dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n", info->hpdet_ip_version); in arizona_hpdet_read()
453 return -EINVAL; in arizona_hpdet_read()
456 dev_dbg(arizona->dev, "HP impedance %d ohms\n", val); in arizona_hpdet_read()
463 struct arizona *arizona = info->arizona; in arizona_hpdet_do_id()
464 int id_gpio = arizona->pdata.hpdet_id_gpio; in arizona_hpdet_do_id()
466 if (!arizona->pdata.hpdet_acc_id) in arizona_hpdet_do_id()
473 info->hpdet_res[info->num_hpdet_res++] = *reading; in arizona_hpdet_do_id()
476 if (id_gpio && info->num_hpdet_res == 1) { in arizona_hpdet_do_id()
477 dev_dbg(arizona->dev, "Measuring mic\n"); in arizona_hpdet_do_id()
479 regmap_update_bits(arizona->regmap, in arizona_hpdet_do_id()
484 info->micd_modes[0].src); in arizona_hpdet_do_id()
488 regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, in arizona_hpdet_do_id()
490 return -EAGAIN; in arizona_hpdet_do_id()
494 dev_dbg(arizona->dev, "HPDET measured %d %d\n", in arizona_hpdet_do_id()
495 info->hpdet_res[0], info->hpdet_res[1]); in arizona_hpdet_do_id()
497 /* Take the headphone impedance for the main report */ in arizona_hpdet_do_id()
498 *reading = info->hpdet_res[0]; in arizona_hpdet_do_id()
501 if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) { in arizona_hpdet_do_id()
502 dev_dbg(arizona->dev, "Retrying high impedance\n"); in arizona_hpdet_do_id()
503 info->num_hpdet_res = 0; in arizona_hpdet_do_id()
504 info->hpdet_retried = true; in arizona_hpdet_do_id()
506 pm_runtime_put(arizona->dev); in arizona_hpdet_do_id()
507 return -EAGAIN; in arizona_hpdet_do_id()
511 * If we measure the mic as high impedance in arizona_hpdet_do_id()
513 if (!id_gpio || info->hpdet_res[1] > 50) { in arizona_hpdet_do_id()
514 dev_dbg(arizona->dev, "Detected mic\n"); in arizona_hpdet_do_id()
516 info->detecting = true; in arizona_hpdet_do_id()
518 dev_dbg(arizona->dev, "Detected headphone\n"); in arizona_hpdet_do_id()
522 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, in arizona_hpdet_do_id()
523 ARIZONA_ACCDET_SRC, info->micd_modes[0].src); in arizona_hpdet_do_id()
531 struct arizona *arizona = info->arizona; in arizona_hpdet_irq()
532 int id_gpio = arizona->pdata.hpdet_id_gpio; in arizona_hpdet_irq()
536 mutex_lock(&info->lock); in arizona_hpdet_irq()
539 if (!info->hpdet_active) { in arizona_hpdet_irq()
540 dev_warn(arizona->dev, "Spurious HPDET IRQ\n"); in arizona_hpdet_irq()
541 mutex_unlock(&info->lock); in arizona_hpdet_irq()
546 state = info->jack->status & SND_JACK_MECHANICAL; in arizona_hpdet_irq()
548 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n"); in arizona_hpdet_irq()
553 if (ret == -EAGAIN) in arizona_hpdet_irq()
560 regmap_update_bits(arizona->regmap, in arizona_hpdet_irq()
566 if (ret == -EAGAIN) in arizona_hpdet_irq()
577 snd_soc_jack_report(info->jack, report, SND_JACK_LINEOUT | SND_JACK_HEADPHONE); in arizona_hpdet_irq()
581 regmap_update_bits(arizona->regmap, in arizona_hpdet_irq()
592 if (state && (mic || info->mic)) in arizona_hpdet_irq()
595 if (info->hpdet_active) { in arizona_hpdet_irq()
596 pm_runtime_put_autosuspend(arizona->dev); in arizona_hpdet_irq()
597 info->hpdet_active = false; in arizona_hpdet_irq()
602 info->hpdet_done = true; in arizona_hpdet_irq()
605 mutex_unlock(&info->lock); in arizona_hpdet_irq()
612 struct arizona *arizona = info->arizona; in arizona_identify_headphone()
615 if (info->hpdet_done) in arizona_identify_headphone()
618 dev_dbg(arizona->dev, "Starting HPDET\n"); in arizona_identify_headphone()
621 pm_runtime_get_sync(arizona->dev); in arizona_identify_headphone()
623 info->hpdet_active = true; in arizona_identify_headphone()
629 ret = regmap_update_bits(arizona->regmap, in arizona_identify_headphone()
632 arizona->pdata.hpdet_channel); in arizona_identify_headphone()
634 dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret); in arizona_identify_headphone()
638 ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, in arizona_identify_headphone()
641 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", ret); in arizona_identify_headphone()
649 pm_runtime_put_autosuspend(arizona->dev); in arizona_identify_headphone()
652 snd_soc_jack_report(info->jack, SND_JACK_HEADPHONE, in arizona_identify_headphone()
655 if (info->mic) in arizona_identify_headphone()
658 info->hpdet_active = false; in arizona_identify_headphone()
663 struct arizona *arizona = info->arizona; in arizona_start_hpdet_acc_id()
668 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); in arizona_start_hpdet_acc_id()
671 pm_runtime_get_sync(arizona->dev); in arizona_start_hpdet_acc_id()
673 info->hpdet_active = true; in arizona_start_hpdet_acc_id()
677 ret = regmap_update_bits(arizona->regmap, in arizona_start_hpdet_acc_id()
680 info->micd_modes[0].src | in arizona_start_hpdet_acc_id()
681 arizona->pdata.hpdet_channel); in arizona_start_hpdet_acc_id()
683 dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret); in arizona_start_hpdet_acc_id()
687 if (arizona->pdata.hpdet_acc_id_line) { in arizona_start_hpdet_acc_id()
688 ret = regmap_update_bits(arizona->regmap, in arizona_start_hpdet_acc_id()
692 dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", ret); in arizona_start_hpdet_acc_id()
703 snd_soc_jack_report(info->jack, SND_JACK_HEADPHONE, in arizona_start_hpdet_acc_id()
706 info->hpdet_active = false; in arizona_start_hpdet_acc_id()
715 mutex_lock(&info->lock); in arizona_micd_timeout_work()
717 dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n"); in arizona_micd_timeout_work()
719 info->detecting = false; in arizona_micd_timeout_work()
723 mutex_unlock(&info->lock); in arizona_micd_timeout_work()
728 struct arizona *arizona = info->arizona; in arizona_micd_adc_read()
733 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_micd_adc_read()
736 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val); in arizona_micd_adc_read()
738 dev_err(arizona->dev, "Failed to read MICDET_ADCVAL: %d\n", ret); in arizona_micd_adc_read()
742 dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val); in arizona_micd_adc_read()
764 struct arizona *arizona = info->arizona; in arizona_micd_read()
769 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); in arizona_micd_read()
771 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); in arizona_micd_read()
775 dev_dbg(arizona->dev, "MICDET: %x\n", val); in arizona_micd_read()
778 dev_warn(arizona->dev, "Microphone detection state invalid\n"); in arizona_micd_read()
779 return -EINVAL; in arizona_micd_read()
784 dev_err(arizona->dev, "Failed to get valid MICDET value\n"); in arizona_micd_read()
785 return -EINVAL; in arizona_micd_read()
794 struct arizona *arizona = info->arizona; in arizona_micdet_reading()
797 if (info->detecting && arizona->pdata.micd_software_compare) in arizona_micdet_reading()
808 dev_warn(arizona->dev, "Detected open circuit\n"); in arizona_micdet_reading()
809 info->mic = false; in arizona_micdet_reading()
810 info->detecting = false; in arizona_micdet_reading()
817 info->mic = true; in arizona_micdet_reading()
818 info->detecting = false; in arizona_micdet_reading()
822 snd_soc_jack_report(info->jack, SND_JACK_MICROPHONE, SND_JACK_MICROPHONE); in arizona_micdet_reading()
825 ret = regulator_allow_bypass(info->micvdd, true); in arizona_micdet_reading()
827 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", ret); in arizona_micdet_reading()
839 if (info->jack_flips >= info->micd_num_modes * 10) { in arizona_micdet_reading()
840 dev_dbg(arizona->dev, "Detected HP/line\n"); in arizona_micdet_reading()
842 info->detecting = false; in arizona_micdet_reading()
846 info->micd_mode++; in arizona_micdet_reading()
847 if (info->micd_mode == info->micd_num_modes) in arizona_micdet_reading()
848 info->micd_mode = 0; in arizona_micdet_reading()
849 arizona_extcon_set_mode(info, info->micd_mode); in arizona_micdet_reading()
851 info->jack_flips++; in arizona_micdet_reading()
853 if (arizona->pdata.micd_software_compare) in arizona_micdet_reading()
854 regmap_update_bits(arizona->regmap, in arizona_micdet_reading()
860 &info->micd_timeout_work, in arizona_micdet_reading()
861 msecs_to_jiffies(arizona->pdata.micd_timeout)); in arizona_micdet_reading()
871 dev_dbg(arizona->dev, "Headphone detected\n"); in arizona_micdet_reading()
872 info->detecting = false; in arizona_micdet_reading()
882 struct arizona *arizona = info->arizona; in arizona_button_reading()
894 if (info->mic) { in arizona_button_reading()
895 dev_dbg(arizona->dev, "Mic button detected\n"); in arizona_button_reading()
900 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) { in arizona_button_reading()
901 key = ffs(lvl) - 1; in arizona_button_reading()
902 snd_soc_jack_report(info->jack, in arizona_button_reading()
904 info->micd_button_mask); in arizona_button_reading()
906 dev_err(arizona->dev, "Button out of range\n"); in arizona_button_reading()
909 dev_warn(arizona->dev, "Button with no mic: %x\n", val); in arizona_button_reading()
912 dev_dbg(arizona->dev, "Mic button released\n"); in arizona_button_reading()
913 snd_soc_jack_report(info->jack, 0, info->micd_button_mask); in arizona_button_reading()
925 struct arizona *arizona = info->arizona; in arizona_micd_detect()
927 cancel_delayed_work_sync(&info->micd_timeout_work); in arizona_micd_detect()
929 mutex_lock(&info->lock); in arizona_micd_detect()
932 if (!(info->jack->status & SND_JACK_MECHANICAL)) { in arizona_micd_detect()
933 dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n"); in arizona_micd_detect()
934 mutex_unlock(&info->lock); in arizona_micd_detect()
938 if (info->detecting) in arizona_micd_detect()
943 pm_runtime_mark_last_busy(arizona->dev); in arizona_micd_detect()
944 mutex_unlock(&info->lock); in arizona_micd_detect()
950 struct arizona *arizona = info->arizona; in arizona_micdet()
951 int debounce = arizona->pdata.micd_detect_debounce; in arizona_micdet()
953 cancel_delayed_work_sync(&info->micd_detect_work); in arizona_micdet()
954 cancel_delayed_work_sync(&info->micd_timeout_work); in arizona_micdet()
956 mutex_lock(&info->lock); in arizona_micdet()
957 if (!info->detecting) in arizona_micdet()
959 mutex_unlock(&info->lock); in arizona_micdet()
963 &info->micd_detect_work, in arizona_micdet()
966 arizona_micd_detect(&info->micd_detect_work.work); in arizona_micdet()
977 mutex_lock(&info->lock); in arizona_hpdet_work()
979 mutex_unlock(&info->lock); in arizona_hpdet_work()
984 struct arizona *arizona = info->arizona; in arizona_hpdet_wait()
989 ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, in arizona_hpdet_wait()
992 dev_err(arizona->dev, "Failed to read HPDET state: %d\n", ret); in arizona_hpdet_wait()
996 switch (info->hpdet_ip_version) { in arizona_hpdet_wait()
1010 dev_warn(arizona->dev, "HPDET did not appear to complete\n"); in arizona_hpdet_wait()
1012 return -ETIMEDOUT; in arizona_hpdet_wait()
1018 struct arizona *arizona = info->arizona; in arizona_jackdet()
1023 cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work); in arizona_jackdet()
1024 cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work); in arizona_jackdet()
1026 pm_runtime_get_sync(arizona->dev); in arizona_jackdet()
1028 mutex_lock(&info->lock); in arizona_jackdet()
1030 if (info->micd_clamp) { in arizona_jackdet()
1035 if (arizona->pdata.jd_invert) in arizona_jackdet()
1041 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val); in arizona_jackdet()
1043 dev_err(arizona->dev, "Failed to read jackdet status: %d\n", ret); in arizona_jackdet()
1044 mutex_unlock(&info->lock); in arizona_jackdet()
1045 pm_runtime_put_autosuspend(arizona->dev); in arizona_jackdet()
1050 if (val == info->last_jackdet) { in arizona_jackdet()
1051 dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); in arizona_jackdet()
1054 &info->hpdet_work, in arizona_jackdet()
1058 int micd_timeout = arizona->pdata.micd_timeout; in arizona_jackdet()
1061 &info->micd_timeout_work, in arizona_jackdet()
1067 info->last_jackdet = val; in arizona_jackdet()
1069 if (info->last_jackdet == present) { in arizona_jackdet()
1070 dev_dbg(arizona->dev, "Detected jack\n"); in arizona_jackdet()
1071 snd_soc_jack_report(info->jack, SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); in arizona_jackdet()
1073 info->detecting = true; in arizona_jackdet()
1074 info->mic = false; in arizona_jackdet()
1075 info->jack_flips = 0; in arizona_jackdet()
1077 if (!arizona->pdata.hpdet_acc_id) { in arizona_jackdet()
1081 &info->hpdet_work, in arizona_jackdet()
1085 if (info->micd_clamp || !arizona->pdata.jd_invert) in arizona_jackdet()
1086 regmap_update_bits(arizona->regmap, in arizona_jackdet()
1091 dev_dbg(arizona->dev, "Detected jack removal\n"); in arizona_jackdet()
1095 info->num_hpdet_res = 0; in arizona_jackdet()
1096 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++) in arizona_jackdet()
1097 info->hpdet_res[i] = 0; in arizona_jackdet()
1098 info->mic = false; in arizona_jackdet()
1099 info->hpdet_done = false; in arizona_jackdet()
1100 info->hpdet_retried = false; in arizona_jackdet()
1102 snd_soc_jack_report(info->jack, 0, ARIZONA_JACK_MASK | info->micd_button_mask); in arizona_jackdet()
1113 regmap_update_bits(arizona->regmap, in arizona_jackdet()
1121 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, in arizona_jackdet()
1127 mutex_unlock(&info->lock); in arizona_jackdet()
1129 pm_runtime_put_autosuspend(arizona->dev); in arizona_jackdet()
1141 reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2); in arizona_micd_set_level()
1151 regmap_update_bits(arizona->regmap, reg, mask, level); in arizona_micd_set_level()
1157 const char * const prop = "wlf,micd-configs"; in arizona_extcon_get_micd_configs()
1164 nconfs = device_property_count_u32(arizona->dev, prop); in arizona_extcon_get_micd_configs()
1170 return -ENOMEM; in arizona_extcon_get_micd_configs()
1172 ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs); in arizona_extcon_get_micd_configs()
1180 ret = -ENOMEM; in arizona_extcon_get_micd_configs()
1190 arizona->pdata.micd_configs = micd_configs; in arizona_extcon_get_micd_configs()
1191 arizona->pdata.num_micd_configs = nconfs; in arizona_extcon_get_micd_configs()
1201 struct arizona_pdata *pdata = &arizona->pdata; in arizona_extcon_device_get_pdata()
1205 device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val); in arizona_extcon_device_get_pdata()
1209 pdata->hpdet_channel = val; in arizona_extcon_device_get_pdata()
1212 dev_err(arizona->dev, "Wrong wlf,hpdet-channel DT value %d\n", val); in arizona_extcon_device_get_pdata()
1213 pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL; in arizona_extcon_device_get_pdata()
1216 device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce", in arizona_extcon_device_get_pdata()
1217 &pdata->micd_detect_debounce); in arizona_extcon_device_get_pdata()
1219 device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time", in arizona_extcon_device_get_pdata()
1220 &pdata->micd_bias_start_time); in arizona_extcon_device_get_pdata()
1222 device_property_read_u32(arizona->dev, "wlf,micd-rate", in arizona_extcon_device_get_pdata()
1223 &pdata->micd_rate); in arizona_extcon_device_get_pdata()
1225 device_property_read_u32(arizona->dev, "wlf,micd-dbtime", in arizona_extcon_device_get_pdata()
1226 &pdata->micd_dbtime); in arizona_extcon_device_get_pdata()
1228 device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms", in arizona_extcon_device_get_pdata()
1229 &pdata->micd_timeout); in arizona_extcon_device_get_pdata()
1231 pdata->micd_force_micbias = device_property_read_bool(arizona->dev, in arizona_extcon_device_get_pdata()
1232 "wlf,micd-force-micbias"); in arizona_extcon_device_get_pdata()
1234 pdata->micd_software_compare = device_property_read_bool(arizona->dev, in arizona_extcon_device_get_pdata()
1235 "wlf,micd-software-compare"); in arizona_extcon_device_get_pdata()
1237 pdata->jd_invert = device_property_read_bool(arizona->dev, in arizona_extcon_device_get_pdata()
1238 "wlf,jd-invert"); in arizona_extcon_device_get_pdata()
1240 device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw); in arizona_extcon_device_get_pdata()
1242 pdata->jd_gpio5 = device_property_read_bool(arizona->dev, in arizona_extcon_device_get_pdata()
1243 "wlf,use-jd2"); in arizona_extcon_device_get_pdata()
1244 pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev, in arizona_extcon_device_get_pdata()
1245 "wlf,use-jd2-nopull"); in arizona_extcon_device_get_pdata()
1249 dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret); in arizona_extcon_device_get_pdata()
1256 struct arizona *arizona = info->arizona; in arizona_jack_codec_dev_probe()
1257 struct arizona_pdata *pdata = &arizona->pdata; in arizona_jack_codec_dev_probe()
1260 if (!dev_get_platdata(arizona->dev)) in arizona_jack_codec_dev_probe()
1263 info->micvdd = devm_regulator_get(dev, "MICVDD"); in arizona_jack_codec_dev_probe()
1264 if (IS_ERR(info->micvdd)) in arizona_jack_codec_dev_probe()
1265 return dev_err_probe(arizona->dev, PTR_ERR(info->micvdd), "getting MICVDD\n"); in arizona_jack_codec_dev_probe()
1267 mutex_init(&info->lock); in arizona_jack_codec_dev_probe()
1268 info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS); in arizona_jack_codec_dev_probe()
1269 INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); in arizona_jack_codec_dev_probe()
1270 INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect); in arizona_jack_codec_dev_probe()
1271 INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work); in arizona_jack_codec_dev_probe()
1273 switch (arizona->type) { in arizona_jack_codec_dev_probe()
1275 switch (arizona->rev) { in arizona_jack_codec_dev_probe()
1277 info->micd_reva = true; in arizona_jack_codec_dev_probe()
1280 info->micd_clamp = true; in arizona_jack_codec_dev_probe()
1281 info->hpdet_ip_version = 1; in arizona_jack_codec_dev_probe()
1287 switch (arizona->rev) { in arizona_jack_codec_dev_probe()
1291 info->micd_clamp = true; in arizona_jack_codec_dev_probe()
1292 info->hpdet_ip_version = 2; in arizona_jack_codec_dev_probe()
1298 info->micd_clamp = true; in arizona_jack_codec_dev_probe()
1299 info->hpdet_ip_version = 2; in arizona_jack_codec_dev_probe()
1305 if (!pdata->micd_timeout) in arizona_jack_codec_dev_probe()
1306 pdata->micd_timeout = DEFAULT_MICD_TIMEOUT; in arizona_jack_codec_dev_probe()
1308 if (pdata->num_micd_configs) { in arizona_jack_codec_dev_probe()
1309 info->micd_modes = pdata->micd_configs; in arizona_jack_codec_dev_probe()
1310 info->micd_num_modes = pdata->num_micd_configs; in arizona_jack_codec_dev_probe()
1312 info->micd_modes = micd_default_modes; in arizona_jack_codec_dev_probe()
1313 info->micd_num_modes = ARRAY_SIZE(micd_default_modes); in arizona_jack_codec_dev_probe()
1316 if (arizona->pdata.gpsw > 0) in arizona_jack_codec_dev_probe()
1317 regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1, in arizona_jack_codec_dev_probe()
1318 ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw); in arizona_jack_codec_dev_probe()
1320 if (pdata->micd_pol_gpio > 0) { in arizona_jack_codec_dev_probe()
1321 if (info->micd_modes[0].gpio) in arizona_jack_codec_dev_probe()
1326 ret = devm_gpio_request_one(dev, pdata->micd_pol_gpio, in arizona_jack_codec_dev_probe()
1329 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n", in arizona_jack_codec_dev_probe()
1330 pdata->micd_pol_gpio, ret); in arizona_jack_codec_dev_probe()
1334 info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio); in arizona_jack_codec_dev_probe()
1336 if (info->micd_modes[0].gpio) in arizona_jack_codec_dev_probe()
1346 info->micd_pol_gpio = gpiod_get_optional(arizona->dev, in arizona_jack_codec_dev_probe()
1347 "wlf,micd-pol", in arizona_jack_codec_dev_probe()
1349 if (IS_ERR(info->micd_pol_gpio)) { in arizona_jack_codec_dev_probe()
1350 ret = PTR_ERR(info->micd_pol_gpio); in arizona_jack_codec_dev_probe()
1351 dev_err_probe(arizona->dev, ret, "getting microphone polarity GPIO\n"); in arizona_jack_codec_dev_probe()
1356 if (arizona->pdata.hpdet_id_gpio > 0) { in arizona_jack_codec_dev_probe()
1357 ret = devm_gpio_request_one(dev, arizona->pdata.hpdet_id_gpio, in arizona_jack_codec_dev_probe()
1361 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n", in arizona_jack_codec_dev_probe()
1362 arizona->pdata.hpdet_id_gpio, ret); in arizona_jack_codec_dev_probe()
1363 gpiod_put(info->micd_pol_gpio); in arizona_jack_codec_dev_probe()
1374 gpiod_put(info->micd_pol_gpio); in arizona_jack_codec_dev_remove()
1382 struct arizona *arizona = info->arizona; in arizona_jack_enable_jack_detect()
1383 struct arizona_pdata *pdata = &arizona->pdata; in arizona_jack_enable_jack_detect()
1389 if (arizona->pdata.micd_bias_start_time) in arizona_jack_enable_jack_detect()
1390 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_jack_enable_jack_detect()
1392 arizona->pdata.micd_bias_start_time in arizona_jack_enable_jack_detect()
1395 if (arizona->pdata.micd_rate) in arizona_jack_enable_jack_detect()
1396 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_jack_enable_jack_detect()
1398 arizona->pdata.micd_rate in arizona_jack_enable_jack_detect()
1401 switch (arizona->pdata.micd_dbtime) { in arizona_jack_enable_jack_detect()
1403 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_jack_enable_jack_detect()
1408 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_jack_enable_jack_detect()
1418 if (arizona->pdata.num_micd_ranges) { in arizona_jack_enable_jack_detect()
1419 info->micd_ranges = pdata->micd_ranges; in arizona_jack_enable_jack_detect()
1420 info->num_micd_ranges = pdata->num_micd_ranges; in arizona_jack_enable_jack_detect()
1422 info->micd_ranges = micd_default_ranges; in arizona_jack_enable_jack_detect()
1423 info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges); in arizona_jack_enable_jack_detect()
1426 if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_BUTTONS) { in arizona_jack_enable_jack_detect()
1427 dev_err(arizona->dev, "Too many MICD ranges: %d > %d\n", in arizona_jack_enable_jack_detect()
1428 arizona->pdata.num_micd_ranges, ARIZONA_MAX_MICD_BUTTONS); in arizona_jack_enable_jack_detect()
1429 return -EINVAL; in arizona_jack_enable_jack_detect()
1432 if (info->num_micd_ranges > 1) { in arizona_jack_enable_jack_detect()
1433 for (i = 1; i < info->num_micd_ranges; i++) { in arizona_jack_enable_jack_detect()
1434 if (info->micd_ranges[i - 1].max > in arizona_jack_enable_jack_detect()
1435 info->micd_ranges[i].max) { in arizona_jack_enable_jack_detect()
1436 dev_err(arizona->dev, "MICD ranges must be sorted\n"); in arizona_jack_enable_jack_detect()
1437 return -EINVAL; in arizona_jack_enable_jack_detect()
1443 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, in arizona_jack_enable_jack_detect()
1447 for (i = 0; i < info->num_micd_ranges; i++) { in arizona_jack_enable_jack_detect()
1449 if (arizona_micd_levels[j] >= info->micd_ranges[i].max) in arizona_jack_enable_jack_detect()
1453 dev_err(arizona->dev, "Unsupported MICD level %d\n", in arizona_jack_enable_jack_detect()
1454 info->micd_ranges[i].max); in arizona_jack_enable_jack_detect()
1455 return -EINVAL; in arizona_jack_enable_jack_detect()
1458 dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n", in arizona_jack_enable_jack_detect()
1464 info->micd_button_mask |= SND_JACK_BTN_0 >> i; in arizona_jack_enable_jack_detect()
1465 snd_jack_set_key(jack->jack, SND_JACK_BTN_0 >> i, in arizona_jack_enable_jack_detect()
1466 info->micd_ranges[i].key); in arizona_jack_enable_jack_detect()
1469 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2, in arizona_jack_enable_jack_detect()
1481 if (info->micd_clamp) { in arizona_jack_enable_jack_detect()
1482 if (arizona->pdata.jd_gpio5) { in arizona_jack_enable_jack_detect()
1485 if (arizona->pdata.jd_gpio5_nopull) in arizona_jack_enable_jack_detect()
1488 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, in arizona_jack_enable_jack_detect()
1491 if (arizona->pdata.jd_invert) in arizona_jack_enable_jack_detect()
1496 if (arizona->pdata.jd_invert) in arizona_jack_enable_jack_detect()
1502 regmap_update_bits(arizona->regmap, in arizona_jack_enable_jack_detect()
1506 regmap_update_bits(arizona->regmap, in arizona_jack_enable_jack_detect()
1514 info->jack = jack; in arizona_jack_enable_jack_detect()
1516 pm_runtime_get_sync(arizona->dev); in arizona_jack_enable_jack_detect()
1518 if (info->micd_clamp) { in arizona_jack_enable_jack_detect()
1529 dev_err(arizona->dev, "Failed to get JACKDET rise IRQ: %d\n", ret); in arizona_jack_enable_jack_detect()
1535 dev_err(arizona->dev, "Failed to set JD rise IRQ wake: %d\n", ret); in arizona_jack_enable_jack_detect()
1542 dev_err(arizona->dev, "Failed to get JD fall IRQ: %d\n", ret); in arizona_jack_enable_jack_detect()
1548 dev_err(arizona->dev, "Failed to set JD fall IRQ wake: %d\n", ret); in arizona_jack_enable_jack_detect()
1555 dev_err(arizona->dev, "Failed to get MICDET IRQ: %d\n", ret); in arizona_jack_enable_jack_detect()
1562 dev_err(arizona->dev, "Failed to get HPDET IRQ: %d\n", ret); in arizona_jack_enable_jack_detect()
1567 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE, in arizona_jack_enable_jack_detect()
1569 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, in arizona_jack_enable_jack_detect()
1572 ret = regulator_allow_bypass(info->micvdd, true); in arizona_jack_enable_jack_detect()
1574 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n", ret); in arizona_jack_enable_jack_detect()
1576 pm_runtime_put(arizona->dev); in arizona_jack_enable_jack_detect()
1591 pm_runtime_put(arizona->dev); in arizona_jack_enable_jack_detect()
1592 info->jack = NULL; in arizona_jack_enable_jack_detect()
1598 struct arizona *arizona = info->arizona; in arizona_jack_disable_jack_detect()
1603 if (!info->jack) in arizona_jack_disable_jack_detect()
1606 if (info->micd_clamp) { in arizona_jack_disable_jack_detect()
1620 cancel_delayed_work_sync(&info->hpdet_work); in arizona_jack_disable_jack_detect()
1621 cancel_delayed_work_sync(&info->micd_detect_work); in arizona_jack_disable_jack_detect()
1622 cancel_delayed_work_sync(&info->micd_timeout_work); in arizona_jack_disable_jack_detect()
1624 ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, in arizona_jack_disable_jack_detect()
1628 dev_err(arizona->dev, "Failed to disable micd on remove: %d\n", ret); in arizona_jack_disable_jack_detect()
1630 regulator_disable(info->micvdd); in arizona_jack_disable_jack_detect()
1631 pm_runtime_put(arizona->dev); in arizona_jack_disable_jack_detect()
1634 regmap_update_bits(arizona->regmap, in arizona_jack_disable_jack_detect()
1637 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, in arizona_jack_disable_jack_detect()
1640 info->jack = NULL; in arizona_jack_disable_jack_detect()