GNU Linux-libre 6.9.1-gnu
[releases.git] / sound / soc / codecs / wcd-mbhc-v2.h
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__ */