1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | #ifndef __WCD_MBHC_V2_H__ |
4 | #define __WCD_MBHC_V2_H__ |
5 | |
6 | #include <sound/jack.h> |
7 | |
8 | #define WCD_MBHC_FIELD(id, rreg, rmask) \ |
9 | [id] = { .reg = rreg, .mask = rmask } |
10 | |
11 | enum wcd_mbhc_field_function { |
12 | WCD_MBHC_L_DET_EN, |
13 | WCD_MBHC_GND_DET_EN, |
14 | WCD_MBHC_MECH_DETECTION_TYPE, |
15 | WCD_MBHC_MIC_CLAMP_CTL, |
16 | WCD_MBHC_ELECT_DETECTION_TYPE, |
17 | WCD_MBHC_HS_L_DET_PULL_UP_CTRL, |
18 | WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, |
19 | WCD_MBHC_HPHL_PLUG_TYPE, |
20 | WCD_MBHC_GND_PLUG_TYPE, |
21 | WCD_MBHC_SW_HPH_LP_100K_TO_GND, |
22 | WCD_MBHC_ELECT_SCHMT_ISRC, |
23 | WCD_MBHC_FSM_EN, |
24 | WCD_MBHC_INSREM_DBNC, |
25 | WCD_MBHC_BTN_DBNC, |
26 | WCD_MBHC_HS_VREF, |
27 | WCD_MBHC_HS_COMP_RESULT, |
28 | WCD_MBHC_IN2P_CLAMP_STATE, |
29 | WCD_MBHC_MIC_SCHMT_RESULT, |
30 | WCD_MBHC_HPHL_SCHMT_RESULT, |
31 | WCD_MBHC_HPHR_SCHMT_RESULT, |
32 | WCD_MBHC_OCP_FSM_EN, |
33 | WCD_MBHC_BTN_RESULT, |
34 | WCD_MBHC_BTN_ISRC_CTL, |
35 | WCD_MBHC_ELECT_RESULT, |
36 | WCD_MBHC_MICB_CTRL, /* Pull-up and micb control */ |
37 | WCD_MBHC_HPH_CNP_WG_TIME, |
38 | WCD_MBHC_HPHR_PA_EN, |
39 | WCD_MBHC_HPHL_PA_EN, |
40 | WCD_MBHC_HPH_PA_EN, |
41 | WCD_MBHC_SWCH_LEVEL_REMOVE, |
42 | WCD_MBHC_PULLDOWN_CTRL, |
43 | WCD_MBHC_ANC_DET_EN, |
44 | WCD_MBHC_FSM_STATUS, |
45 | WCD_MBHC_MUX_CTL, |
46 | WCD_MBHC_MOISTURE_STATUS, |
47 | WCD_MBHC_HPHR_GND, |
48 | WCD_MBHC_HPHL_GND, |
49 | WCD_MBHC_HPHL_OCP_DET_EN, |
50 | WCD_MBHC_HPHR_OCP_DET_EN, |
51 | WCD_MBHC_HPHL_OCP_STATUS, |
52 | WCD_MBHC_HPHR_OCP_STATUS, |
53 | WCD_MBHC_ADC_EN, |
54 | WCD_MBHC_ADC_COMPLETE, |
55 | WCD_MBHC_ADC_TIMEOUT, |
56 | WCD_MBHC_ADC_RESULT, |
57 | WCD_MBHC_MICB2_VOUT, |
58 | WCD_MBHC_ADC_MODE, |
59 | WCD_MBHC_DETECTION_DONE, |
60 | WCD_MBHC_ELECT_ISRC_EN, |
61 | WCD_MBHC_REG_FUNC_MAX, |
62 | }; |
63 | |
64 | #define WCD_MBHC_DEF_BUTTONS 8 |
65 | #define WCD_MBHC_KEYCODE_NUM 8 |
66 | #define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100 |
67 | #define WCD_MBHC_THR_HS_MICB_MV 2700 |
68 | #define WCD_MONO_HS_MIN_THR 2 |
69 | |
70 | enum wcd_mbhc_detect_logic { |
71 | WCD_DETECTION_LEGACY, |
72 | WCD_DETECTION_ADC, |
73 | }; |
74 | |
75 | enum wcd_mbhc_cs_mb_en_flag { |
76 | WCD_MBHC_EN_CS = 0, |
77 | WCD_MBHC_EN_MB, |
78 | WCD_MBHC_EN_PULLUP, |
79 | WCD_MBHC_EN_NONE, |
80 | }; |
81 | |
82 | enum { |
83 | WCD_MBHC_ELEC_HS_INS, |
84 | WCD_MBHC_ELEC_HS_REM, |
85 | }; |
86 | |
87 | enum wcd_mbhc_plug_type { |
88 | MBHC_PLUG_TYPE_INVALID = -1, |
89 | MBHC_PLUG_TYPE_NONE, |
90 | MBHC_PLUG_TYPE_HEADSET, |
91 | MBHC_PLUG_TYPE_HEADPHONE, |
92 | MBHC_PLUG_TYPE_HIGH_HPH, |
93 | MBHC_PLUG_TYPE_GND_MIC_SWAP, |
94 | }; |
95 | |
96 | enum pa_dac_ack_flags { |
97 | WCD_MBHC_HPHL_PA_OFF_ACK = 0, |
98 | WCD_MBHC_HPHR_PA_OFF_ACK, |
99 | }; |
100 | |
101 | enum wcd_mbhc_btn_det_mem { |
102 | WCD_MBHC_BTN_DET_V_BTN_LOW, |
103 | WCD_MBHC_BTN_DET_V_BTN_HIGH |
104 | }; |
105 | |
106 | enum { |
107 | MIC_BIAS_1 = 1, |
108 | MIC_BIAS_2, |
109 | MIC_BIAS_3, |
110 | MIC_BIAS_4 |
111 | }; |
112 | |
113 | enum { |
114 | MICB_PULLUP_ENABLE, |
115 | MICB_PULLUP_DISABLE, |
116 | MICB_ENABLE, |
117 | MICB_DISABLE, |
118 | }; |
119 | |
120 | enum wcd_notify_event { |
121 | WCD_EVENT_INVALID, |
122 | /* events for micbias ON and OFF */ |
123 | WCD_EVENT_PRE_MICBIAS_2_OFF, |
124 | WCD_EVENT_POST_MICBIAS_2_OFF, |
125 | WCD_EVENT_PRE_MICBIAS_2_ON, |
126 | WCD_EVENT_POST_MICBIAS_2_ON, |
127 | WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF, |
128 | WCD_EVENT_POST_DAPM_MICBIAS_2_OFF, |
129 | WCD_EVENT_PRE_DAPM_MICBIAS_2_ON, |
130 | WCD_EVENT_POST_DAPM_MICBIAS_2_ON, |
131 | /* events for PA ON and OFF */ |
132 | WCD_EVENT_PRE_HPHL_PA_ON, |
133 | WCD_EVENT_POST_HPHL_PA_OFF, |
134 | WCD_EVENT_PRE_HPHR_PA_ON, |
135 | WCD_EVENT_POST_HPHR_PA_OFF, |
136 | WCD_EVENT_PRE_HPHL_PA_OFF, |
137 | WCD_EVENT_PRE_HPHR_PA_OFF, |
138 | WCD_EVENT_OCP_OFF, |
139 | WCD_EVENT_OCP_ON, |
140 | WCD_EVENT_LAST, |
141 | }; |
142 | |
143 | enum wcd_mbhc_event_state { |
144 | WCD_MBHC_EVENT_PA_HPHL, |
145 | WCD_MBHC_EVENT_PA_HPHR, |
146 | }; |
147 | |
148 | enum wcd_mbhc_hph_type { |
149 | WCD_MBHC_HPH_NONE = 0, |
150 | WCD_MBHC_HPH_MONO, |
151 | WCD_MBHC_HPH_STEREO, |
152 | }; |
153 | |
154 | /* |
155 | * These enum definitions are directly mapped to the register |
156 | * definitions |
157 | */ |
158 | |
159 | enum mbhc_hs_pullup_iref { |
160 | I_DEFAULT = -1, |
161 | I_OFF = 0, |
162 | I_1P0_UA, |
163 | I_2P0_UA, |
164 | I_3P0_UA, |
165 | }; |
166 | |
167 | enum mbhc_hs_pullup_iref_v2 { |
168 | HS_PULLUP_I_DEFAULT = -1, |
169 | HS_PULLUP_I_3P0_UA = 0, |
170 | HS_PULLUP_I_2P25_UA, |
171 | HS_PULLUP_I_1P5_UA, |
172 | HS_PULLUP_I_0P75_UA, |
173 | HS_PULLUP_I_1P125_UA = 0x05, |
174 | HS_PULLUP_I_0P375_UA = 0x07, |
175 | HS_PULLUP_I_2P0_UA, |
176 | HS_PULLUP_I_1P0_UA = 0x0A, |
177 | HS_PULLUP_I_0P5_UA, |
178 | HS_PULLUP_I_0P25_UA = 0x0F, |
179 | HS_PULLUP_I_0P125_UA = 0x17, |
180 | HS_PULLUP_I_OFF, |
181 | }; |
182 | |
183 | enum mbhc_moisture_rref { |
184 | R_OFF, |
185 | R_24_KOHM, |
186 | R_84_KOHM, |
187 | R_184_KOHM, |
188 | }; |
189 | |
190 | struct wcd_mbhc_config { |
191 | int btn_high[WCD_MBHC_DEF_BUTTONS]; |
192 | int btn_low[WCD_MBHC_DEF_BUTTONS]; |
193 | int v_hs_max; |
194 | int num_btn; |
195 | bool mono_stero_detection; |
196 | bool typec_analog_mux; |
197 | bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active); |
198 | bool hs_ext_micbias; |
199 | bool gnd_det_en; |
200 | uint32_t linein_th; |
201 | bool moisture_en; |
202 | int mbhc_micbias; |
203 | int anc_micbias; |
204 | bool moisture_duty_cycle_en; |
205 | bool hphl_swh; /*track HPHL switch NC / NO */ |
206 | bool gnd_swh; /*track GND switch NC / NO */ |
207 | u32 hs_thr; |
208 | u32 hph_thr; |
209 | u32 micb_mv; |
210 | u32 moist_vref; |
211 | u32 moist_iref; |
212 | u32 moist_rref; |
213 | }; |
214 | |
215 | struct wcd_mbhc_intr { |
216 | int mbhc_sw_intr; |
217 | int mbhc_btn_press_intr; |
218 | int mbhc_btn_release_intr; |
219 | int mbhc_hs_ins_intr; |
220 | int mbhc_hs_rem_intr; |
221 | int hph_left_ocp; |
222 | int hph_right_ocp; |
223 | }; |
224 | |
225 | struct wcd_mbhc_field { |
226 | u16 reg; |
227 | u8 mask; |
228 | }; |
229 | |
230 | struct wcd_mbhc; |
231 | |
232 | struct wcd_mbhc_cb { |
233 | void (*update_cross_conn_thr)(struct snd_soc_component *component); |
234 | void (*get_micbias_val)(struct snd_soc_component *component, int *mb); |
235 | void (*bcs_enable)(struct snd_soc_component *component, bool bcs_enable); |
236 | void (*compute_impedance)(struct snd_soc_component *component, |
237 | uint32_t *zl, uint32_t *zr); |
238 | void (*set_micbias_value)(struct snd_soc_component *component); |
239 | void (*set_auto_zeroing)(struct snd_soc_component *component, |
240 | bool enable); |
241 | void (*clk_setup)(struct snd_soc_component *component, bool enable); |
242 | bool (*micbias_enable_status)(struct snd_soc_component *component, int micb_num); |
243 | void (*mbhc_bias)(struct snd_soc_component *component, bool enable); |
244 | void (*set_btn_thr)(struct snd_soc_component *component, |
245 | int *btn_low, int *btn_high, |
246 | int num_btn, bool is_micbias); |
247 | void (*hph_pull_up_control)(struct snd_soc_component *component, |
248 | enum mbhc_hs_pullup_iref); |
249 | int (*mbhc_micbias_control)(struct snd_soc_component *component, |
250 | int micb_num, int req); |
251 | void (*mbhc_micb_ramp_control)(struct snd_soc_component *component, |
252 | bool enable); |
253 | bool (*extn_use_mb)(struct snd_soc_component *component); |
254 | int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_component *component, |
255 | int micb_num, bool req_en); |
256 | void (*mbhc_gnd_det_ctrl)(struct snd_soc_component *component, |
257 | bool enable); |
258 | void (*hph_pull_down_ctrl)(struct snd_soc_component *component, |
259 | bool enable); |
260 | void (*mbhc_moisture_config)(struct snd_soc_component *component); |
261 | void (*update_anc_state)(struct snd_soc_component *component, |
262 | bool enable, int anc_num); |
263 | void (*hph_pull_up_control_v2)(struct snd_soc_component *component, |
264 | int pull_up_cur); |
265 | bool (*mbhc_get_moisture_status)(struct snd_soc_component *component); |
266 | void (*mbhc_moisture_polling_ctrl)(struct snd_soc_component *component, bool enable); |
267 | void (*mbhc_moisture_detect_en)(struct snd_soc_component *component, bool enable); |
268 | }; |
269 | |
270 | #if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC) |
271 | int wcd_dt_parse_mbhc_data(struct device *dev, struct wcd_mbhc_config *cfg); |
272 | int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg, |
273 | struct snd_soc_jack *jack); |
274 | void wcd_mbhc_stop(struct wcd_mbhc *mbhc); |
275 | void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type); |
276 | int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc); |
277 | int wcd_mbhc_typec_report_plug(struct wcd_mbhc *mbhc); |
278 | int wcd_mbhc_typec_report_unplug(struct wcd_mbhc *mbhc); |
279 | struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, |
280 | const struct wcd_mbhc_cb *mbhc_cb, |
281 | const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, |
282 | struct wcd_mbhc_field *fields, |
283 | bool impedance_det_en); |
284 | int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, |
285 | uint32_t *zr); |
286 | void wcd_mbhc_deinit(struct wcd_mbhc *mbhc); |
287 | int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event); |
288 | |
289 | #else |
290 | static inline int wcd_dt_parse_mbhc_data(struct device *dev, |
291 | struct wcd_mbhc_config *cfg) |
292 | { |
293 | return -ENOTSUPP; |
294 | } |
295 | |
296 | static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc) |
297 | { |
298 | } |
299 | |
300 | static inline struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, |
301 | const struct wcd_mbhc_cb *mbhc_cb, |
302 | const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, |
303 | struct wcd_mbhc_field *fields, |
304 | bool impedance_det_en) |
305 | { |
306 | return ERR_PTR(-ENOTSUPP); |
307 | } |
308 | |
309 | static inline void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type) |
310 | { |
311 | } |
312 | |
313 | static inline int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc) |
314 | { |
315 | return -ENOTSUPP; |
316 | } |
317 | |
318 | static inline int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event) |
319 | { |
320 | return -ENOTSUPP; |
321 | } |
322 | |
323 | static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc, |
324 | struct wcd_mbhc_config *mbhc_cfg, |
325 | struct snd_soc_jack *jack) |
326 | { |
327 | return 0; |
328 | } |
329 | |
330 | static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, |
331 | uint32_t *zl, |
332 | uint32_t *zr) |
333 | { |
334 | *zl = 0; |
335 | *zr = 0; |
336 | return -EINVAL; |
337 | } |
338 | static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) |
339 | { |
340 | } |
341 | #endif |
342 | |
343 | #endif /* __WCD_MBHC_V2_H__ */ |
344 | |