2 * extcon-madera.c - Extcon driver for Cirrus Logic Madera codecs
4 * Copyright 2015-2017 Cirrus Logic
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/device.h>
14 #include <linux/delay.h>
15 #include <linux/err.h>
16 #include <linux/extcon.h>
17 #include <linux/gpio.h>
18 #include <linux/input.h>
19 #include <linux/interrupt.h>
20 #include <linux/math64.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/property.h>
24 #include <linux/regmap.h>
25 #include <linux/slab.h>
26 #include <linux/regulator/consumer.h>
28 #include <sound/soc.h>
30 #include <linux/extcon/extcon-madera.h>
31 #include <linux/extcon/extcon-madera-pdata.h>
32 #include <dt-bindings/extcon/extcon-madera.h>
34 #include <linux/mfd/madera/core.h>
35 #include <linux/mfd/madera/pdata.h>
36 #include <linux/mfd/madera/registers.h>
38 #define MADERA_MAX_MICD_RANGE 8
40 #define MADERA_MICD_CLAMP_MODE_JD1L 0x4
41 #define MADERA_MICD_CLAMP_MODE_JD1H 0x5
42 #define MADERA_MICD_CLAMP_MODE_JD1L_JD2L 0x8
43 #define MADERA_MICD_CLAMP_MODE_JD1L_JD2H 0x9
44 #define MADERA_MICD_CLAMP_MODE_JD1H_JD2H 0xb
46 #define MADERA_HPDET_MAX_OHM 10000
47 #define MADERA_HPDET_MAX_HOHM (MADERA_HPDET_MAX_OHM * 100)
48 #define MADERA_HP_SHORT_IMPEDANCE_MIN 4
50 #define MADERA_HPDET_DEBOUNCE_MS 500
51 #define MADERA_DEFAULT_MICD_TIMEOUT_MS 2000
53 #define MADERA_HPDONE_PROBE_INTERVAL_MS 20
54 #define MADERA_HPDONE_PROBE_COUNT 15
56 #define MADERA_MICROPHONE_MIN_OHM 1258
57 #define MADERA_MICROPHONE_MAX_OHM 30000
59 #define MADERA_HP_TUNING_INVALID -1
63 static const unsigned int madera_cable
[] = {
65 EXTCON_JACK_HEADPHONE
,
66 EXTCON_JACK_MICROPHONE
,
71 static const struct madera_micd_config cs47l85_micd_default_modes
[] = {
72 { MADERA_ACCD_SENSE_MICDET2
, 0, MADERA_ACCD_BIAS_SRC_MICBIAS1
, 0, 0 },
73 { MADERA_ACCD_SENSE_MICDET1
, 0, MADERA_ACCD_BIAS_SRC_MICBIAS2
, 1, 0 },
76 static const struct madera_micd_config madera_micd_default_modes
[] = {
77 { MADERA_MICD1_SENSE_MICDET1
, MADERA_MICD1_GND_MICDET2
,
78 MADERA_MICD_BIAS_SRC_MICBIAS1A
, 0, MADERA_HPD_GND_HPOUTFB2
},
79 { MADERA_MICD1_SENSE_MICDET2
, MADERA_MICD1_GND_MICDET1
,
80 MADERA_MICD_BIAS_SRC_MICBIAS1B
, 1, MADERA_HPD_GND_HPOUTFB1
},
83 static const unsigned int madera_default_hpd_pins
[4] = {
84 [0] = MADERA_HPD_OUT_OUT1L
,
85 [1] = MADERA_HPD_SENSE_HPDET1
,
86 [2] = MADERA_HPD_OUT_OUT1R
,
87 [3] = MADERA_HPD_SENSE_HPDET1
,
90 static struct madera_micd_range madera_micd_default_ranges
[] = {
91 { .max
= 70, .key
= KEY_MEDIA
},
92 { .max
= 186, .key
= KEY_VOICECOMMAND
},
93 { .max
= 295, .key
= KEY_VOLUMEUP
},
94 { .max
= 681, .key
= KEY_VOLUMEDOWN
},
97 /* The number of levels in madera_micd_levels valid for button thresholds */
98 #define MADERA_NUM_MICD_BUTTON_LEVELS 64
100 /* ohms for each micd level */
101 static const int madera_micd_levels
[] = {
102 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
103 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
104 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
105 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
110 * HP calibration data
111 * See the datasheet for the meanings of the constants and their values
113 struct madera_hpdet_calibration_data
{
116 s64 C0
; /* value * 1000000 */
117 s64 C1
; /* value * 10000 */
118 s64 C2
; /* not multiplied */
119 s64 C3
; /* value * 1000000 */
120 s64 C4_x_C3
; /* value * 1000000 */
121 s64 C5
; /* value * 1000000 */
125 static const struct madera_hpdet_calibration_data cs47l15_hpdet_ranges
[] = {
127 { 33, 123, 1000000, -4300, 7975, 69600000, 382800, 33350000,
129 { 123, 1033, 9633000, -79500, 7300, 62900000, 283050, 33350000,
131 { 1033, 10033, 100684000, -949400, 7300, 63200000, 284400, 33350000,
136 static const struct madera_hpdet_calibration_data cs47l85_hpdet_ranges
[] = {
137 { 4, 30, 1007000, -7200, 4003, 69300000, 381150, 250000, 500000},
138 { 8, 100, 1007000, -7200, 7975, 69600000, 382800, 250000, 500000},
139 { 100, 1000, 9696000, -79500, 7300, 62900000, 345950, 250000, 500000},
140 { 1000, 10000, 100684000, -949400, 7300, 63200000, 347600, 250000, 500000},
143 static const struct madera_hpdet_calibration_data madera_hpdet_ranges
[] = {
144 { 4, 30, 1014000, -4300, 3950, 69300000, 381150, 700000, 500000},
145 { 8, 100, 1014000, -8600, 7975, 69600000, 382800, 700000, 500000},
146 { 100, 1000, 9744000, -79500, 7300, 62900000, 345950, 700000, 500000},
147 { 1000, 10000, 101158000, -949400, 7300, 63200000, 347600, 700000, 500000},
150 static const struct madera_hpdet_calibration_data cs47l92_hpdet_ranges
[] = {
151 { 4, 30, 1007000, -7200, 4005, 69300000, 381150, 600000, 500000},
152 { 8, 100, 1007000, -7200, 7975, 69600000, 382800, 600000, 500000},
153 { 100, 1000, 9744000, -79500, 7300, 62900000, 345950, 600000, 500000},
154 { 1000, 10000, 100684000, -949400, 7300, 63200000, 347600, 600000, 500000},
157 struct madera_hp_tuning
{
159 const struct reg_sequence
*patch
;
163 static const struct reg_sequence cs47l15_low_impedance_patch
[] = {
197 static const struct reg_sequence cs47l15_normal_impedance_patch
[] = {
231 static const struct reg_sequence cs47l15_high_impedance_patch
[] = {
265 static const struct madera_hp_tuning cs47l15_hp_tuning
[] = {
268 cs47l15_low_impedance_patch
,
269 ARRAY_SIZE(cs47l15_low_impedance_patch
),
273 cs47l15_normal_impedance_patch
,
274 ARRAY_SIZE(cs47l15_normal_impedance_patch
),
277 MADERA_HPDET_MAX_HOHM
,
278 cs47l15_high_impedance_patch
,
279 ARRAY_SIZE(cs47l15_high_impedance_patch
),
283 static const struct reg_sequence cs47l35_low_impedance_patch
[] = {
317 static const struct reg_sequence cs47l35_normal_impedance_patch
[] = {
351 static const struct madera_hp_tuning cs47l35_hp_tuning
[] = {
354 cs47l35_low_impedance_patch
,
355 ARRAY_SIZE(cs47l35_low_impedance_patch
),
358 MADERA_HPDET_MAX_HOHM
,
359 cs47l35_normal_impedance_patch
,
360 ARRAY_SIZE(cs47l35_normal_impedance_patch
),
364 static const struct reg_sequence cs47l85_low_impedance_patch
[] = {
374 static const struct reg_sequence cs47l85_normal_impedance_patch
[] = {
384 static const struct madera_hp_tuning cs47l85_hp_tuning
[] = {
387 cs47l85_low_impedance_patch
,
388 ARRAY_SIZE(cs47l85_low_impedance_patch
),
391 MADERA_HPDET_MAX_HOHM
,
392 cs47l85_normal_impedance_patch
,
393 ARRAY_SIZE(cs47l85_normal_impedance_patch
),
397 static const struct reg_sequence cs47l90_low_impedance_patch
[] = {
431 static const struct reg_sequence cs47l90_normal_impedance_patch
[] = {
465 static const struct reg_sequence cs47l90_high_impedance_patch
[] = {
499 static const struct madera_hp_tuning cs47l90_hp_tuning
[] = {
502 cs47l90_low_impedance_patch
,
503 ARRAY_SIZE(cs47l90_low_impedance_patch
),
506 cs47l90_normal_impedance_patch
,
507 ARRAY_SIZE(cs47l90_normal_impedance_patch
),
509 { MADERA_HPDET_MAX_HOHM
,
510 cs47l90_high_impedance_patch
,
511 ARRAY_SIZE(cs47l90_high_impedance_patch
),
515 static const struct reg_sequence cs47l92_low_impedance_patch
[] = {
549 static const struct reg_sequence cs47l92_normal_impedance_patch
[] = {
583 static const struct reg_sequence cs47l92_high_impedance_patch
[] = {
617 static const struct madera_hp_tuning cs47l92_hp_tuning
[] = {
620 cs47l92_low_impedance_patch
,
621 ARRAY_SIZE(cs47l92_low_impedance_patch
),
624 cs47l92_normal_impedance_patch
,
625 ARRAY_SIZE(cs47l92_normal_impedance_patch
),
627 { MADERA_HPDET_MAX_HOHM
,
628 cs47l92_high_impedance_patch
,
629 ARRAY_SIZE(cs47l92_high_impedance_patch
),
633 static ssize_t
madera_extcon_show(struct device
*dev
,
634 struct device_attribute
*attr
,
637 struct platform_device
*pdev
= to_platform_device(dev
);
638 struct madera_extcon
*info
= platform_get_drvdata(pdev
);
640 return scnprintf(buf
, PAGE_SIZE
, "%d\n",
641 info
->madera
->hp_impedance_x100
[0]);
644 static DEVICE_ATTR(hp1_impedance
, 0444, madera_extcon_show
, NULL
);
646 inline void madera_extcon_report(struct madera_extcon
*info
,
647 int which
, bool attached
)
651 dev_warn(info
->dev
, "Extcon report: %d is %s\n",
652 which
, attached
? "attached" : "removed");
654 ret
= extcon_set_state_sync(info
->edev
, which
, attached
);
656 dev_warn(info
->dev
, "Failed to report cable state: %d\n", ret
);
658 if (IS_ENABLED(CONFIG_EXTCON_MADERA_INPUT_EVENT
)) {
660 case EXTCON_MECHANICAL
:
661 input_report_switch(info
->input
,
662 SW_JACK_PHYSICAL_INSERT
,
665 case EXTCON_JACK_HEADPHONE
:
666 input_report_switch(info
->input
,
670 case EXTCON_JACK_MICROPHONE
:
671 input_report_switch(info
->input
,
672 SW_MICROPHONE_INSERT
,
675 case EXTCON_JACK_LINE_OUT
:
676 input_report_switch(info
->input
,
682 input_sync(info
->input
);
685 EXPORT_SYMBOL_GPL(madera_extcon_report
);
688 enum madera_accdet_mode
madera_jds_get_mode(struct madera_extcon
*info
)
691 return info
->state
->mode
;
693 return MADERA_ACCDET_MODE_INVALID
;
696 int madera_jds_set_state(struct madera_extcon
*info
,
697 const struct madera_jd_state
*new_state
)
701 if (new_state
!= info
->state
) {
703 info
->state
->stop(info
);
705 info
->state
= new_state
;
708 ret
= info
->state
->start(info
);
716 EXPORT_SYMBOL_GPL(madera_jds_set_state
);
718 static void madera_jds_reading(struct madera_extcon
*info
, int val
)
722 ret
= info
->state
->reading(info
, val
);
724 if (ret
== -EAGAIN
&& info
->state
->restart
)
725 info
->state
->restart(info
);
728 static inline bool madera_jds_cancel_timeout(struct madera_extcon
*info
)
730 return cancel_delayed_work_sync(&info
->state_timeout_work
);
733 static void madera_jds_start_timeout(struct madera_extcon
*info
)
735 const struct madera_jd_state
*state
= info
->state
;
740 if (state
->timeout_ms
&& state
->timeout
) {
741 int ms
= state
->timeout_ms(info
);
743 schedule_delayed_work(&info
->state_timeout_work
,
744 msecs_to_jiffies(ms
));
748 static void madera_jds_timeout_work(struct work_struct
*work
)
750 struct madera_extcon
*info
=
751 container_of(work
, struct madera_extcon
,
752 state_timeout_work
.work
);
754 mutex_lock(&info
->lock
);
757 dev_warn(info
->dev
, "Spurious timeout in idle state\n");
758 } else if (!info
->state
->timeout
) {
759 dev_warn(info
->dev
, "Spurious timeout state.mode=%d\n",
762 info
->state
->timeout(info
);
763 madera_jds_start_timeout(info
);
766 mutex_unlock(&info
->lock
);
769 static void madera_extcon_hp_clamp(struct madera_extcon
*info
, bool clamp
)
771 struct madera
*madera
= info
->madera
;
772 unsigned int mask
= 0, ep_mask
= 0, val
= 0;
775 snd_soc_dapm_mutex_lock(madera
->dapm
);
777 switch (madera
->type
) {
780 ep_mask
= MADERA_EP_SEL_MASK
;
786 mask
= MADERA_HPD_OVD_ENA_SEL_MASK
;
788 val
= MADERA_HPD_OVD_ENA_SEL_MASK
;
794 madera
->out_clamp
[0] = clamp
;
796 /* Keep the HP output stages disabled while disabling the clamp */
798 ret
= regmap_update_bits(madera
->regmap
,
799 MADERA_OUTPUT_ENABLES_1
,
803 (2 * (info
->pdata
->output
- 1))),
807 "Failed to disable headphone outputs: %d\n",
811 dev_dbg(info
->dev
, "%s clamp mask=0x%x val=0x%x\n",
812 clamp
? "Setting" : "Clearing", mask
, val
);
814 switch (madera
->type
) {
820 ret
= regmap_update_bits(madera
->regmap
,
821 MADERA_HEADPHONE_DETECT_0
,
822 MADERA_HPD_OVD_ENA_SEL_MASK
,
825 dev_warn(info
->dev
, "Failed to do clamp: %d\n", ret
);
829 /* Restore the desired state when restoring the clamp */
832 ret
= regmap_update_bits(madera
->regmap
,
833 MADERA_OUTPUT_ENABLES_1
,
834 ep_mask
, madera
->ep_sel
);
837 "Failed to restore output demux: %d\n",
841 madera
->out_shorted
[0] = (madera
->hp_impedance_x100
[0] <=
842 info
->hpdet_short_x100
);
844 if (!madera
->out_shorted
[0]) {
845 ret
= regmap_update_bits(madera
->regmap
,
846 MADERA_OUTPUT_ENABLES_1
,
849 (2 * (info
->pdata
->output
- 1)),
853 "Failed to restore headphone outputs: %d\n",
858 snd_soc_dapm_mutex_unlock(madera
->dapm
);
861 static const char *madera_extcon_get_micbias_src(struct madera_extcon
*info
)
863 struct madera
*madera
= info
->madera
;
864 unsigned int bias
= info
->micd_modes
[info
->micd_mode
].bias
;
866 switch (madera
->type
) {
918 static const char *madera_extcon_get_micbias(struct madera_extcon
*info
)
920 struct madera
*madera
= info
->madera
;
921 unsigned int bias
= info
->micd_modes
[info
->micd_mode
].bias
;
923 switch (madera
->type
) {
1005 static void madera_extcon_enable_micbias_pin(struct madera_extcon
*info
,
1008 struct madera
*madera
= info
->madera
;
1009 struct snd_soc_dapm_context
*dapm
= madera
->dapm
;
1012 ret
= snd_soc_dapm_force_enable_pin(dapm
, widget
);
1014 dev_warn(info
->dev
, "Failed to enable %s: %d\n", widget
, ret
);
1016 snd_soc_dapm_sync(dapm
);
1018 dev_warn(info
->dev
, "Enabled %s\n", widget
);
1021 static void madera_extcon_disable_micbias_pin(struct madera_extcon
*info
,
1024 struct madera
*madera
= info
->madera
;
1025 struct snd_soc_dapm_context
*dapm
= madera
->dapm
;
1028 ret
= snd_soc_dapm_disable_pin(dapm
, widget
);
1030 dev_warn(info
->dev
, "Failed to enable %s: %d\n", widget
, ret
);
1032 snd_soc_dapm_sync(dapm
);
1034 dev_warn(info
->dev
, "Disabled %s\n", widget
);
1037 static void madera_extcon_set_micd_bias(struct madera_extcon
*info
, bool enable
)
1039 int old_bias
= info
->micd_bias
.bias
;
1040 int new_bias
= info
->micd_modes
[info
->micd_mode
].bias
;
1043 info
->micd_bias
.bias
= new_bias
;
1045 if ((new_bias
== old_bias
) && (info
->micd_bias
.enabled
== enable
))
1048 widget
= madera_extcon_get_micbias_src(info
);
1051 if (info
->micd_bias
.enabled
)
1052 madera_extcon_disable_micbias_pin(info
, widget
);
1055 madera_extcon_enable_micbias_pin(info
, widget
);
1057 info
->micd_bias
.enabled
= enable
;
1060 static void madera_extcon_enable_micbias(struct madera_extcon
*info
)
1062 struct madera
*madera
= info
->madera
;
1063 const char *widget
= madera_extcon_get_micbias(info
);
1065 switch (madera
->type
) {
1071 madera_extcon_set_micd_bias(info
, true);
1076 * If forced we must manually control the pin state, otherwise
1077 * the codec will manage this automatically
1079 if (info
->pdata
->micd_force_micbias
)
1080 madera_extcon_enable_micbias_pin(info
, widget
);
1083 static void madera_extcon_disable_micbias(struct madera_extcon
*info
)
1085 struct madera
*madera
= info
->madera
;
1086 const char *widget
= madera_extcon_get_micbias(info
);
1088 switch (madera
->type
) {
1094 madera_extcon_set_micd_bias(info
, false);
1099 * If forced we must manually control the pin state, otherwise
1100 * the codec will manage this automatically
1102 if (info
->pdata
->micd_force_micbias
)
1103 madera_extcon_disable_micbias_pin(info
, widget
);
1106 static void madera_extcon_set_mode(struct madera_extcon
*info
, int mode
)
1108 struct madera
*madera
= info
->madera
;
1111 "set mic_mode[%d] src=0x%x gnd=0x%x bias=0x%x gpio=%d hp_gnd=%d\n",
1112 mode
, info
->micd_modes
[mode
].src
, info
->micd_modes
[mode
].gnd
,
1113 info
->micd_modes
[mode
].bias
, info
->micd_modes
[mode
].gpio
,
1114 info
->micd_modes
[mode
].hp_gnd
);
1116 if (info
->micd_pol_gpio
)
1117 gpiod_set_value_cansleep(info
->micd_pol_gpio
,
1118 info
->micd_modes
[mode
].gpio
);
1120 switch (madera
->type
) {
1124 regmap_update_bits(madera
->regmap
,
1125 MADERA_MIC_DETECT_1_CONTROL_1
,
1126 MADERA_MICD_BIAS_SRC_MASK
,
1127 info
->micd_modes
[mode
].bias
<<
1128 MADERA_MICD_BIAS_SRC_SHIFT
);
1129 regmap_update_bits(madera
->regmap
,
1130 MADERA_ACCESSORY_DETECT_MODE_1
,
1132 info
->micd_modes
[mode
].src
<<
1133 MADERA_ACCDET_SRC_SHIFT
);
1136 regmap_update_bits(madera
->regmap
,
1137 MADERA_MIC_DETECT_1_CONTROL_1
,
1138 MADERA_MICD_BIAS_SRC_MASK
,
1139 info
->micd_modes
[mode
].bias
<<
1140 MADERA_MICD_BIAS_SRC_SHIFT
);
1141 regmap_update_bits(madera
->regmap
,
1142 MADERA_MIC_DETECT_1_CONTROL_0
,
1143 MADERA_MICD1_SENSE_MASK
,
1144 info
->micd_modes
[mode
].src
<<
1145 MADERA_MICD1_SENSE_SHIFT
);
1146 regmap_update_bits(madera
->regmap
,
1147 MADERA_MIC_DETECT_1_CONTROL_0
,
1148 MADERA_MICD1_GND_MASK
,
1149 info
->micd_modes
[mode
].gnd
<<
1150 MADERA_MICD1_GND_SHIFT
);
1151 regmap_update_bits(madera
->regmap
,
1152 MADERA_HEADPHONE_DETECT_0
,
1153 MADERA_HPD_GND_SEL_MASK
,
1154 info
->micd_modes
[mode
].gnd
<<
1155 MADERA_HPD_GND_SEL_SHIFT
);
1156 regmap_update_bits(madera
->regmap
,
1157 MADERA_OUTPUT_PATH_CONFIG_1
+
1158 (8 * (info
->pdata
->output
- 1)),
1159 MADERA_HP1_GND_SEL_MASK
,
1160 info
->micd_modes
[mode
].hp_gnd
<<
1161 MADERA_HP1_GND_SEL_SHIFT
);
1165 info
->micd_mode
= mode
;
1168 static void madera_extcon_next_mode(struct madera_extcon
*info
)
1170 int old_mode
= info
->micd_mode
;
1172 bool change_bias
= false;
1174 new_mode
= (old_mode
+ 1) % info
->num_micd_modes
;
1176 dev_warn(info
->dev
, "change micd mode %d->%d (bias %d->%d)\n",
1178 info
->micd_modes
[old_mode
].bias
,
1179 info
->micd_modes
[new_mode
].bias
);
1181 if (info
->micd_modes
[old_mode
].bias
!=
1182 info
->micd_modes
[new_mode
].bias
) {
1185 madera_extcon_disable_micbias(info
);
1188 madera_extcon_set_mode(info
, new_mode
);
1191 madera_extcon_enable_micbias(info
);
1194 static int madera_micd_adc_read(struct madera_extcon
*info
)
1196 struct madera
*madera
= info
->madera
;
1197 unsigned int val
= 0;
1200 /* Must disable MICD before we read the ADCVAL */
1201 ret
= regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1202 MADERA_MICD_ENA
, 0);
1204 dev_err(info
->dev
, "Failed to disable MICD: %d\n", ret
);
1208 ret
= regmap_read(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_4
, &val
);
1210 dev_err(info
->dev
, "Failed to read MICDET_ADCVAL: %d\n", ret
);
1214 dev_warn(info
->dev
, "MICDET_ADCVAL: 0x%x\n", val
);
1216 val
&= MADERA_MICDET_ADCVAL_MASK
;
1217 if (val
< ARRAY_SIZE(madera_micd_levels
))
1218 val
= madera_micd_levels
[val
];
1225 static int madera_micd_read(struct madera_extcon
*info
)
1227 struct madera
*madera
= info
->madera
;
1228 unsigned int val
= 0;
1231 for (i
= 0; i
< 10 && !(val
& MADERA_MICD_LVL_0_TO_8
); i
++) {
1232 ret
= regmap_read(madera
->regmap
,
1233 MADERA_MIC_DETECT_1_CONTROL_3
, &val
);
1236 "Failed to read MICDET: %d\n", ret
);
1240 dev_warn(info
->dev
, "MICDET: 0x%x\n", val
);
1242 if (!(val
& MADERA_MICD_VALID
)) {
1244 "Microphone detection state invalid\n");
1249 if (i
== 10 && !(val
& MADERA_MICD_LVL_0_TO_8
)) {
1250 dev_warn(info
->dev
, "Failed to get valid MICDET value\n");
1254 if (!(val
& MADERA_MICD_STS
)) {
1256 } else if (!(val
& MADERA_MICD_LVL_0_TO_7
)) {
1257 val
= madera_micd_levels
[ARRAY_SIZE(madera_micd_levels
) - 1];
1261 lvl
= (val
& MADERA_MICD_LVL_MASK
) >> MADERA_MICD_LVL_SHIFT
;
1264 if (lvl
< info
->num_micd_ranges
) {
1265 val
= info
->micd_ranges
[lvl
].max
;
1267 i
= ARRAY_SIZE(madera_micd_levels
) - 2;
1268 val
= madera_micd_levels
[i
];
1275 static void madera_extcon_notify_micd(const struct madera_extcon
*info
,
1277 unsigned int impedance
)
1279 struct madera_micdet_notify_data data
;
1281 data
.present
= present
;
1282 data
.impedance_x100
= madera_ohm_to_hohm(impedance
);
1283 data
.out_num
= info
->pdata
->output
;
1284 dev_warn(info
->dev
, "madera_extcon_notify_micd mic impedance is : %d, present is %d \n", data
.impedance_x100
,present
);
1285 madera_call_notifiers(info
->madera
, MADERA_NOTIFY_MICDET
, &data
);
1288 static int madera_hpdet_calc_calibration(const struct madera_extcon
*info
,
1290 const struct madera_hpdet_trims
*trims
,
1291 const struct madera_hpdet_calibration_data
*calib
)
1293 int grad_x4
= trims
->grad_x4
;
1294 int off_x4
= trims
->off_x4
;
1298 val
= (val
* 1000000) + calib
->dacval_adjust
;
1299 val
= div64_s64(val
, calib
->C2
);
1301 n
= div_s64(1000000000000LL, calib
->C3
+
1302 ((calib
->C4_x_C3
* grad_x4
) / 4));
1305 return MADERA_HPDET_MAX_HOHM
;
1307 val
= calib
->C0
+ ((calib
->C1
* off_x4
) / 4);
1310 val
= div_s64(val
, n
);
1313 /* Round up and divide to get hundredths of an ohm */
1315 val
= div_s64(val
, 10000);
1319 else if (val
> MADERA_HPDET_MAX_HOHM
)
1320 return MADERA_HPDET_MAX_HOHM
;
1325 static int madera_hpdet_calibrate(struct madera_extcon
*info
,
1326 unsigned int range
, unsigned int *ohms_x100
)
1328 struct madera
*madera
= info
->madera
;
1329 unsigned int dacval
, dacval_down
;
1332 ret
= regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_3
, &dacval
);
1334 dev_err(info
->dev
, "Failed to read HP DACVAL: %d\n", ret
);
1338 dacval
= (dacval
>> MADERA_HP_DACVAL_SHIFT
) & MADERA_HP_DACVAL_MASK
;
1340 switch (madera
->type
) {
1344 ret
= regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_5
,
1348 "Failed to read HP DACVAL_down: %d\n", ret
);
1352 dacval_down
= (dacval_down
>> MADERA_HP_DACVAL_DOWN_SHIFT
) &
1353 MADERA_HP_DACVAL_DOWN_MASK
;
1355 dacval
= (dacval
+ dacval_down
) / 2;
1362 "hpdet_d calib range %d dac %d\n", range
, dacval
);
1364 *ohms_x100
= madera_hpdet_calc_calibration(info
, dacval
,
1365 &info
->hpdet_trims
[range
],
1366 &info
->hpdet_ranges
[range
]);
1370 static int madera_hpdet_read(struct madera_extcon
*info
)
1372 struct madera
*madera
= info
->madera
;
1373 unsigned int val
, range
, sense_pin
, ohms_x100
;
1375 bool is_jdx_micdetx_pin
= false;
1376 int hpdet_ext_res_x100
;
1378 dev_warn(info
->dev
, "HPDET read\n");
1380 ret
= regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_2
, &val
);
1382 dev_err(info
->dev
, "Failed to read HPDET status: %d\n", ret
);
1386 if (!(val
& MADERA_HP_DONE_MASK
)) {
1387 dev_warn(info
->dev
, "HPDET did not complete: %x\n", val
);
1391 switch (madera
->type
) {
1397 regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_0
,
1399 sense_pin
= (sense_pin
& MADERA_HPD_SENSE_SEL_MASK
) >>
1400 MADERA_HPD_SENSE_SEL_SHIFT
;
1402 switch (sense_pin
) {
1403 case MADERA_HPD_SENSE_HPDET1
:
1404 case MADERA_HPD_SENSE_HPDET2
:
1405 is_jdx_micdetx_pin
= false;
1408 dev_warn(info
->dev
, "is_jdx_micdetx_pin\n");
1409 is_jdx_micdetx_pin
= true;
1414 val
&= MADERA_HP_LVL_MASK
;
1415 /* The value is in 0.5 ohm increments, get it in hundredths */
1416 ohms_x100
= val
* 50;
1418 if (is_jdx_micdetx_pin
)
1421 regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
, &range
);
1422 range
= (range
& MADERA_HP_IMPEDANCE_RANGE_MASK
) >>
1423 MADERA_HP_IMPEDANCE_RANGE_SHIFT
;
1425 /* Skip up a range, or report? */
1426 if (range
< info
->num_hpdet_ranges
- 1 &&
1427 ((val
/ 2) >= info
->hpdet_ranges
[range
].max
)) {
1429 dev_warn(info
->dev
, "Moving to HPDET range %d-%d\n",
1430 info
->hpdet_ranges
[range
].min
,
1431 info
->hpdet_ranges
[range
].max
);
1433 regmap_update_bits(madera
->regmap
,
1434 MADERA_HEADPHONE_DETECT_1
,
1435 MADERA_HP_IMPEDANCE_RANGE_MASK
,
1437 MADERA_HP_IMPEDANCE_RANGE_SHIFT
);
1441 if (info
->hpdet_trims
) {
1442 /* Perform calibration */
1443 ret
= madera_hpdet_calibrate(info
, range
, &ohms_x100
);
1447 /* Use uncalibrated reading */
1448 if (range
&& ((val
/ 2) < info
->hpdet_ranges
[range
].min
)) {
1450 "Reporting range boundary %d\n",
1451 info
->hpdet_ranges
[range
].min
);
1453 madera_ohm_to_hohm(info
->hpdet_ranges
[range
].min
);
1457 hpdet_ext_res_x100
= info
->pdata
->hpdet_ext_res_x100
;
1458 if (hpdet_ext_res_x100
) {
1459 if (hpdet_ext_res_x100
>= ohms_x100
) {
1461 "External resistor (%d.%02d) >= measurement (%d.00)\n",
1462 hpdet_ext_res_x100
/ 100,
1463 hpdet_ext_res_x100
% 100,
1465 val
= 0; /* treat as a short */
1468 "Compensating for external %d.%02d ohm resistor\n",
1469 hpdet_ext_res_x100
/ 100,
1470 hpdet_ext_res_x100
% 100);
1472 ohms_x100
-= hpdet_ext_res_x100
;
1477 dev_warn(info
->dev
, "HP impedance %d.%02d ohms\n",
1478 ohms_x100
/ 100, ohms_x100
% 100);
1480 return (int)ohms_x100
;
1483 static int madera_tune_headphone(struct madera_extcon
*info
, int reading
)
1485 struct madera
*madera
= info
->madera
;
1486 const struct madera_hp_tuning
*tuning
;
1490 switch (madera
->type
) {
1492 tuning
= cs47l15_hp_tuning
;
1493 n_tunings
= ARRAY_SIZE(cs47l15_hp_tuning
);
1496 tuning
= cs47l35_hp_tuning
;
1497 n_tunings
= ARRAY_SIZE(cs47l35_hp_tuning
);
1501 tuning
= cs47l85_hp_tuning
;
1502 n_tunings
= ARRAY_SIZE(cs47l85_hp_tuning
);
1506 tuning
= cs47l90_hp_tuning
;
1507 n_tunings
= ARRAY_SIZE(cs47l90_hp_tuning
);
1511 tuning
= cs47l92_hp_tuning
;
1512 n_tunings
= ARRAY_SIZE(cs47l92_hp_tuning
);
1518 if (reading
<= info
->hpdet_short_x100
) {
1519 /* Headphones are always off here so just mark them */
1520 dev_warn(info
->dev
, "Possible HP short, disabling\n");
1524 if (reading
== MADERA_HP_Z_OPEN
) {
1525 if (info
->hp_tuning_level
== 1)
1528 dev_warn(info
->dev
, "No jack: Setting tuning level 1\n");
1530 info
->hp_tuning_level
= 1;
1532 ret
= regmap_multi_reg_write(madera
->regmap
,
1534 tuning
[1].patch_len
);
1539 * Check for tuning, we don't need to compare against the last
1540 * tuning entry because we always select that if reading is not
1541 * in range of the lower tunings
1543 for (i
= 0; i
< n_tunings
- 1; ++i
) {
1544 if (reading
<= tuning
[i
].max_hohm
)
1548 if (info
->hp_tuning_level
!= i
) {
1549 dev_warn(info
->dev
, "New tuning level %d\n", i
);
1551 info
->hp_tuning_level
= i
;
1553 ret
= regmap_multi_reg_write(madera
->regmap
,
1555 tuning
[i
].patch_len
);
1558 "Failed to apply HP tuning %d\n", ret
);
1566 void madera_set_headphone_imp(struct madera_extcon
*info
, int ohms_x100
)
1568 struct madera
*madera
= info
->madera
;
1569 struct madera_hpdet_notify_data data
;
1571 madera
->hp_impedance_x100
[0] = ohms_x100
;
1573 data
.impedance_x100
= ohms_x100
;
1574 madera_call_notifiers(madera
, MADERA_NOTIFY_HPDET
, &data
);
1576 madera_tune_headphone(info
, ohms_x100
);
1578 EXPORT_SYMBOL_GPL(madera_set_headphone_imp
);
1580 static void madera_hpdet_start_micd(struct madera_extcon
*info
)
1582 struct madera
*madera
= info
->madera
;
1584 regmap_update_bits(madera
->regmap
, MADERA_IRQ1_MASK_6
,
1585 MADERA_IM_MICDET1_EINT1_MASK
,
1586 MADERA_IM_MICDET1_EINT1
);
1587 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_0
,
1588 MADERA_MICD1_ADC_MODE_MASK
,
1589 MADERA_MICD1_ADC_MODE_MASK
);
1590 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1591 MADERA_MICD_BIAS_STARTTIME_MASK
|
1592 MADERA_MICD_RATE_MASK
|
1593 MADERA_MICD_DBTIME_MASK
|
1594 MADERA_MICD_ENA
, MADERA_MICD_ENA
);
1597 static void madera_hpdet_stop_micd(struct madera_extcon
*info
)
1599 struct madera
*madera
= info
->madera
;
1600 unsigned int start_time
= 1, dbtime
= 1, rate
= 1;
1602 if (info
->pdata
->micd_bias_start_time
)
1603 start_time
= info
->pdata
->micd_bias_start_time
;
1605 if (info
->pdata
->micd_rate
)
1606 rate
= info
->pdata
->micd_rate
;
1608 if (info
->pdata
->micd_dbtime
)
1609 dbtime
= info
->pdata
->micd_dbtime
;
1611 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1612 MADERA_MICD_BIAS_STARTTIME_MASK
|
1613 MADERA_MICD_RATE_MASK
|
1614 MADERA_MICD_DBTIME_MASK
|
1616 start_time
<< MADERA_MICD_BIAS_STARTTIME_SHIFT
|
1617 rate
<< MADERA_MICD_RATE_SHIFT
|
1618 dbtime
<< MADERA_MICD_DBTIME_SHIFT
);
1620 usleep_range(100, 400);
1622 /* Clear any spurious IRQs that have happened */
1623 regmap_write(madera
->regmap
, MADERA_IRQ1_STATUS_6
,
1624 MADERA_MICDET1_EINT1
);
1625 regmap_update_bits(madera
->regmap
, MADERA_IRQ1_MASK_6
,
1626 MADERA_IM_MICDET1_EINT1_MASK
, 0);
1629 int madera_hpdet_start(struct madera_extcon
*info
)
1631 struct madera
*madera
= info
->madera
;
1633 unsigned int hpd_sense
, hpd_clamp
, val
, hpd_gnd
;
1635 dev_warn(info
->dev
, "Starting HPDET\n");
1637 /* If we specified to assume a fixed impedance skip HPDET */
1638 if (info
->pdata
->fixed_hpdet_imp_x100
) {
1639 madera_set_headphone_imp(info
,
1640 info
->pdata
->fixed_hpdet_imp_x100
);
1645 /* Make sure we keep the device enabled during the measurement */
1646 pm_runtime_get_sync(info
->dev
);
1648 switch (madera
->type
) {
1652 madera_extcon_hp_clamp(info
, false);
1653 ret
= regmap_update_bits(madera
->regmap
,
1654 MADERA_ACCESSORY_DETECT_MODE_1
,
1655 MADERA_ACCDET_MODE_MASK
,
1659 "Failed to set HPDET mode (%d): %d\n",
1666 if (info
->state
->mode
== MADERA_ACCDET_MODE_HPL
) {
1667 hpd_clamp
= info
->pdata
->hpd_pins
[0];
1668 hpd_sense
= info
->pdata
->hpd_pins
[1];
1670 hpd_clamp
= info
->pdata
->hpd_pins
[2];
1671 hpd_sense
= info
->pdata
->hpd_pins
[3];
1674 hpd_gnd
= info
->micd_modes
[info
->micd_mode
].gnd
;
1676 val
= (hpd_sense
<< MADERA_HPD_SENSE_SEL_SHIFT
) |
1677 (hpd_clamp
<< MADERA_HPD_OUT_SEL_SHIFT
) |
1678 (hpd_sense
<< MADERA_HPD_FRC_SEL_SHIFT
) |
1679 (hpd_gnd
<< MADERA_HPD_GND_SEL_SHIFT
);
1681 ret
= regmap_update_bits(madera
->regmap
,
1682 MADERA_MIC_DETECT_1_CONTROL_0
,
1683 MADERA_MICD1_GND_MASK
,
1684 hpd_gnd
<< MADERA_MICD1_GND_SHIFT
);
1686 dev_err(madera
->dev
, "Failed to set MICD_GND: %d\n",
1691 ret
= regmap_update_bits(madera
->regmap
,
1692 MADERA_HEADPHONE_DETECT_0
,
1693 MADERA_HPD_GND_SEL_MASK
|
1694 MADERA_HPD_SENSE_SEL_MASK
|
1695 MADERA_HPD_FRC_SEL_MASK
|
1696 MADERA_HPD_OUT_SEL_MASK
,
1700 "Failed to set HPDET sense: %d\n", ret
);
1703 madera_extcon_hp_clamp(info
, false);
1704 madera_hpdet_start_micd(info
);
1708 ret
= regmap_update_bits(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
,
1709 MADERA_HP_POLL
, MADERA_HP_POLL
);
1711 dev_err(info
->dev
, "Can't start HPDET measurement: %d\n", ret
);
1718 madera_extcon_hp_clamp(info
, true);
1720 pm_runtime_put_autosuspend(info
->dev
);
1725 EXPORT_SYMBOL_GPL(madera_hpdet_start
);
1727 void madera_hpdet_restart(struct madera_extcon
*info
)
1729 struct madera
*madera
= info
->madera
;
1731 /* Reset back to starting range */
1732 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1733 MADERA_MICD_ENA_MASK
, 0);
1735 regmap_update_bits(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
,
1736 MADERA_HP_IMPEDANCE_RANGE_MASK
| MADERA_HP_POLL
,
1737 info
->hpdet_init_range
<<
1738 MADERA_HP_IMPEDANCE_RANGE_SHIFT
);
1740 switch (madera
->type
) {
1746 regmap_update_bits(madera
->regmap
,
1747 MADERA_MIC_DETECT_1_CONTROL_1
,
1748 MADERA_MICD_ENA_MASK
, MADERA_MICD_ENA
);
1752 regmap_update_bits(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
,
1753 MADERA_HP_POLL
, MADERA_HP_POLL
);
1755 EXPORT_SYMBOL_GPL(madera_hpdet_restart
);
1757 static int madera_hpdet_wait(struct madera_extcon
*info
)
1759 struct madera
*madera
= info
->madera
;
1763 for (i
= 0; i
< MADERA_HPDONE_PROBE_COUNT
; i
++) {
1764 ret
= regmap_read(madera
->regmap
, MADERA_HEADPHONE_DETECT_2
,
1767 dev_err(madera
->dev
, "Failed to read HPDET state: %d\n",
1772 if (val
& MADERA_HP_DONE_MASK
)
1775 msleep(MADERA_HPDONE_PROBE_INTERVAL_MS
);
1778 dev_err(madera
->dev
, "HPDET did not appear to complete\n");
1783 void madera_hpdet_stop(struct madera_extcon
*info
)
1785 struct madera
*madera
= info
->madera
;
1787 dev_warn(info
->dev
, "Stopping HPDET\n");
1790 * If the jack was removed we abort this state.
1791 * Ensure that the detect hardware has returned to idle
1793 madera_hpdet_wait(info
);
1795 /* Reset back to starting range */
1796 madera_hpdet_stop_micd(info
);
1798 regmap_update_bits(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
,
1799 MADERA_HP_IMPEDANCE_RANGE_MASK
| MADERA_HP_POLL
,
1800 info
->hpdet_init_range
<<
1801 MADERA_HP_IMPEDANCE_RANGE_SHIFT
);
1803 switch (madera
->type
) {
1807 /* Reset to default mode */
1808 regmap_update_bits(madera
->regmap
,
1809 MADERA_ACCESSORY_DETECT_MODE_1
,
1810 MADERA_ACCDET_MODE_MASK
, 0);
1816 madera_extcon_hp_clamp(info
, true);
1818 pm_runtime_mark_last_busy(info
->dev
);
1819 pm_runtime_put_autosuspend(info
->dev
);
1821 EXPORT_SYMBOL_GPL(madera_hpdet_stop
);
1823 int madera_hpdet_reading(struct madera_extcon
*info
, int val
)
1825 dev_warn(info
->dev
, "Reading HPDET %d\n", val
);
1830 madera_set_headphone_imp(info
, val
);
1832 /* Report high impedence cables as line outputs */
1833 if(!info
->have_mic
&& val
>= 500000)
1834 madera_extcon_report(info
, EXTCON_JACK_LINE_OUT
, true);
1836 madera_extcon_report(info
, EXTCON_JACK_HEADPHONE
, true);
1839 madera_jds_set_state(info
, &madera_micd_button
);
1841 madera_jds_set_state(info
, NULL
);
1845 EXPORT_SYMBOL_GPL(madera_hpdet_reading
);
1847 int madera_micd_start(struct madera_extcon
*info
)
1849 struct madera
*madera
= info
->madera
;
1851 unsigned int micd_mode
;
1853 /* Microphone detection can't use idle mode */
1854 pm_runtime_get_sync(info
->dev
);
1856 dev_warn(info
->dev
, "Disabling MICD_OVD\n");
1857 regmap_update_bits(madera
->regmap
,
1858 MADERA_MICD_CLAMP_CONTROL
,
1859 MADERA_MICD_CLAMP_OVD_MASK
, 0);
1861 ret
= regulator_enable(info
->micvdd
);
1863 dev_err(info
->dev
, "Failed to enable MICVDD: %d\n", ret
);
1865 switch (madera
->type
) {
1869 regmap_update_bits(madera
->regmap
,
1870 MADERA_ACCESSORY_DETECT_MODE_1
,
1871 MADERA_ACCDET_MODE_MASK
, info
->state
->mode
);
1874 if (info
->state
->mode
== MADERA_ACCDET_MODE_ADC
)
1875 micd_mode
= MADERA_MICD1_ADC_MODE_MASK
;
1879 regmap_update_bits(madera
->regmap
,
1880 MADERA_MIC_DETECT_1_CONTROL_0
,
1881 MADERA_MICD1_ADC_MODE_MASK
, micd_mode
);
1885 madera_extcon_enable_micbias(info
);
1887 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1888 MADERA_MICD_ENA
, MADERA_MICD_ENA
);
1892 EXPORT_SYMBOL_GPL(madera_micd_start
);
1894 void madera_micd_stop(struct madera_extcon
*info
)
1896 struct madera
*madera
= info
->madera
;
1898 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1899 MADERA_MICD_ENA
, 0);
1901 madera_extcon_disable_micbias(info
);
1903 switch (madera
->type
) {
1907 /* Reset to default mode */
1908 regmap_update_bits(madera
->regmap
,
1909 MADERA_ACCESSORY_DETECT_MODE_1
,
1910 MADERA_ACCDET_MODE_MASK
, 0);
1916 regulator_disable(info
->micvdd
);
1918 dev_warn(info
->dev
, "Enabling MICD_OVD\n");
1919 regmap_update_bits(madera
->regmap
, MADERA_MICD_CLAMP_CONTROL
,
1920 MADERA_MICD_CLAMP_OVD_MASK
, MADERA_MICD_CLAMP_OVD
);
1922 pm_runtime_mark_last_busy(info
->dev
);
1923 pm_runtime_put_autosuspend(info
->dev
);
1925 EXPORT_SYMBOL_GPL(madera_micd_stop
);
1927 static void madera_micd_restart(struct madera_extcon
*info
)
1929 struct madera
*madera
= info
->madera
;
1931 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1932 MADERA_MICD_ENA
, 0);
1933 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_1
,
1934 MADERA_MICD_ENA
, MADERA_MICD_ENA
);
1937 static int madera_micd_button_debounce(struct madera_extcon
*info
, int val
)
1939 int debounce_lim
= info
->pdata
->micd_manual_debounce
;
1942 if (info
->micd_debounce
!= val
)
1943 info
->micd_count
= 0;
1945 info
->micd_debounce
= val
;
1948 if (info
->micd_count
== debounce_lim
) {
1949 info
->micd_count
= 0;
1950 if (val
== info
->micd_res_old
)
1953 info
->micd_res_old
= val
;
1955 dev_warn(info
->dev
, "Software debounce: %d,%x\n",
1956 info
->micd_count
, val
);
1957 madera_micd_restart(info
);
1965 static int madera_micd_button_process(struct madera_extcon
*info
, int val
)
1969 if (val
< MADERA_MICROPHONE_MIN_OHM
) {
1970 dev_warn(info
->dev
, "Mic button detected\n");
1972 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
1973 input_report_key(info
->input
,
1974 info
->micd_ranges
[i
].key
, 0);
1976 for (i
= 0; i
< info
->num_micd_ranges
; i
++) {
1977 if (val
<= info
->micd_ranges
[i
].max
) {
1978 key
= info
->micd_ranges
[i
].key
;
1979 dev_warn(info
->dev
, "Key %d down\n", key
);
1980 input_report_key(info
->input
, key
, 1);
1981 input_sync(info
->input
);
1986 if (i
== info
->num_micd_ranges
)
1988 "Button level %u out of range\n", val
);
1990 dev_warn(info
->dev
, "Mic button released\n");
1992 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
1993 input_report_key(info
->input
,
1994 info
->micd_ranges
[i
].key
, 0);
1995 input_sync(info
->input
);
2001 int madera_micd_button_reading(struct madera_extcon
*info
, int val
)
2009 ohms
= madera_hohm_to_ohm((unsigned int)val
);
2011 ret
= madera_micd_button_debounce(info
, ohms
);
2015 return madera_micd_button_process(info
, ohms
);
2017 EXPORT_SYMBOL_GPL(madera_micd_button_reading
);
2019 int madera_micd_mic_start(struct madera_extcon
*info
)
2023 info
->detecting
= true;
2025 ret
= regulator_allow_bypass(info
->micvdd
, false);
2027 dev_err(info
->dev
, "Failed to regulate MICVDD: %d\n", ret
);
2029 return madera_micd_start(info
);
2031 EXPORT_SYMBOL_GPL(madera_micd_mic_start
);
2033 void madera_micd_mic_stop(struct madera_extcon
*info
)
2037 madera_micd_stop(info
);
2039 ret
= regulator_allow_bypass(info
->micvdd
, true);
2041 dev_err(info
->dev
, "Failed to bypass MICVDD: %d\n", ret
);
2043 info
->detecting
= false;
2045 EXPORT_SYMBOL_GPL(madera_micd_mic_stop
);
2047 int madera_micd_mic_reading(struct madera_extcon
*info
, int val
)
2054 ohms
= madera_hohm_to_ohm((unsigned int)val
);
2056 /* Due to jack detect this should never happen */
2057 if (ohms
> MADERA_MICROPHONE_MAX_OHM
) {
2058 dev_warn(info
->dev
, "Detected open circuit\n");
2059 info
->have_mic
= info
->pdata
->micd_open_circuit_declare
;
2063 /* If we got a high impedence we should have a headset, report it. */
2064 if (ohms
>= MADERA_MICROPHONE_MIN_OHM
) {
2065 dev_warn(info
->dev
, "Detected headset\n");
2066 info
->have_mic
= true;
2071 * If we detected a lower impedence during initial startup
2072 * then we probably have the wrong polarity, flip it. Don't
2073 * do this for the lowest impedences to speed up detection of
2074 * plain headphones. If both polarities report a low
2075 * impedence then give up and report headphones.
2077 if (ohms
> info
->micd_ranges
[0].max
&&
2078 info
->num_micd_modes
> 1) {
2079 if (info
->jack_flips
>= info
->num_micd_modes
* 10) {
2080 dev_warn(info
->dev
, "Detected HP/line\n");
2083 madera_extcon_next_mode(info
);
2092 * If we're still detecting and we detect a short then we've
2095 dev_warn(info
->dev
, "Headphone detected\n");
2098 pm_runtime_mark_last_busy(info
->dev
);
2100 if (info
->pdata
->hpdet_channel
)
2101 madera_jds_set_state(info
, &madera_hpdet_right
);
2103 madera_jds_set_state(info
, &madera_hpdet_left
);
2105 madera_extcon_report(info
, EXTCON_JACK_MICROPHONE
, info
->have_mic
);
2107 madera_extcon_notify_micd(info
, info
->have_mic
, ohms
);
2111 EXPORT_SYMBOL_GPL(madera_micd_mic_reading
);
2113 int madera_micd_mic_timeout_ms(struct madera_extcon
*info
)
2115 if (info
->pdata
->micd_timeout_ms
)
2116 return info
->pdata
->micd_timeout_ms
;
2118 return MADERA_DEFAULT_MICD_TIMEOUT_MS
;
2120 EXPORT_SYMBOL_GPL(madera_micd_mic_timeout_ms
);
2122 void madera_micd_mic_timeout(struct madera_extcon
*info
)
2126 dev_warn(info
->dev
, "MICD timed out, reporting HP\n");
2128 if (info
->pdata
->hpdet_channel
)
2129 ret
= madera_jds_set_state(info
, &madera_hpdet_right
);
2131 ret
= madera_jds_set_state(info
, &madera_hpdet_left
);
2134 madera_extcon_report(info
, EXTCON_JACK_MICROPHONE
, false);
2136 EXPORT_SYMBOL_GPL(madera_micd_mic_timeout
);
2138 static int madera_jack_present(struct madera_extcon
*info
,
2139 unsigned int *jack_val
)
2141 struct madera
*madera
= info
->madera
;
2142 unsigned int present
, val
;
2145 ret
= regmap_read(madera
->regmap
, MADERA_IRQ1_RAW_STATUS_7
, &val
);
2147 dev_err(info
->dev
, "Failed to read jackdet status: %d\n", ret
);
2151 dev_warn(info
->dev
, "IRQ1_RAW_STATUS_7=0x%x\n", val
);
2153 if (info
->pdata
->jd_use_jd2
) {
2154 val
&= MADERA_MICD_CLAMP_RISE_STS1
;
2156 } else if (info
->pdata
->jd_invert
) {
2157 val
&= MADERA_JD1_FALL_STS1_MASK
;
2158 present
= MADERA_JD1_FALL_STS1
;
2160 val
&= MADERA_JD1_RISE_STS1_MASK
;
2161 present
= MADERA_JD1_RISE_STS1
;
2164 dev_warn(info
->dev
, "jackdet val=0x%x present=0x%x\n", val
, present
);
2175 static irqreturn_t
madera_hpdet_handler(int irq
, void *data
)
2177 struct madera_extcon
*info
= data
;
2180 dev_warn(info
->dev
, "HPDET handler\n");
2182 madera_jds_cancel_timeout(info
);
2184 mutex_lock(&info
->lock
);
2186 switch (madera_jds_get_mode(info
)) {
2187 case MADERA_ACCDET_MODE_HPL
:
2188 case MADERA_ACCDET_MODE_HPR
:
2189 case MADERA_ACCDET_MODE_HPM
:
2190 /* Fall through to spurious if no jack present */
2191 if (madera_jack_present(info
, NULL
) > 0)
2194 dev_warn(info
->dev
, "Spurious HPDET IRQ\n");
2195 madera_jds_start_timeout(info
);
2196 mutex_unlock(&info
->lock
);
2200 ret
= madera_hpdet_read(info
);
2204 madera_jds_reading(info
, ret
);
2207 madera_jds_start_timeout(info
);
2209 pm_runtime_mark_last_busy(info
->dev
);
2211 mutex_unlock(&info
->lock
);
2216 static void madera_micd_handler(struct work_struct
*work
)
2218 struct madera_extcon
*info
= container_of(work
,
2219 struct madera_extcon
,
2220 micd_detect_work
.work
);
2221 enum madera_accdet_mode mode
;
2224 madera_jds_cancel_timeout(info
);
2226 mutex_lock(&info
->lock
);
2229 * Must check that we are in a micd state before accessing
2230 * any codec registers
2232 dev_warn(info
->dev
, "madera_micd_handler mode is %d \n", mode
);
2233 mode
= madera_jds_get_mode(info
);
2235 case MADERA_ACCDET_MODE_MIC
:
2236 case MADERA_ACCDET_MODE_ADC
:
2242 if (madera_jack_present(info
, NULL
) <= 0)
2246 case MADERA_ACCDET_MODE_MIC
:
2247 ret
= madera_micd_read(info
);
2249 case MADERA_ACCDET_MODE_ADC
:
2250 ret
= madera_micd_adc_read(info
);
2252 default: /* we can't get here but compiler still warns */
2261 dev_warn(info
->dev
, "Mic impedance %d ohms\n", ret
);
2262 ret
= madera_ohm_to_hohm((unsigned int)ret
);
2265 madera_jds_reading(info
, ret
);
2268 madera_jds_start_timeout(info
);
2270 pm_runtime_mark_last_busy(info
->dev
);
2272 mutex_unlock(&info
->lock
);
2277 dev_warn(info
->dev
, "Spurious MICDET IRQ\n");
2278 madera_jds_start_timeout(info
);
2279 mutex_unlock(&info
->lock
);
2282 static irqreturn_t
madera_micdet(int irq
, void *data
)
2284 struct madera_extcon
*info
= data
;
2285 int debounce
= info
->pdata
->micd_detect_debounce_ms
;
2287 dev_warn(info
->dev
, "micdet IRQ debounce is %d ",debounce
);
2289 cancel_delayed_work_sync(&info
->micd_detect_work
);
2291 mutex_lock(&info
->lock
);
2293 if (!info
->detecting
)
2296 mutex_unlock(&info
->lock
);
2299 * Defer to the workqueue to ensure serialization
2300 * and prevent race conditions if an IRQ occurs while
2301 * running the delayed work
2303 dev_warn(info
->dev
, "micdet IRQ debounce msecs_to_jiffies is %d ",msecs_to_jiffies(debounce
));
2304 schedule_delayed_work(&info
->micd_detect_work
,
2305 msecs_to_jiffies(debounce
));
2310 const struct madera_jd_state madera_hpdet_left
= {
2311 .mode
= MADERA_ACCDET_MODE_HPL
,
2312 .start
= madera_hpdet_start
,
2313 .reading
= madera_hpdet_reading
,
2314 .stop
= madera_hpdet_stop
,
2316 EXPORT_SYMBOL_GPL(madera_hpdet_left
);
2318 const struct madera_jd_state madera_hpdet_right
= {
2319 .mode
= MADERA_ACCDET_MODE_HPR
,
2320 .start
= madera_hpdet_start
,
2321 .reading
= madera_hpdet_reading
,
2322 .stop
= madera_hpdet_stop
,
2324 EXPORT_SYMBOL_GPL(madera_hpdet_right
);
2326 const struct madera_jd_state madera_micd_button
= {
2327 .mode
= MADERA_ACCDET_MODE_MIC
,
2328 .start
= madera_micd_start
,
2329 .reading
= madera_micd_button_reading
,
2330 .stop
= madera_micd_stop
,
2332 EXPORT_SYMBOL_GPL(madera_micd_button
);
2334 const struct madera_jd_state madera_micd_adc_mic
= {
2335 .mode
= MADERA_ACCDET_MODE_ADC
,
2336 .start
= madera_micd_mic_start
,
2337 .restart
= madera_micd_restart
,
2338 .reading
= madera_micd_mic_reading
,
2339 .stop
= madera_micd_mic_stop
,
2341 .timeout_ms
= madera_micd_mic_timeout_ms
,
2342 .timeout
= madera_micd_mic_timeout
,
2344 EXPORT_SYMBOL_GPL(madera_micd_adc_mic
);
2346 const struct madera_jd_state madera_micd_microphone
= {
2347 .mode
= MADERA_ACCDET_MODE_MIC
,
2348 .start
= madera_micd_mic_start
,
2349 .reading
= madera_micd_mic_reading
,
2350 .stop
= madera_micd_mic_stop
,
2352 .timeout_ms
= madera_micd_mic_timeout_ms
,
2353 .timeout
= madera_micd_mic_timeout
,
2355 EXPORT_SYMBOL_GPL(madera_micd_microphone
);
2357 static irqreturn_t
madera_jackdet(int irq
, void *data
)
2359 struct madera_extcon
*info
= data
;
2360 struct madera
*madera
= info
->madera
;
2361 unsigned int val
, mask
;
2362 bool cancelled_state
;
2365 dev_warn(info
->dev
, "jackdet IRQ");
2367 cancelled_state
= madera_jds_cancel_timeout(info
);
2369 pm_runtime_get_sync(info
->dev
);
2371 mutex_lock(&info
->lock
);
2374 present
= madera_jack_present(info
, &val
);
2376 mutex_unlock(&info
->lock
);
2377 pm_runtime_put_autosuspend(info
->dev
);
2381 if (val
== info
->last_jackdet
) {
2382 dev_warn(info
->dev
, "Suppressing duplicate JACKDET\n");
2383 if (cancelled_state
)
2384 madera_jds_start_timeout(info
);
2388 info
->last_jackdet
= val
;
2390 mask
= MADERA_MICD_CLAMP_DB
| MADERA_JD1_DB
;
2392 if (info
->pdata
->jd_use_jd2
)
2393 mask
|= MADERA_JD2_DB
;
2396 dev_warn(info
->dev
, "Detected jack\n");
2398 madera_extcon_report(info
, EXTCON_MECHANICAL
, true);
2400 info
->have_mic
= false;
2401 info
->jack_flips
= 0;
2403 if (info
->pdata
->custom_jd
)
2404 madera_jds_set_state(info
, info
->pdata
->custom_jd
);
2405 else if (info
->pdata
->micd_software_compare
)
2406 madera_jds_set_state(info
, &madera_micd_adc_mic
);
2408 madera_jds_set_state(info
, &madera_micd_microphone
);
2410 madera_jds_start_timeout(info
);
2412 regmap_update_bits(madera
->regmap
, MADERA_INTERRUPT_DEBOUNCE_7
,
2415 dev_warn(info
->dev
, "Detected jack removal\n");
2417 info
->have_mic
= false;
2418 info
->micd_res_old
= 0;
2419 info
->micd_debounce
= 0;
2420 info
->micd_count
= 0;
2421 madera_jds_set_state(info
, NULL
);
2423 for (i
= 0; i
< info
->num_micd_ranges
; i
++)
2424 input_report_key(info
->input
,
2425 info
->micd_ranges
[i
].key
, 0);
2426 input_sync(info
->input
);
2428 for (i
= 0; i
< ARRAY_SIZE(madera_cable
) - 1; i
++)
2429 madera_extcon_report(info
, madera_cable
[i
], false);
2431 regmap_update_bits(madera
->regmap
, MADERA_INTERRUPT_DEBOUNCE_7
,
2434 madera_set_headphone_imp(info
, MADERA_HP_Z_OPEN
);
2436 madera_extcon_notify_micd(info
, false, 0);
2440 mutex_unlock(&info
->lock
);
2442 pm_runtime_mark_last_busy(info
->dev
);
2443 pm_runtime_put_autosuspend(info
->dev
);
2448 /* Map a level onto a slot in the register bank */
2449 static void madera_micd_set_level(struct madera
*madera
, int index
,
2455 reg
= MADERA_MIC_DETECT_1_LEVEL_4
- (index
/ 2);
2464 /* Program the level itself */
2465 regmap_update_bits(madera
->regmap
, reg
, mask
, level
);
2468 static void madera_extcon_of_get_micd_ranges(struct madera_extcon
*info
,
2469 struct fwnode_handle
*node
,
2470 struct madera_accdet_pdata
*pdata
)
2472 struct madera_micd_range
*micd_ranges
;
2474 int nvalues
, nranges
, i
, j
;
2477 nvalues
= fwnode_property_read_u32_array(node
, "cirrus,micd-ranges",
2482 values
= kmalloc_array(nvalues
, sizeof(u32
), GFP_KERNEL
);
2486 ret
= fwnode_property_read_u32_array(node
, "cirrus,micd-ranges",
2491 nranges
= nvalues
/ 2;
2492 micd_ranges
= devm_kcalloc(info
->dev
,
2494 sizeof(struct madera_micd_range
),
2497 for (i
= 0, j
= 0; i
< nranges
; ++i
) {
2498 micd_ranges
[i
].max
= values
[j
++];
2499 micd_ranges
[i
].key
= values
[j
++];
2502 pdata
->micd_ranges
= micd_ranges
;
2503 pdata
->num_micd_ranges
= nranges
;
2509 static void madera_extcon_get_micd_configs(struct madera_extcon
*info
,
2510 struct fwnode_handle
*node
,
2511 struct madera_accdet_pdata
*pdata
)
2513 struct madera_micd_config
*micd_configs
;
2515 int nvalues
, nconfigs
, i
, j
;
2518 nvalues
= fwnode_property_read_u32_array(node
,
2519 "cirrus,micd-configs",
2521 if (nvalues
== -EINVAL
) {
2522 return; /* not found */
2523 } else if ((nvalues
< 0) || (nvalues
% 5)) {
2524 dev_warn(info
->dev
, "cirrus,micd-configs is malformed\n");
2528 values
= kmalloc_array(nvalues
, sizeof(u32
), GFP_KERNEL
);
2532 ret
= fwnode_property_read_u32_array(node
,
2533 "cirrus,micd-configs",
2538 nconfigs
= nvalues
/ 5;
2539 micd_configs
= devm_kcalloc(info
->dev
,
2541 sizeof(struct madera_micd_config
),
2546 for (i
= 0, j
= 0; i
< nconfigs
; ++i
) {
2547 micd_configs
[i
].src
= values
[j
++];
2548 micd_configs
[i
].gnd
= values
[j
++];
2549 micd_configs
[i
].bias
= values
[j
++];
2550 micd_configs
[i
].gpio
= values
[j
++];
2551 micd_configs
[i
].hp_gnd
= values
[j
++];
2554 info
->micd_modes
= micd_configs
;
2555 info
->num_micd_modes
= nconfigs
;
2561 static void madera_extcon_get_hpd_pins(struct madera_extcon
*info
,
2562 struct fwnode_handle
*node
,
2563 struct madera_accdet_pdata
*pdata
)
2567 BUILD_BUG_ON(ARRAY_SIZE(pdata
->hpd_pins
) !=
2568 ARRAY_SIZE(madera_default_hpd_pins
));
2570 memcpy(pdata
->hpd_pins
, madera_default_hpd_pins
,
2571 sizeof(pdata
->hpd_pins
));
2573 ret
= fwnode_property_read_u32_array(node
,
2576 ARRAY_SIZE(pdata
->hpd_pins
));
2580 "Malformed cirrus,hpd-pins: %d\n", ret
);
2584 /* supply defaults where requested */
2585 for (i
= 0; i
< ARRAY_SIZE(pdata
->hpd_pins
); ++i
)
2586 if (pdata
->hpd_pins
[i
] > 0xFFFF)
2587 pdata
->hpd_pins
[i
] = madera_default_hpd_pins
[i
];
2590 static void madera_extcon_process_accdet_node(struct madera_extcon
*info
,
2591 struct fwnode_handle
*node
)
2593 struct madera
*madera
= info
->madera
;
2594 struct madera_accdet_pdata
*pdata
;
2597 enum gpiod_flags gpio_status
;
2599 ret
= fwnode_property_read_u32(node
, "reg", &out_num
);
2602 "failed to read reg property (%d)\n",
2608 dev_warn(info
->dev
, "accdet node illegal reg %u\n", out_num
);
2612 dev_warn(info
->dev
, "processing accdet reg=%u\n", out_num
);
2614 for (i
= 0; i
< ARRAY_SIZE(madera
->pdata
.accdet
); i
++)
2615 if (!madera
->pdata
.accdet
[i
].enabled
)
2618 if (i
== ARRAY_SIZE(madera
->pdata
.accdet
)) {
2619 dev_warn(madera
->dev
, "Too many accdet nodes: %d\n", i
+ 1);
2623 pdata
= &madera
->pdata
.accdet
[i
];
2624 pdata
->enabled
= true; /* implied by presence of properties node */
2625 pdata
->output
= out_num
;
2627 fwnode_property_read_u32(node
, "cirrus,micd-detect-debounce-ms",
2628 &pdata
->micd_detect_debounce_ms
);
2630 fwnode_property_read_u32(node
, "cirrus,micd-manual-debounce",
2631 &pdata
->micd_manual_debounce
);
2633 fwnode_property_read_u32(node
, "cirrus,micd-bias-start-time",
2634 &pdata
->micd_bias_start_time
);
2636 fwnode_property_read_u32(node
, "cirrus,micd-rate",
2639 fwnode_property_read_u32(node
, "cirrus,micd-dbtime",
2640 &pdata
->micd_dbtime
);
2642 fwnode_property_read_u32(node
, "cirrus,micd-timeout-ms",
2643 &pdata
->micd_timeout_ms
);
2645 /* don't override any preset force_micbias enable */
2646 if (fwnode_property_present(node
, "cirrus,micd-force-micbias"))
2647 pdata
->micd_force_micbias
= true;
2649 pdata
->micd_software_compare
=
2650 fwnode_property_present(node
,
2651 "cirrus,micd-software-compare");
2653 pdata
->micd_open_circuit_declare
=
2654 fwnode_property_present(node
,
2655 "cirrus,micd-open-circuit-declare");
2657 pdata
->jd_use_jd2
= fwnode_property_present(node
,
2658 "cirrus,jd-use-jd2");
2660 pdata
->jd_invert
= fwnode_property_present(node
,
2661 "cirrus,jd-invert");
2663 fwnode_property_read_u32(node
, "cirrus,fixed-hpdet-imp",
2664 &pdata
->fixed_hpdet_imp_x100
);
2666 fwnode_property_read_u32(node
, "cirrus,hpdet-short-circuit-imp",
2667 &pdata
->hpdet_short_circuit_imp
);
2669 fwnode_property_read_u32(node
, "cirrus,hpdet-channel",
2670 &pdata
->hpdet_channel
);
2672 fwnode_property_read_u32(node
, "cirrus,jd-wake-time",
2673 &pdata
->jd_wake_time
);
2675 fwnode_property_read_u32(node
, "cirrus,micd-clamp-mode",
2676 &pdata
->micd_clamp_mode
);
2678 fwnode_property_read_u32(node
, "cirrus,hpdet-ext-res",
2679 &pdata
->hpdet_ext_res_x100
);
2681 madera_extcon_get_hpd_pins(info
, node
, pdata
);
2682 madera_extcon_get_micd_configs(info
, node
, pdata
);
2683 madera_extcon_of_get_micd_ranges(info
, node
, pdata
);
2685 if (info
->micd_modes
[0].gpio
)
2686 gpio_status
= GPIOD_OUT_HIGH
;
2688 gpio_status
= GPIOD_OUT_LOW
;
2690 info
->micd_pol_gpio
= devm_fwnode_get_gpiod_from_child(info
->dev
,
2695 if (IS_ERR(info
->micd_pol_gpio
)) {
2697 "Malformed cirrus,micd-pol-gpios ignored: %ld\n",
2698 PTR_ERR(info
->micd_pol_gpio
));
2699 info
->micd_pol_gpio
= NULL
;
2703 static int madera_extcon_get_device_pdata(struct madera_extcon
*info
)
2705 struct device_node
*parent
, *child
;
2706 struct madera
*madera
= info
->madera
;
2709 * a GPSW is not necessarily exclusive to a single accessory detect
2710 * channel so is not in the subnodes
2712 device_property_read_u32_array(info
->madera
->dev
, "cirrus,gpsw",
2713 info
->madera
->pdata
.gpsw
,
2714 ARRAY_SIZE(info
->madera
->pdata
.gpsw
));
2716 parent
= of_get_child_by_name(madera
->dev
->of_node
, "cirrus,accdet");
2718 dev_warn(madera
->dev
, "No DT nodes\n");
2722 for_each_child_of_node(parent
, child
)
2723 madera_extcon_process_accdet_node(info
, &child
->fwnode
);
2725 of_node_put(parent
);
2731 #define MADERA_EXTCON_PDATA_DUMP(x, f) \
2732 dev_warn(info->dev, "\t" #x ": " f "\n", pdata->x)
2734 static void madera_extcon_dump_config(struct madera_extcon
*info
)
2736 const struct madera_accdet_pdata
*pdata
;
2739 dev_warn(info
->dev
, "extcon pdata gpsw=[0x%x 0x%x]\n",
2740 info
->madera
->pdata
.gpsw
[0], info
->madera
->pdata
.gpsw
[1]);
2742 for (i
= 0; i
< ARRAY_SIZE(info
->madera
->pdata
.accdet
); ++i
) {
2743 pdata
= &info
->madera
->pdata
.accdet
[i
];
2745 dev_warn(info
->dev
, "extcon pdata OUT%u\n", pdata
->output
);
2746 MADERA_EXTCON_PDATA_DUMP(enabled
, "%u");
2747 MADERA_EXTCON_PDATA_DUMP(jd_wake_time
, "%d");
2748 MADERA_EXTCON_PDATA_DUMP(jd_use_jd2
, "%u");
2749 MADERA_EXTCON_PDATA_DUMP(jd_invert
, "%u");
2750 MADERA_EXTCON_PDATA_DUMP(fixed_hpdet_imp_x100
, "%d");
2751 MADERA_EXTCON_PDATA_DUMP(hpdet_ext_res_x100
, "%d");
2752 MADERA_EXTCON_PDATA_DUMP(hpdet_short_circuit_imp
, "%d");
2753 MADERA_EXTCON_PDATA_DUMP(hpdet_channel
, "%d");
2754 MADERA_EXTCON_PDATA_DUMP(micd_detect_debounce_ms
, "%d");
2755 MADERA_EXTCON_PDATA_DUMP(hpdet_short_circuit_imp
, "%d");
2756 MADERA_EXTCON_PDATA_DUMP(hpdet_channel
, "%d");
2757 MADERA_EXTCON_PDATA_DUMP(micd_detect_debounce_ms
, "%d");
2758 MADERA_EXTCON_PDATA_DUMP(micd_manual_debounce
, "%d");
2759 MADERA_EXTCON_PDATA_DUMP(micd_bias_start_time
, "%d");
2760 MADERA_EXTCON_PDATA_DUMP(micd_rate
, "%d");
2761 MADERA_EXTCON_PDATA_DUMP(micd_dbtime
, "%d");
2762 MADERA_EXTCON_PDATA_DUMP(micd_timeout_ms
, "%d");
2763 MADERA_EXTCON_PDATA_DUMP(micd_clamp_mode
, "%u");
2764 MADERA_EXTCON_PDATA_DUMP(micd_force_micbias
, "%u");
2765 MADERA_EXTCON_PDATA_DUMP(micd_open_circuit_declare
, "%u");
2766 MADERA_EXTCON_PDATA_DUMP(micd_software_compare
, "%u");
2768 if (info
->micd_pol_gpio
)
2769 dev_warn(info
->dev
, "micd_pol_gpio: %d\n",
2770 desc_to_gpio(info
->micd_pol_gpio
));
2772 dev_warn(info
->dev
, "micd_pol_gpio: unused\n");
2774 dev_warn(info
->dev
, "\tmicd_ranges {\n");
2775 for (j
= 0; j
< info
->num_micd_ranges
; ++j
)
2776 dev_warn(info
->dev
, "\t\tmax: %d key: %d\n",
2777 info
->micd_ranges
[j
].max
,
2778 info
->micd_ranges
[j
].key
);
2779 dev_warn(info
->dev
, "\t}\n");
2781 dev_warn(info
->dev
, "\tmicd_configs {\n");
2782 for (j
= 0; j
< info
->num_micd_modes
; ++j
)
2784 "\t\tsrc: 0x%x gnd: 0x%x bias: %u gpio: %u hp_gnd: %d\n",
2785 info
->micd_modes
[j
].src
,
2786 info
->micd_modes
[j
].gnd
,
2787 info
->micd_modes
[j
].bias
,
2788 info
->micd_modes
[j
].gpio
,
2789 info
->micd_modes
[j
].hp_gnd
);
2790 dev_warn(info
->dev
, "\t}\n");
2792 dev_warn(info
->dev
, "\thpd_pins: %u %u %u %u\n",
2793 pdata
->hpd_pins
[0], pdata
->hpd_pins
[1],
2794 pdata
->hpd_pins
[2], pdata
->hpd_pins
[3]);
2798 static inline void madera_extcon_dump_config(struct madera_extcon
*info
)
2803 /* See datasheet for a description of this calibration data */
2804 static int madera_extcon_read_calibration(struct madera_extcon
*info
)
2806 struct madera
*madera
= info
->madera
;
2807 struct madera_hpdet_trims
*trims
;
2809 unsigned int offset
, gradient
, interim_val
;
2810 unsigned int otp_hpdet_calib_1
, otp_hpdet_calib_2
;
2812 switch (madera
->type
) {
2814 otp_hpdet_calib_1
= CS47L35_OTP_HPDET_CAL_1
;
2815 otp_hpdet_calib_2
= CS47L35_OTP_HPDET_CAL_2
;
2819 otp_hpdet_calib_1
= CS47L85_OTP_HPDET_CAL_1
;
2820 otp_hpdet_calib_2
= CS47L85_OTP_HPDET_CAL_2
;
2823 otp_hpdet_calib_1
= MADERA_OTP_HPDET_CAL_1
;
2824 otp_hpdet_calib_2
= MADERA_OTP_HPDET_CAL_2
;
2828 ret
= regmap_read(madera
->regmap_32bit
, otp_hpdet_calib_1
, &offset
);
2831 "Failed to read HP CALIB OFFSET value: %d\n", ret
);
2835 ret
= regmap_read(madera
->regmap_32bit
, otp_hpdet_calib_2
, &gradient
);
2838 "Failed to read HP CALIB OFFSET value: %d\n", ret
);
2842 if (((offset
== 0) && (gradient
== 0)) ||
2843 ((offset
== 0xFFFFFFFF) && (gradient
== 0xFFFFFFFF))) {
2844 dev_warn(info
->dev
, "No HP trims\n");
2848 trims
= devm_kcalloc(info
->dev
, 4,
2849 sizeof(struct madera_hpdet_trims
),
2852 dev_err(info
->dev
, "Failed to alloc hpdet trims\n");
2856 interim_val
= (offset
& MADERA_OTP_HPDET_CALIB_OFFSET_00_MASK
) >>
2857 MADERA_OTP_HPDET_CALIB_OFFSET_00_SHIFT
;
2858 trims
[0].off_x4
= 128 - interim_val
;
2860 interim_val
= (gradient
& MADERA_OTP_HPDET_GRADIENT_0X_MASK
) >>
2861 MADERA_OTP_HPDET_GRADIENT_0X_SHIFT
;
2862 trims
[0].grad_x4
= 128 - interim_val
;
2864 interim_val
= (offset
& MADERA_OTP_HPDET_CALIB_OFFSET_01_MASK
) >>
2865 MADERA_OTP_HPDET_CALIB_OFFSET_01_SHIFT
;
2866 trims
[1].off_x4
= 128 - interim_val
;
2868 trims
[1].grad_x4
= trims
[0].grad_x4
;
2870 interim_val
= (offset
& MADERA_OTP_HPDET_CALIB_OFFSET_10_MASK
) >>
2871 MADERA_OTP_HPDET_CALIB_OFFSET_10_SHIFT
;
2872 trims
[2].off_x4
= 128 - interim_val
;
2874 interim_val
= (gradient
& MADERA_OTP_HPDET_GRADIENT_1X_MASK
) >>
2875 MADERA_OTP_HPDET_GRADIENT_1X_SHIFT
;
2876 trims
[2].grad_x4
= 128 - interim_val
;
2878 interim_val
= (offset
& MADERA_OTP_HPDET_CALIB_OFFSET_11_MASK
) >>
2879 MADERA_OTP_HPDET_CALIB_OFFSET_11_SHIFT
;
2880 trims
[3].off_x4
= 128 - interim_val
;
2882 trims
[3].grad_x4
= trims
[2].grad_x4
;
2884 info
->hpdet_trims
= trims
;
2887 "trims_x_4: %u,%u %u,%u %u,%u %u,%u\n",
2888 trims
[0].off_x4
, trims
[0].grad_x4
,
2889 trims
[1].off_x4
, trims
[1].grad_x4
,
2890 trims
[2].off_x4
, trims
[2].grad_x4
,
2891 trims
[3].off_x4
, trims
[3].grad_x4
);
2896 static void madera_extcon_set_micd_clamp_mode(struct madera_extcon
*info
)
2898 unsigned int clamp_ctrl_val
;
2901 * If the user has supplied a micd_clamp_mode, assume they know
2902 * what they are doing and just write it out
2904 if (info
->pdata
->micd_clamp_mode
) {
2905 clamp_ctrl_val
= info
->pdata
->micd_clamp_mode
;
2906 } else if (info
->pdata
->jd_use_jd2
) {
2907 if (info
->pdata
->jd_invert
)
2908 clamp_ctrl_val
= MADERA_MICD_CLAMP_MODE_JD1H_JD2H
;
2910 clamp_ctrl_val
= MADERA_MICD_CLAMP_MODE_JD1L_JD2L
;
2912 if (info
->pdata
->jd_invert
)
2913 clamp_ctrl_val
= MADERA_MICD_CLAMP_MODE_JD1H
;
2915 clamp_ctrl_val
= MADERA_MICD_CLAMP_MODE_JD1L
;
2918 regmap_update_bits(info
->madera
->regmap
,
2919 MADERA_MICD_CLAMP_CONTROL
,
2920 MADERA_MICD_CLAMP_MODE_MASK
,
2923 regmap_update_bits(info
->madera
->regmap
,
2924 MADERA_INTERRUPT_DEBOUNCE_7
,
2925 MADERA_MICD_CLAMP_DB
,
2926 MADERA_MICD_CLAMP_DB
);
2929 static int madera_extcon_add_micd_levels(struct madera_extcon
*info
)
2931 struct madera
*madera
= info
->madera
;
2935 BUILD_BUG_ON(ARRAY_SIZE(madera_micd_levels
) <
2936 MADERA_NUM_MICD_BUTTON_LEVELS
);
2938 /* Disable all buttons by default */
2939 regmap_update_bits(madera
->regmap
, MADERA_MIC_DETECT_1_CONTROL_2
,
2940 MADERA_MICD_LVL_SEL_MASK
, 0x81);
2942 /* Set up all the buttons the user specified */
2943 for (i
= 0; i
< info
->num_micd_ranges
; i
++) {
2944 for (j
= 0; j
< MADERA_NUM_MICD_BUTTON_LEVELS
; j
++)
2945 if (madera_micd_levels
[j
] >= info
->micd_ranges
[i
].max
)
2948 if (j
== MADERA_NUM_MICD_BUTTON_LEVELS
) {
2949 dev_err(info
->dev
, "Unsupported MICD level %d\n",
2950 info
->micd_ranges
[i
].max
);
2955 dev_warn(info
->dev
, "%d ohms for MICD threshold %d\n",
2956 madera_micd_levels
[j
], i
);
2958 madera_micd_set_level(madera
, i
, j
);
2959 if (info
->micd_ranges
[i
].key
> 0)
2960 input_set_capability(info
->input
, EV_KEY
,
2961 info
->micd_ranges
[i
].key
);
2963 /* Enable reporting of that range */
2964 regmap_update_bits(madera
->regmap
,
2965 MADERA_MIC_DETECT_1_CONTROL_2
,
2969 /* Set all the remaining keys to a maximum */
2970 for (; i
< MADERA_MAX_MICD_RANGE
; i
++)
2971 madera_micd_set_level(madera
, i
, 0x3f);
2977 static int madera_extcon_init_micd_ranges(struct madera_extcon
*info
)
2979 const struct madera_accdet_pdata
*pdata
= info
->pdata
;
2980 struct madera_micd_range
*ranges
;
2983 if (pdata
->num_micd_ranges
== 0) {
2984 info
->micd_ranges
= madera_micd_default_ranges
;
2985 info
->num_micd_ranges
=
2986 ARRAY_SIZE(madera_micd_default_ranges
);
2990 if (pdata
->num_micd_ranges
> MADERA_MAX_MICD_RANGE
) {
2991 dev_err(info
->dev
, "Too many MICD ranges: %d\n",
2992 pdata
->num_micd_ranges
);
2996 ranges
= devm_kmalloc_array(info
->dev
,
2997 pdata
->num_micd_ranges
,
2998 sizeof(struct madera_micd_range
),
3001 dev_err(info
->dev
, "Failed to kalloc micd ranges\n");
3005 memcpy(ranges
, pdata
->micd_ranges
,
3006 sizeof(struct madera_micd_range
) * pdata
->num_micd_ranges
);
3007 info
->micd_ranges
= ranges
;
3008 info
->num_micd_ranges
= pdata
->num_micd_ranges
;
3010 for (i
= 0; i
< info
->num_micd_ranges
- 1; i
++) {
3011 if (info
->micd_ranges
[i
].max
> info
->micd_ranges
[i
+ 1].max
) {
3012 dev_err(info
->dev
, "MICD ranges must be sorted\n");
3020 devm_kfree(info
->dev
, ranges
);
3025 static void madera_extcon_xlate_pdata(struct madera_accdet_pdata
*pdata
)
3029 BUILD_BUG_ON(ARRAY_SIZE(pdata
->hpd_pins
) !=
3030 ARRAY_SIZE(madera_default_hpd_pins
));
3032 /* translate from pdata format where 0=default and >0xFFFF means 0 */
3033 for (i
= 0; i
< ARRAY_SIZE(pdata
->hpd_pins
); ++i
) {
3034 if (pdata
->hpd_pins
[i
] == 0)
3035 pdata
->hpd_pins
[i
] = madera_default_hpd_pins
[i
];
3036 else if (pdata
->hpd_pins
[i
] > 0xFFFF)
3037 pdata
->hpd_pins
[i
] = 0;
3041 static int madera_extcon_probe(struct platform_device
*pdev
)
3043 struct madera
*madera
= dev_get_drvdata(pdev
->dev
.parent
);
3044 struct madera_accdet_pdata
*pdata
= &madera
->pdata
.accdet
[0];
3045 struct madera_extcon
*info
;
3046 unsigned int debounce_val
, analog_val
;
3047 int jack_irq_fall
, jack_irq_rise
;
3048 int ret
, mode
, i
, hpdet_short_measured
;
3050 /* quick exit if Madera irqchip driver hasn't completed probe */
3051 if (!madera
->irq_dev
) {
3052 dev_warn(&pdev
->dev
, "irqchip driver not ready\n");
3053 return -EPROBE_DEFER
;
3056 if (!madera
->dapm
|| !madera
->dapm
->card
)
3057 return -EPROBE_DEFER
;
3059 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
3063 info
->pdata
= pdata
;
3064 info
->madera
= madera
;
3065 info
->dev
= &pdev
->dev
;
3066 mutex_init(&info
->lock
);
3067 init_completion(&info
->manual_mic_completion
);
3068 INIT_DELAYED_WORK(&info
->micd_detect_work
, madera_micd_handler
);
3069 INIT_DELAYED_WORK(&info
->state_timeout_work
, madera_jds_timeout_work
);
3070 platform_set_drvdata(pdev
, info
);
3072 switch (madera
->type
) {
3074 info
->hpdet_init_range
= 1; /* range 0 not used on CS47L15 */
3075 info
->hpdet_ranges
= cs47l15_hpdet_ranges
;
3076 info
->num_hpdet_ranges
= ARRAY_SIZE(cs47l15_hpdet_ranges
);
3077 info
->micd_modes
= madera_micd_default_modes
;
3078 info
->num_micd_modes
= ARRAY_SIZE(madera_micd_default_modes
);
3081 pdata
->micd_force_micbias
= true;
3082 info
->hpdet_ranges
= cs47l85_hpdet_ranges
;
3083 info
->num_hpdet_ranges
= ARRAY_SIZE(cs47l85_hpdet_ranges
);
3084 info
->micd_modes
= cs47l85_micd_default_modes
;
3085 info
->num_micd_modes
= ARRAY_SIZE(cs47l85_micd_default_modes
);
3089 info
->hpdet_ranges
= cs47l85_hpdet_ranges
;
3090 info
->num_hpdet_ranges
= ARRAY_SIZE(cs47l85_hpdet_ranges
);
3091 info
->micd_modes
= cs47l85_micd_default_modes
;
3092 info
->num_micd_modes
= ARRAY_SIZE(cs47l85_micd_default_modes
);
3096 info
->hpdet_ranges
= cs47l92_hpdet_ranges
;
3097 info
->num_hpdet_ranges
= ARRAY_SIZE(cs47l92_hpdet_ranges
);
3098 info
->micd_modes
= madera_micd_default_modes
;
3099 info
->num_micd_modes
= ARRAY_SIZE(madera_micd_default_modes
);
3102 info
->hpdet_ranges
= madera_hpdet_ranges
;
3103 info
->num_hpdet_ranges
= ARRAY_SIZE(madera_hpdet_ranges
);
3104 info
->micd_modes
= madera_micd_default_modes
;
3105 info
->num_micd_modes
= ARRAY_SIZE(madera_micd_default_modes
);
3109 if (dev_get_platdata(madera
->dev
)) {
3110 madera_extcon_xlate_pdata(pdata
);
3112 if (pdata
->num_micd_configs
) {
3113 info
->micd_modes
= pdata
->micd_configs
;
3114 info
->num_micd_modes
= pdata
->num_micd_configs
;
3117 if (info
->micd_modes
[0].gpio
)
3118 mode
= GPIOF_OUT_INIT_HIGH
;
3120 mode
= GPIOF_OUT_INIT_LOW
;
3122 ret
= devm_gpio_request_one(&pdev
->dev
,
3123 pdata
->micd_pol_gpio
,
3127 dev_err(info
->dev
, "Failed to request GPIO%d: %d\n",
3128 pdata
->micd_pol_gpio
, ret
);
3132 info
->micd_pol_gpio
= gpio_to_desc(pdata
->micd_pol_gpio
);
3134 ret
= madera_extcon_get_device_pdata(info
);
3139 if (!pdata
->enabled
|| pdata
->output
== 0)
3140 return -ENODEV
; /* no accdet output configured */
3142 info
->hpdet_short_x100
=
3143 madera_ohm_to_hohm(pdata
->hpdet_short_circuit_imp
);
3145 /* Actual measured short is increased by external resistance */
3146 hpdet_short_measured
= pdata
->hpdet_short_circuit_imp
+
3147 madera_hohm_to_ohm(pdata
->hpdet_ext_res_x100
);
3149 if (hpdet_short_measured
< MADERA_HP_SHORT_IMPEDANCE_MIN
) {
3151 * increase comparison threshold to minimum we can measure
3152 * taking into account that threshold does not include external
3155 info
->hpdet_short_x100
=
3156 madera_ohm_to_hohm(MADERA_HP_SHORT_IMPEDANCE_MIN
) -
3157 pdata
->hpdet_ext_res_x100
;
3159 "Increasing HP short circuit impedance from %d to %d\n",
3160 pdata
->hpdet_short_circuit_imp
,
3161 madera_hohm_to_ohm(info
->hpdet_short_x100
));
3164 info
->micvdd
= devm_regulator_get(&pdev
->dev
, "MICVDD");
3165 if (IS_ERR(info
->micvdd
)) {
3166 ret
= PTR_ERR(info
->micvdd
);
3167 dev_err(info
->dev
, "Failed to get MICVDD: %d\n", ret
);
3171 if (pdata
->jd_invert
)
3172 info
->last_jackdet
=
3173 ~(MADERA_MICD_CLAMP_RISE_STS1
| MADERA_JD1_FALL_STS1
);
3175 info
->last_jackdet
=
3176 ~(MADERA_MICD_CLAMP_RISE_STS1
| MADERA_JD1_RISE_STS1
);
3178 info
->edev
= devm_extcon_dev_allocate(&pdev
->dev
, madera_cable
);
3179 if (IS_ERR(info
->edev
)) {
3180 dev_err(&pdev
->dev
, "failed to allocate extcon device\n");
3184 ret
= devm_extcon_dev_register(&pdev
->dev
, info
->edev
);
3186 dev_err(info
->dev
, "extcon_dev_register() failed: %d\n", ret
);
3190 info
->input
= devm_input_allocate_device(&pdev
->dev
);
3192 dev_err(info
->dev
, "Can't allocate input dev\n");
3197 info
->input
->name
= "Headset";
3198 info
->input
->phys
= "madera/extcon";
3199 info
->input
->dev
.parent
= &pdev
->dev
;
3201 if (madera
->pdata
.gpsw
[0] > 0)
3202 regmap_update_bits(madera
->regmap
,
3204 MADERA_SW1_MODE_MASK
,
3205 madera
->pdata
.gpsw
[0] <<
3206 MADERA_SW1_MODE_SHIFT
);
3207 switch (madera
->type
) {
3212 if (madera
->pdata
.gpsw
[1] > 0)
3213 regmap_update_bits(madera
->regmap
,
3215 MADERA_SW2_MODE_MASK
,
3216 madera
->pdata
.gpsw
[1] <<
3217 MADERA_SW2_MODE_SHIFT
);
3223 if (info
->pdata
->micd_bias_start_time
)
3224 regmap_update_bits(madera
->regmap
,
3225 MADERA_MIC_DETECT_1_CONTROL_1
,
3226 MADERA_MICD_BIAS_STARTTIME_MASK
,
3227 info
->pdata
->micd_bias_start_time
3228 << MADERA_MICD_BIAS_STARTTIME_SHIFT
);
3230 if (info
->pdata
->micd_rate
)
3231 regmap_update_bits(madera
->regmap
,
3232 MADERA_MIC_DETECT_1_CONTROL_1
,
3233 MADERA_MICD_RATE_MASK
,
3234 info
->pdata
->micd_rate
3235 << MADERA_MICD_RATE_SHIFT
);
3237 if (info
->pdata
->micd_dbtime
)
3238 regmap_update_bits(madera
->regmap
,
3239 MADERA_MIC_DETECT_1_CONTROL_1
,
3240 MADERA_MICD_DBTIME_MASK
,
3241 info
->pdata
->micd_dbtime
3242 << MADERA_MICD_DBTIME_SHIFT
);
3244 ret
= madera_extcon_init_micd_ranges(info
);
3248 ret
= madera_extcon_add_micd_levels(info
);
3252 madera_extcon_set_micd_clamp_mode(info
);
3254 /*Since Invert the calmp was set, the calmp need to set true as init in case EPOUT will be mute */
3255 madera
->out_clamp
[0]=true;
3257 if ((info
->num_micd_modes
> 2) && !info
->micd_pol_gpio
)
3258 dev_warn(info
->dev
, "Have >1 mic_configs but no pol_gpio\n");
3260 madera_extcon_set_mode(info
, 0);
3263 * Invalidate the tuning level so that the first detection
3264 * will always apply a tuning
3266 info
->hp_tuning_level
= MADERA_HP_TUNING_INVALID
;
3268 pm_runtime_enable(&pdev
->dev
);
3269 pm_runtime_idle(&pdev
->dev
);
3271 pm_runtime_get_sync(&pdev
->dev
);
3273 madera_extcon_read_calibration(info
);
3274 if (info
->hpdet_trims
) {
3275 switch (madera
->type
) {
3279 /* set for accurate HP impedance detection */
3280 regmap_update_bits(madera
->regmap
,
3281 MADERA_ACCESSORY_DETECT_MODE_1
,
3282 MADERA_ACCDET_POLARITY_INV_ENA_MASK
,
3283 1 << MADERA_ACCDET_POLARITY_INV_ENA_SHIFT
);
3289 switch (madera
->type
) {
3291 pdata
->hpdet_ext_res_x100
+= 3300;
3298 /* Skip any HPDET ranges less than the external resistance */
3299 for (i
= info
->hpdet_init_range
; i
< info
->num_hpdet_ranges
; ++i
) {
3300 if (madera_ohm_to_hohm(info
->hpdet_ranges
[i
].max
) >=
3301 pdata
->hpdet_ext_res_x100
) {
3302 info
->hpdet_init_range
= i
;
3306 if (i
== info
->num_hpdet_ranges
) {
3308 "No possible range for external resistance %u.%02u\n",
3309 pdata
->hpdet_ext_res_x100
/ 100,
3310 pdata
->hpdet_ext_res_x100
% 100);
3314 regmap_update_bits(madera
->regmap
, MADERA_HEADPHONE_DETECT_1
,
3315 MADERA_HP_IMPEDANCE_RANGE_MASK
,
3316 info
->hpdet_init_range
<<
3317 MADERA_HP_IMPEDANCE_RANGE_SHIFT
);
3319 ret
= madera_request_irq(madera
, MADERA_IRQ_MICDET1
,
3320 "MICDET", madera_micdet
, info
);
3322 dev_err(&pdev
->dev
, "Failed to get MICDET IRQ: %d\n", ret
);
3326 ret
= madera_request_irq(madera
, MADERA_IRQ_HPDET
,
3327 "HPDET", madera_hpdet_handler
, info
);
3329 dev_err(&pdev
->dev
, "Failed to get HPDET IRQ: %d\n", ret
);
3333 if (info
->pdata
->jd_use_jd2
) {
3334 debounce_val
= MADERA_JD1_DB
| MADERA_JD2_DB
;
3335 analog_val
= MADERA_JD1_ENA
| MADERA_JD2_ENA
;
3336 jack_irq_rise
= MADERA_IRQ_MICD_CLAMP_RISE
;
3337 jack_irq_fall
= MADERA_IRQ_MICD_CLAMP_FALL
;
3339 debounce_val
= MADERA_JD1_DB
;
3340 analog_val
= MADERA_JD1_ENA
;
3341 jack_irq_rise
= MADERA_IRQ_JD1_RISE
;
3342 jack_irq_fall
= MADERA_IRQ_JD1_FALL
;
3345 regmap_update_bits(madera
->regmap
, MADERA_INTERRUPT_DEBOUNCE_7
,
3346 debounce_val
, debounce_val
);
3347 regmap_update_bits(madera
->regmap
, MADERA_JACK_DETECT_ANALOGUE
,
3348 analog_val
, analog_val
);
3350 ret
= madera_request_irq(madera
, jack_irq_rise
,
3351 "JACKDET rise", madera_jackdet
, info
);
3354 "Failed to get JACKDET rise IRQ: %d\n", ret
);
3358 ret
= madera_set_irq_wake(madera
, jack_irq_rise
, 1);
3361 "Failed to set JD rise IRQ wake: %d\n", ret
);
3365 ret
= madera_request_irq(madera
, jack_irq_fall
,
3366 "JACKDET fall", madera_jackdet
, info
);
3368 dev_err(&pdev
->dev
, "Failed to get JD fall IRQ: %d\n", ret
);
3372 ret
= madera_set_irq_wake(madera
, jack_irq_fall
, 1);
3375 "Failed to set JD fall IRQ wake: %d\n", ret
);
3379 ret
= regulator_allow_bypass(info
->micvdd
, true);
3382 "Failed to set MICVDD to bypass: %d\n", ret
);
3384 pm_runtime_put(&pdev
->dev
);
3386 if (IS_ENABLED(CONFIG_EXTCON_MADERA_INPUT_EVENT
)) {
3387 input_set_capability(info
->input
,
3389 SW_MICROPHONE_INSERT
);
3390 input_set_capability(info
->input
,
3392 SW_HEADPHONE_INSERT
);
3393 input_set_capability(info
->input
,
3395 SW_JACK_PHYSICAL_INSERT
);
3396 input_set_capability(info
->input
,
3401 ret
= input_register_device(info
->input
);
3403 dev_err(&pdev
->dev
, "Can't register input device: %d\n", ret
);
3407 ret
= device_create_file(&pdev
->dev
, &dev_attr_hp1_impedance
);
3409 dev_warn(&pdev
->dev
,
3410 "Failed to create sysfs node for hp_impedance %d\n",
3413 madera_extcon_dump_config(info
);
3418 madera_set_irq_wake(madera
, jack_irq_fall
, 0);
3420 madera_free_irq(madera
, jack_irq_fall
, info
);
3422 madera_set_irq_wake(madera
, jack_irq_rise
, 0);
3424 madera_free_irq(madera
, jack_irq_rise
, info
);
3426 madera_free_irq(madera
, MADERA_IRQ_HPDET
, info
);
3428 madera_free_irq(madera
, MADERA_IRQ_MICDET1
, info
);
3431 pm_runtime_disable(&pdev
->dev
);
3436 static int madera_extcon_remove(struct platform_device
*pdev
)
3438 struct madera_extcon
*info
= platform_get_drvdata(pdev
);
3439 struct madera
*madera
= info
->madera
;
3440 int jack_irq_rise
, jack_irq_fall
;
3442 pm_runtime_disable(&pdev
->dev
);
3444 regmap_update_bits(madera
->regmap
, MADERA_MICD_CLAMP_CONTROL
,
3445 MADERA_MICD_CLAMP_MODE_MASK
, 0);
3447 if (info
->pdata
->jd_use_jd2
) {
3448 jack_irq_rise
= MADERA_IRQ_MICD_CLAMP_RISE
;
3449 jack_irq_fall
= MADERA_IRQ_MICD_CLAMP_FALL
;
3451 jack_irq_rise
= MADERA_IRQ_JD1_RISE
;
3452 jack_irq_fall
= MADERA_IRQ_JD1_FALL
;
3455 madera_set_irq_wake(madera
, jack_irq_rise
, 0);
3456 madera_set_irq_wake(madera
, jack_irq_fall
, 0);
3457 madera_free_irq(madera
, MADERA_IRQ_HPDET
, info
);
3458 madera_free_irq(madera
, MADERA_IRQ_MICDET1
, info
);
3459 madera_free_irq(madera
, jack_irq_rise
, info
);
3460 madera_free_irq(madera
, jack_irq_fall
, info
);
3461 regmap_update_bits(madera
->regmap
, MADERA_JACK_DETECT_ANALOGUE
,
3462 MADERA_JD1_ENA
| MADERA_JD2_ENA
, 0);
3464 device_remove_file(&pdev
->dev
, &dev_attr_hp1_impedance
);
3465 kfree(info
->hpdet_trims
);
3470 static struct platform_driver madera_extcon_driver
= {
3472 .name
= "madera-extcon",
3474 .probe
= madera_extcon_probe
,
3475 .remove
= madera_extcon_remove
,
3478 module_platform_driver(madera_extcon_driver
);
3480 MODULE_DESCRIPTION("Madera extcon driver");
3481 MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
3482 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
3483 MODULE_LICENSE("GPL v2");
3484 MODULE_ALIAS("platform:extcon-madera");