1
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
11enum 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,
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
70enum wcd_mbhc_detect_logic {
71 WCD_DETECTION_LEGACY,
72 WCD_DETECTION_ADC,
73};
74
75enum 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
82enum {
83 WCD_MBHC_ELEC_HS_INS,
84 WCD_MBHC_ELEC_HS_REM,
85};
86
87enum 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
96enum pa_dac_ack_flags {
97 WCD_MBHC_HPHL_PA_OFF_ACK = 0,
98 WCD_MBHC_HPHR_PA_OFF_ACK,
99};
100
101enum wcd_mbhc_btn_det_mem {
102 WCD_MBHC_BTN_DET_V_BTN_LOW,
103 WCD_MBHC_BTN_DET_V_BTN_HIGH
104};
105
106enum {
107 MIC_BIAS_1 = 1,
108 MIC_BIAS_2,
109 MIC_BIAS_3,
110 MIC_BIAS_4
111};
112
113enum {
114 MICB_PULLUP_ENABLE,
115 MICB_PULLUP_DISABLE,
116 MICB_ENABLE,
117 MICB_DISABLE,
118};
119
120enum wcd_notify_event {
121 WCD_EVENT_INVALID,
122
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
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
143enum wcd_mbhc_event_state {
144 WCD_MBHC_EVENT_PA_HPHL,
145 WCD_MBHC_EVENT_PA_HPHR,
146};
147
148enum wcd_mbhc_hph_type {
149 WCD_MBHC_HPH_NONE = 0,
150 WCD_MBHC_HPH_MONO,
151 WCD_MBHC_HPH_STEREO,
152};
153
154
155
156
157
158
159enum 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
167enum 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
183enum mbhc_moisture_rref {
184 R_OFF,
185 R_24_KOHM,
186 R_84_KOHM,
187 R_184_KOHM,
188};
189
190struct 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 (*swap_gnd_mic)(struct snd_soc_component *component, bool active);
197 bool hs_ext_micbias;
198 bool gnd_det_en;
199 uint32_t linein_th;
200 bool moisture_en;
201 int mbhc_micbias;
202 int anc_micbias;
203 bool moisture_duty_cycle_en;
204 bool hphl_swh;
205 bool gnd_swh;
206 u32 hs_thr;
207 u32 hph_thr;
208 u32 micb_mv;
209 u32 moist_vref;
210 u32 moist_iref;
211 u32 moist_rref;
212};
213
214struct wcd_mbhc_intr {
215 int mbhc_sw_intr;
216 int mbhc_btn_press_intr;
217 int mbhc_btn_release_intr;
218 int mbhc_hs_ins_intr;
219 int mbhc_hs_rem_intr;
220 int hph_left_ocp;
221 int hph_right_ocp;
222};
223
224struct wcd_mbhc_field {
225 u16 reg;
226 u8 mask;
227};
228
229struct wcd_mbhc;
230
231struct wcd_mbhc_cb {
232 void (*update_cross_conn_thr)(struct snd_soc_component *component);
233 void (*get_micbias_val)(struct snd_soc_component *component, int *mb);
234 void (*bcs_enable)(struct snd_soc_component *component, bool bcs_enable);
235 void (*compute_impedance)(struct snd_soc_component *component,
236 uint32_t *zl, uint32_t *zr);
237 void (*set_micbias_value)(struct snd_soc_component *component);
238 void (*set_auto_zeroing)(struct snd_soc_component *component,
239 bool enable);
240 void (*clk_setup)(struct snd_soc_component *component, bool enable);
241 bool (*micbias_enable_status)(struct snd_soc_component *component, int micb_num);
242 void (*mbhc_bias)(struct snd_soc_component *component, bool enable);
243 void (*set_btn_thr)(struct snd_soc_component *component,
244 int *btn_low, int *btn_high,
245 int num_btn, bool is_micbias);
246 void (*hph_pull_up_control)(struct snd_soc_component *component,
247 enum mbhc_hs_pullup_iref);
248 int (*mbhc_micbias_control)(struct snd_soc_component *component,
249 int micb_num, int req);
250 void (*mbhc_micb_ramp_control)(struct snd_soc_component *component,
251 bool enable);
252 bool (*extn_use_mb)(struct snd_soc_component *component);
253 int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_component *component,
254 int micb_num, bool req_en);
255 void (*mbhc_gnd_det_ctrl)(struct snd_soc_component *component,
256 bool enable);
257 void (*hph_pull_down_ctrl)(struct snd_soc_component *component,
258 bool enable);
259 void (*mbhc_moisture_config)(struct snd_soc_component *component);
260 void (*update_anc_state)(struct snd_soc_component *component,
261 bool enable, int anc_num);
262 void (*hph_pull_up_control_v2)(struct snd_soc_component *component,
263 int pull_up_cur);
264 bool (*mbhc_get_moisture_status)(struct snd_soc_component *component);
265 void (*mbhc_moisture_polling_ctrl)(struct snd_soc_component *component, bool enable);
266 void (*mbhc_moisture_detect_en)(struct snd_soc_component *component, bool enable);
267};
268
269#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC)
270int wcd_dt_parse_mbhc_data(struct device *dev, struct wcd_mbhc_config *cfg);
271int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg,
272 struct snd_soc_jack *jack);
273void wcd_mbhc_stop(struct wcd_mbhc *mbhc);
274void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type);
275int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc);
276struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
277 const struct wcd_mbhc_cb *mbhc_cb,
278 const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
279 struct wcd_mbhc_field *fields,
280 bool impedance_det_en);
281int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
282 uint32_t *zr);
283void wcd_mbhc_deinit(struct wcd_mbhc *mbhc);
284int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event);
285
286#else
287static inline int wcd_dt_parse_mbhc_data(struct device *dev,
288 struct wcd_mbhc_config *cfg)
289{
290 return -ENOTSUPP;
291}
292
293static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
294{
295}
296
297static inline struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
298 const struct wcd_mbhc_cb *mbhc_cb,
299 const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
300 struct wcd_mbhc_field *fields,
301 bool impedance_det_en)
302{
303 return ERR_PTR(-ENOTSUPP);
304}
305
306static inline void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type)
307{
308}
309
310static inline int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc)
311{
312 return -ENOTSUPP;
313}
314
315static inline int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event)
316{
317 return -ENOTSUPP;
318}
319
320static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc,
321 struct wcd_mbhc_config *mbhc_cfg,
322 struct snd_soc_jack *jack)
323{
324 return 0;
325}
326
327static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc,
328 uint32_t *zl,
329 uint32_t *zr)
330{
331 *zl = 0;
332 *zr = 0;
333 return -EINVAL;
334}
335static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
336{
337}
338#endif
339
340#endif
341