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 const 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 const 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