1 /* SPDX-License-Identifier: GPL-2.0 */
3 #ifndef __WCD_MBHC_V2_H__
4 #define __WCD_MBHC_V2_H__
6 #include <sound/jack.h>
8 #define WCD_MBHC_FIELD(id, rreg, rmask) \
9 [id] = { .reg = rreg, .mask = rmask }
11 enum wcd_mbhc_field_function {
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,
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,
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,
41 WCD_MBHC_SWCH_LEVEL_REMOVE,
42 WCD_MBHC_PULLDOWN_CTRL,
46 WCD_MBHC_MOISTURE_STATUS,
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,
54 WCD_MBHC_ADC_COMPLETE,
59 WCD_MBHC_DETECTION_DONE,
60 WCD_MBHC_ELECT_ISRC_EN,
61 WCD_MBHC_REG_FUNC_MAX,
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
70 enum wcd_mbhc_detect_logic {
75 enum wcd_mbhc_cs_mb_en_flag {
87 enum wcd_mbhc_plug_type {
88 MBHC_PLUG_TYPE_INVALID = -1,
90 MBHC_PLUG_TYPE_HEADSET,
91 MBHC_PLUG_TYPE_HEADPHONE,
92 MBHC_PLUG_TYPE_HIGH_HPH,
93 MBHC_PLUG_TYPE_GND_MIC_SWAP,
96 enum pa_dac_ack_flags {
97 WCD_MBHC_HPHL_PA_OFF_ACK = 0,
98 WCD_MBHC_HPHR_PA_OFF_ACK,
101 enum wcd_mbhc_btn_det_mem {
102 WCD_MBHC_BTN_DET_V_BTN_LOW,
103 WCD_MBHC_BTN_DET_V_BTN_HIGH
120 enum wcd_notify_event {
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,
143 enum wcd_mbhc_event_state {
144 WCD_MBHC_EVENT_PA_HPHL,
145 WCD_MBHC_EVENT_PA_HPHR,
148 enum wcd_mbhc_hph_type {
149 WCD_MBHC_HPH_NONE = 0,
155 * These enum definitions are directly mapped to the register
159 enum mbhc_hs_pullup_iref {
167 enum mbhc_hs_pullup_iref_v2 {
168 HS_PULLUP_I_DEFAULT = -1,
169 HS_PULLUP_I_3P0_UA = 0,
173 HS_PULLUP_I_1P125_UA = 0x05,
174 HS_PULLUP_I_0P375_UA = 0x07,
176 HS_PULLUP_I_1P0_UA = 0x0A,
178 HS_PULLUP_I_0P25_UA = 0x0F,
179 HS_PULLUP_I_0P125_UA = 0x17,
183 enum mbhc_moisture_rref {
190 struct wcd_mbhc_config {
191 int btn_high[WCD_MBHC_DEF_BUTTONS];
192 int btn_low[WCD_MBHC_DEF_BUTTONS];
195 bool mono_stero_detection;
196 bool typec_analog_mux;
197 bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active);
204 bool moisture_duty_cycle_en;
205 bool hphl_swh; /*track HPHL switch NC / NO */
206 bool gnd_swh; /*track GND switch NC / NO */
215 struct wcd_mbhc_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;
225 struct wcd_mbhc_field {
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,
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,
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,
258 void (*hph_pull_down_ctrl)(struct snd_soc_component *component,
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,
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);
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,
286 void wcd_mbhc_deinit(struct wcd_mbhc *mbhc);
287 int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event);
290 static inline int wcd_dt_parse_mbhc_data(struct device *dev,
291 struct wcd_mbhc_config *cfg)
296 static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
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)
306 return ERR_PTR(-ENOTSUPP);
309 static inline void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type)
313 static inline int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc)
318 static inline int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event)
323 static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc,
324 struct wcd_mbhc_config *mbhc_cfg,
325 struct snd_soc_jack *jack)
330 static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc,
338 static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
343 #endif /* __WCD_MBHC_V2_H__ */