0001
0002
0003 #ifndef __WCD_MBHC_V2_H__
0004 #define __WCD_MBHC_V2_H__
0005
0006 #include <sound/jack.h>
0007
0008 #define WCD_MBHC_FIELD(id, rreg, rmask) \
0009 [id] = { .reg = rreg, .mask = rmask }
0010
0011 enum wcd_mbhc_field_function {
0012 WCD_MBHC_L_DET_EN,
0013 WCD_MBHC_GND_DET_EN,
0014 WCD_MBHC_MECH_DETECTION_TYPE,
0015 WCD_MBHC_MIC_CLAMP_CTL,
0016 WCD_MBHC_ELECT_DETECTION_TYPE,
0017 WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
0018 WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL,
0019 WCD_MBHC_HPHL_PLUG_TYPE,
0020 WCD_MBHC_GND_PLUG_TYPE,
0021 WCD_MBHC_SW_HPH_LP_100K_TO_GND,
0022 WCD_MBHC_ELECT_SCHMT_ISRC,
0023 WCD_MBHC_FSM_EN,
0024 WCD_MBHC_INSREM_DBNC,
0025 WCD_MBHC_BTN_DBNC,
0026 WCD_MBHC_HS_VREF,
0027 WCD_MBHC_HS_COMP_RESULT,
0028 WCD_MBHC_IN2P_CLAMP_STATE,
0029 WCD_MBHC_MIC_SCHMT_RESULT,
0030 WCD_MBHC_HPHL_SCHMT_RESULT,
0031 WCD_MBHC_HPHR_SCHMT_RESULT,
0032 WCD_MBHC_OCP_FSM_EN,
0033 WCD_MBHC_BTN_RESULT,
0034 WCD_MBHC_BTN_ISRC_CTL,
0035 WCD_MBHC_ELECT_RESULT,
0036 WCD_MBHC_MICB_CTRL,
0037 WCD_MBHC_HPH_CNP_WG_TIME,
0038 WCD_MBHC_HPHR_PA_EN,
0039 WCD_MBHC_HPHL_PA_EN,
0040 WCD_MBHC_HPH_PA_EN,
0041 WCD_MBHC_SWCH_LEVEL_REMOVE,
0042 WCD_MBHC_PULLDOWN_CTRL,
0043 WCD_MBHC_ANC_DET_EN,
0044 WCD_MBHC_FSM_STATUS,
0045 WCD_MBHC_MUX_CTL,
0046 WCD_MBHC_MOISTURE_STATUS,
0047 WCD_MBHC_HPHR_GND,
0048 WCD_MBHC_HPHL_GND,
0049 WCD_MBHC_HPHL_OCP_DET_EN,
0050 WCD_MBHC_HPHR_OCP_DET_EN,
0051 WCD_MBHC_HPHL_OCP_STATUS,
0052 WCD_MBHC_HPHR_OCP_STATUS,
0053 WCD_MBHC_ADC_EN,
0054 WCD_MBHC_ADC_COMPLETE,
0055 WCD_MBHC_ADC_TIMEOUT,
0056 WCD_MBHC_ADC_RESULT,
0057 WCD_MBHC_MICB2_VOUT,
0058 WCD_MBHC_ADC_MODE,
0059 WCD_MBHC_DETECTION_DONE,
0060 WCD_MBHC_ELECT_ISRC_EN,
0061 WCD_MBHC_REG_FUNC_MAX,
0062 };
0063
0064 #define WCD_MBHC_DEF_BUTTONS 8
0065 #define WCD_MBHC_KEYCODE_NUM 8
0066 #define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100
0067 #define WCD_MBHC_THR_HS_MICB_MV 2700
0068 #define WCD_MONO_HS_MIN_THR 2
0069
0070 enum wcd_mbhc_detect_logic {
0071 WCD_DETECTION_LEGACY,
0072 WCD_DETECTION_ADC,
0073 };
0074
0075 enum wcd_mbhc_cs_mb_en_flag {
0076 WCD_MBHC_EN_CS = 0,
0077 WCD_MBHC_EN_MB,
0078 WCD_MBHC_EN_PULLUP,
0079 WCD_MBHC_EN_NONE,
0080 };
0081
0082 enum {
0083 WCD_MBHC_ELEC_HS_INS,
0084 WCD_MBHC_ELEC_HS_REM,
0085 };
0086
0087 enum wcd_mbhc_plug_type {
0088 MBHC_PLUG_TYPE_INVALID = -1,
0089 MBHC_PLUG_TYPE_NONE,
0090 MBHC_PLUG_TYPE_HEADSET,
0091 MBHC_PLUG_TYPE_HEADPHONE,
0092 MBHC_PLUG_TYPE_HIGH_HPH,
0093 MBHC_PLUG_TYPE_GND_MIC_SWAP,
0094 };
0095
0096 enum pa_dac_ack_flags {
0097 WCD_MBHC_HPHL_PA_OFF_ACK = 0,
0098 WCD_MBHC_HPHR_PA_OFF_ACK,
0099 };
0100
0101 enum wcd_mbhc_btn_det_mem {
0102 WCD_MBHC_BTN_DET_V_BTN_LOW,
0103 WCD_MBHC_BTN_DET_V_BTN_HIGH
0104 };
0105
0106 enum {
0107 MIC_BIAS_1 = 1,
0108 MIC_BIAS_2,
0109 MIC_BIAS_3,
0110 MIC_BIAS_4
0111 };
0112
0113 enum {
0114 MICB_PULLUP_ENABLE,
0115 MICB_PULLUP_DISABLE,
0116 MICB_ENABLE,
0117 MICB_DISABLE,
0118 };
0119
0120 enum wcd_notify_event {
0121 WCD_EVENT_INVALID,
0122
0123 WCD_EVENT_PRE_MICBIAS_2_OFF,
0124 WCD_EVENT_POST_MICBIAS_2_OFF,
0125 WCD_EVENT_PRE_MICBIAS_2_ON,
0126 WCD_EVENT_POST_MICBIAS_2_ON,
0127 WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF,
0128 WCD_EVENT_POST_DAPM_MICBIAS_2_OFF,
0129 WCD_EVENT_PRE_DAPM_MICBIAS_2_ON,
0130 WCD_EVENT_POST_DAPM_MICBIAS_2_ON,
0131
0132 WCD_EVENT_PRE_HPHL_PA_ON,
0133 WCD_EVENT_POST_HPHL_PA_OFF,
0134 WCD_EVENT_PRE_HPHR_PA_ON,
0135 WCD_EVENT_POST_HPHR_PA_OFF,
0136 WCD_EVENT_PRE_HPHL_PA_OFF,
0137 WCD_EVENT_PRE_HPHR_PA_OFF,
0138 WCD_EVENT_OCP_OFF,
0139 WCD_EVENT_OCP_ON,
0140 WCD_EVENT_LAST,
0141 };
0142
0143 enum wcd_mbhc_event_state {
0144 WCD_MBHC_EVENT_PA_HPHL,
0145 WCD_MBHC_EVENT_PA_HPHR,
0146 };
0147
0148 enum wcd_mbhc_hph_type {
0149 WCD_MBHC_HPH_NONE = 0,
0150 WCD_MBHC_HPH_MONO,
0151 WCD_MBHC_HPH_STEREO,
0152 };
0153
0154
0155
0156
0157
0158
0159 enum mbhc_hs_pullup_iref {
0160 I_DEFAULT = -1,
0161 I_OFF = 0,
0162 I_1P0_UA,
0163 I_2P0_UA,
0164 I_3P0_UA,
0165 };
0166
0167 enum mbhc_hs_pullup_iref_v2 {
0168 HS_PULLUP_I_DEFAULT = -1,
0169 HS_PULLUP_I_3P0_UA = 0,
0170 HS_PULLUP_I_2P25_UA,
0171 HS_PULLUP_I_1P5_UA,
0172 HS_PULLUP_I_0P75_UA,
0173 HS_PULLUP_I_1P125_UA = 0x05,
0174 HS_PULLUP_I_0P375_UA = 0x07,
0175 HS_PULLUP_I_2P0_UA,
0176 HS_PULLUP_I_1P0_UA = 0x0A,
0177 HS_PULLUP_I_0P5_UA,
0178 HS_PULLUP_I_0P25_UA = 0x0F,
0179 HS_PULLUP_I_0P125_UA = 0x17,
0180 HS_PULLUP_I_OFF,
0181 };
0182
0183 enum mbhc_moisture_rref {
0184 R_OFF,
0185 R_24_KOHM,
0186 R_84_KOHM,
0187 R_184_KOHM,
0188 };
0189
0190 struct wcd_mbhc_config {
0191 int btn_high[WCD_MBHC_DEF_BUTTONS];
0192 int btn_low[WCD_MBHC_DEF_BUTTONS];
0193 int v_hs_max;
0194 int num_btn;
0195 bool mono_stero_detection;
0196 bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active);
0197 bool hs_ext_micbias;
0198 bool gnd_det_en;
0199 uint32_t linein_th;
0200 bool moisture_en;
0201 int mbhc_micbias;
0202 int anc_micbias;
0203 bool moisture_duty_cycle_en;
0204 bool hphl_swh;
0205 bool gnd_swh;
0206 u32 hs_thr;
0207 u32 hph_thr;
0208 u32 micb_mv;
0209 u32 moist_vref;
0210 u32 moist_iref;
0211 u32 moist_rref;
0212 };
0213
0214 struct wcd_mbhc_intr {
0215 int mbhc_sw_intr;
0216 int mbhc_btn_press_intr;
0217 int mbhc_btn_release_intr;
0218 int mbhc_hs_ins_intr;
0219 int mbhc_hs_rem_intr;
0220 int hph_left_ocp;
0221 int hph_right_ocp;
0222 };
0223
0224 struct wcd_mbhc_field {
0225 u16 reg;
0226 u8 mask;
0227 };
0228
0229 struct wcd_mbhc;
0230
0231 struct wcd_mbhc_cb {
0232 void (*update_cross_conn_thr)(struct snd_soc_component *component);
0233 void (*get_micbias_val)(struct snd_soc_component *component, int *mb);
0234 void (*bcs_enable)(struct snd_soc_component *component, bool bcs_enable);
0235 void (*compute_impedance)(struct snd_soc_component *component,
0236 uint32_t *zl, uint32_t *zr);
0237 void (*set_micbias_value)(struct snd_soc_component *component);
0238 void (*set_auto_zeroing)(struct snd_soc_component *component,
0239 bool enable);
0240 void (*clk_setup)(struct snd_soc_component *component, bool enable);
0241 bool (*micbias_enable_status)(struct snd_soc_component *component, int micb_num);
0242 void (*mbhc_bias)(struct snd_soc_component *component, bool enable);
0243 void (*set_btn_thr)(struct snd_soc_component *component,
0244 int *btn_low, int *btn_high,
0245 int num_btn, bool is_micbias);
0246 void (*hph_pull_up_control)(struct snd_soc_component *component,
0247 enum mbhc_hs_pullup_iref);
0248 int (*mbhc_micbias_control)(struct snd_soc_component *component,
0249 int micb_num, int req);
0250 void (*mbhc_micb_ramp_control)(struct snd_soc_component *component,
0251 bool enable);
0252 bool (*extn_use_mb)(struct snd_soc_component *component);
0253 int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_component *component,
0254 int micb_num, bool req_en);
0255 void (*mbhc_gnd_det_ctrl)(struct snd_soc_component *component,
0256 bool enable);
0257 void (*hph_pull_down_ctrl)(struct snd_soc_component *component,
0258 bool enable);
0259 void (*mbhc_moisture_config)(struct snd_soc_component *component);
0260 void (*update_anc_state)(struct snd_soc_component *component,
0261 bool enable, int anc_num);
0262 void (*hph_pull_up_control_v2)(struct snd_soc_component *component,
0263 int pull_up_cur);
0264 bool (*mbhc_get_moisture_status)(struct snd_soc_component *component);
0265 void (*mbhc_moisture_polling_ctrl)(struct snd_soc_component *component, bool enable);
0266 void (*mbhc_moisture_detect_en)(struct snd_soc_component *component, bool enable);
0267 };
0268
0269 #if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC)
0270 int wcd_dt_parse_mbhc_data(struct device *dev, struct wcd_mbhc_config *cfg);
0271 int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg,
0272 struct snd_soc_jack *jack);
0273 void wcd_mbhc_stop(struct wcd_mbhc *mbhc);
0274 void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type);
0275 int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc);
0276 struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
0277 const struct wcd_mbhc_cb *mbhc_cb,
0278 const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
0279 struct wcd_mbhc_field *fields,
0280 bool impedance_det_en);
0281 int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
0282 uint32_t *zr);
0283 void wcd_mbhc_deinit(struct wcd_mbhc *mbhc);
0284 int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event);
0285
0286 #else
0287 static inline int wcd_dt_parse_mbhc_data(struct device *dev,
0288 struct wcd_mbhc_config *cfg)
0289 {
0290 return -ENOTSUPP;
0291 }
0292
0293 static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
0294 {
0295 }
0296
0297 static inline struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
0298 const struct wcd_mbhc_cb *mbhc_cb,
0299 const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
0300 struct wcd_mbhc_field *fields,
0301 bool impedance_det_en)
0302 {
0303 return ERR_PTR(-ENOTSUPP);
0304 }
0305
0306 static inline void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type)
0307 {
0308 }
0309
0310 static inline int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc)
0311 {
0312 return -ENOTSUPP;
0313 }
0314
0315 static inline int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event)
0316 {
0317 return -ENOTSUPP;
0318 }
0319
0320 static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc,
0321 struct wcd_mbhc_config *mbhc_cfg,
0322 struct snd_soc_jack *jack)
0323 {
0324 return 0;
0325 }
0326
0327 static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc,
0328 uint32_t *zl,
0329 uint32_t *zr)
0330 {
0331 *zl = 0;
0332 *zr = 0;
0333 return -EINVAL;
0334 }
0335 static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
0336 {
0337 }
0338 #endif
0339
0340 #endif