wcd-mbhc-v2.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #ifndef __WCD_MBHC_V2_H__
  13. #define __WCD_MBHC_V2_H__
  14. #include <linux/wait.h>
  15. #include <linux/stringify.h>
  16. #include <linux/power_supply.h>
  17. #include "wcdcal-hwdep.h"
  18. #include <sound/jack.h>
  19. #define TOMBAK_MBHC_NC 0
  20. #define TOMBAK_MBHC_NO 1
  21. #define WCD_MBHC_DEF_BUTTONS 8
  22. #define WCD_MBHC_KEYCODE_NUM 8
  23. #define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100
  24. #define WCD_MBHC_THR_HS_MICB_MV 2700
  25. /* z value defined in Ohms */
  26. #define WCD_MONO_HS_MIN_THR 2
  27. #define WCD_MBHC_STRINGIFY(s) __stringify(s)
  28. #define WCD_MBHC_REGISTER(rid, rreg, rmask, rshift, rinvert) \
  29. { .id = rid, .reg = rreg, .mask = rmask, .offset = rshift, .invert = rinvert }
  30. #define WCD_MBHC_RSC_LOCK(mbhc) \
  31. { \
  32. pr_debug("%s: Acquiring BCL\n", __func__); \
  33. mutex_lock(&mbhc->codec_resource_lock); \
  34. pr_debug("%s: Acquiring BCL done\n", __func__); \
  35. }
  36. #define WCD_MBHC_RSC_UNLOCK(mbhc) \
  37. { \
  38. pr_debug("%s: Release BCL\n", __func__); \
  39. mutex_unlock(&mbhc->codec_resource_lock); \
  40. }
  41. #define WCD_MBHC_RSC_ASSERT_LOCKED(mbhc) \
  42. { \
  43. WARN_ONCE(!mutex_is_locked(&mbhc->codec_resource_lock), \
  44. "%s: BCL should have acquired\n", __func__); \
  45. }
  46. /*
  47. * Macros to update and read mbhc register bits. Check for
  48. * "0" before updating or reading the register, because it
  49. * is possible that one codec wants to write to that bit and
  50. * other codec does not.
  51. */
  52. #define WCD_MBHC_REG_UPDATE_BITS(function, val) \
  53. do { \
  54. if (mbhc->wcd_mbhc_regs[function].reg) { \
  55. snd_soc_update_bits(mbhc->codec, \
  56. mbhc->wcd_mbhc_regs[function].reg, \
  57. mbhc->wcd_mbhc_regs[function].mask, \
  58. val << (mbhc->wcd_mbhc_regs[function].offset)); \
  59. } \
  60. } while (0)
  61. #define WCD_MBHC_REG_READ(function, val) \
  62. do { \
  63. if (mbhc->wcd_mbhc_regs[function].reg) { \
  64. val = (((snd_soc_read(mbhc->codec, \
  65. mbhc->wcd_mbhc_regs[function].reg)) & \
  66. (mbhc->wcd_mbhc_regs[function].mask)) >> \
  67. (mbhc->wcd_mbhc_regs[function].offset)); \
  68. } else { \
  69. val = -EINVAL; \
  70. } \
  71. } while (0)
  72. #define WCD_MBHC_CAL_SIZE(buttons, rload) ( \
  73. sizeof(struct wcd_mbhc_general_cfg) + \
  74. sizeof(struct wcd_mbhc_plug_detect_cfg) + \
  75. ((sizeof(s16) + sizeof(s16)) * buttons) + \
  76. sizeof(struct wcd_mbhc_plug_type_cfg) + \
  77. sizeof(struct wcd_mbhc_btn_detect_cfg) + \
  78. sizeof(struct wcd_mbhc_imped_detect_cfg) + \
  79. ((sizeof(u16) + sizeof(u16)) * rload) \
  80. )
  81. #define WCD_MBHC_CAL_GENERAL_PTR(cali) ( \
  82. (struct wcd_mbhc_general_cfg *) cali)
  83. #define WCD_MBHC_CAL_PLUG_DET_PTR(cali) ( \
  84. (struct wcd_mbhc_plug_detect_cfg *) \
  85. &(WCD_MBHC_CAL_GENERAL_PTR(cali)[1]))
  86. #define WCD_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \
  87. (struct wcd_mbhc_plug_type_cfg *) \
  88. &(WCD_MBHC_CAL_PLUG_DET_PTR(cali)[1]))
  89. #define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \
  90. (struct wcd_mbhc_btn_detect_cfg *) \
  91. &(WCD_MBHC_CAL_PLUG_TYPE_PTR(cali)[1]))
  92. #define WCD_MBHC_CAL_IMPED_DET_PTR(cali) ( \
  93. (struct wcd_mbhc_imped_detect_cfg *) \
  94. (((void *)&WCD_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \
  95. (WCD_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \
  96. (sizeof(WCD_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \
  97. sizeof(WCD_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
  98. )
  99. #define WCD_MBHC_CAL_MIN_SIZE ( \
  100. sizeof(struct wcd_mbhc_general_cfg) + \
  101. sizeof(struct wcd_mbhc_plug_detect_cfg) + \
  102. sizeof(struct wcd_mbhc_plug_type_cfg) + \
  103. sizeof(struct wcd_mbhc_btn_detect_cfg) + \
  104. sizeof(struct wcd_mbhc_imped_detect_cfg) + \
  105. (sizeof(u16)*2) \
  106. )
  107. #define WCD_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
  108. sizeof(struct wcd_mbhc_btn_detect_cfg) + \
  109. (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
  110. sizeof(cfg_ptr->_v_btn_high[0]))))
  111. #define WCD_MBHC_CAL_IMPED_MIN_SZ ( \
  112. sizeof(struct wcd_mbhc_imped_detect_cfg) + sizeof(u16) * 2)
  113. #define WCD_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
  114. sizeof(struct wcd_mbhc_imped_detect_cfg) + \
  115. (cfg_ptr->_n_rload * \
  116. (sizeof(cfg_ptr->_rload[0]) + sizeof(cfg_ptr->_alpha[0]))))
  117. #define WCD_MBHC_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
  118. SND_JACK_OC_HPHR | SND_JACK_LINEOUT | \
  119. SND_JACK_MECHANICAL | SND_JACK_MICROPHONE2 | \
  120. SND_JACK_UNSUPPORTED)
  121. #define WCD_MBHC_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
  122. SND_JACK_BTN_2 | SND_JACK_BTN_3 | \
  123. SND_JACK_BTN_4 | SND_JACK_BTN_5)
  124. #define OCP_ATTEMPT 20
  125. #define HS_DETECT_PLUG_TIME_MS (3 * 1000)
  126. #define SPECIAL_HS_DETECT_TIME_MS (2 * 1000)
  127. #define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250
  128. #define GND_MIC_SWAP_THRESHOLD 4
  129. #define GND_MIC_USBC_SWAP_THRESHOLD 2
  130. #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100
  131. #define HS_VREF_MIN_VAL 1400
  132. #define FW_READ_ATTEMPTS 15
  133. #define FW_READ_TIMEOUT 4000000
  134. #define FAKE_REM_RETRY_ATTEMPTS 3
  135. #define MAX_IMPED 60000
  136. #define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50
  137. #define ANC_DETECT_RETRY_CNT 7
  138. #define WCD_MBHC_SPL_HS_CNT 1
  139. enum wcd_mbhc_detect_logic {
  140. WCD_DETECTION_LEGACY,
  141. WCD_DETECTION_ADC,
  142. };
  143. enum wcd_mbhc_cs_mb_en_flag {
  144. WCD_MBHC_EN_CS = 0,
  145. WCD_MBHC_EN_MB,
  146. WCD_MBHC_EN_PULLUP,
  147. WCD_MBHC_EN_NONE,
  148. };
  149. enum {
  150. WCD_MBHC_ELEC_HS_INS,
  151. WCD_MBHC_ELEC_HS_REM,
  152. };
  153. struct wcd_mbhc;
  154. enum wcd_mbhc_register_function {
  155. WCD_MBHC_L_DET_EN,
  156. WCD_MBHC_GND_DET_EN,
  157. WCD_MBHC_MECH_DETECTION_TYPE,
  158. WCD_MBHC_MIC_CLAMP_CTL,
  159. WCD_MBHC_ELECT_DETECTION_TYPE,
  160. WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
  161. WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL,
  162. WCD_MBHC_HPHL_PLUG_TYPE,
  163. WCD_MBHC_GND_PLUG_TYPE,
  164. WCD_MBHC_SW_HPH_LP_100K_TO_GND,
  165. WCD_MBHC_ELECT_SCHMT_ISRC,
  166. WCD_MBHC_FSM_EN,
  167. WCD_MBHC_INSREM_DBNC,
  168. WCD_MBHC_BTN_DBNC,
  169. WCD_MBHC_HS_VREF,
  170. WCD_MBHC_HS_COMP_RESULT,
  171. WCD_MBHC_MIC_SCHMT_RESULT,
  172. WCD_MBHC_HPHL_SCHMT_RESULT,
  173. WCD_MBHC_HPHR_SCHMT_RESULT,
  174. WCD_MBHC_OCP_FSM_EN,
  175. WCD_MBHC_BTN_RESULT,
  176. WCD_MBHC_BTN_ISRC_CTL,
  177. WCD_MBHC_ELECT_RESULT,
  178. WCD_MBHC_MICB_CTRL, /* Pull-up and micb control */
  179. WCD_MBHC_HPH_CNP_WG_TIME,
  180. WCD_MBHC_HPHR_PA_EN,
  181. WCD_MBHC_HPHL_PA_EN,
  182. WCD_MBHC_HPH_PA_EN,
  183. WCD_MBHC_SWCH_LEVEL_REMOVE,
  184. WCD_MBHC_PULLDOWN_CTRL,
  185. WCD_MBHC_ANC_DET_EN,
  186. WCD_MBHC_FSM_STATUS,
  187. WCD_MBHC_MUX_CTL,
  188. WCD_MBHC_MOISTURE_STATUS,
  189. WCD_MBHC_HPHR_GND,
  190. WCD_MBHC_HPHL_GND,
  191. WCD_MBHC_HPHL_OCP_DET_EN,
  192. WCD_MBHC_HPHR_OCP_DET_EN,
  193. WCD_MBHC_HPHL_OCP_STATUS,
  194. WCD_MBHC_HPHR_OCP_STATUS,
  195. WCD_MBHC_ADC_EN,
  196. WCD_MBHC_ADC_COMPLETE,
  197. WCD_MBHC_ADC_TIMEOUT,
  198. WCD_MBHC_ADC_RESULT,
  199. WCD_MBHC_MICB2_VOUT,
  200. WCD_MBHC_ADC_MODE,
  201. WCD_MBHC_DETECTION_DONE,
  202. WCD_MBHC_ELECT_ISRC_EN,
  203. WCD_MBHC_REG_FUNC_MAX,
  204. };
  205. enum wcd_mbhc_plug_type {
  206. MBHC_PLUG_TYPE_INVALID = -1,
  207. MBHC_PLUG_TYPE_NONE,
  208. MBHC_PLUG_TYPE_HEADSET,
  209. MBHC_PLUG_TYPE_HEADPHONE,
  210. MBHC_PLUG_TYPE_HIGH_HPH,
  211. MBHC_PLUG_TYPE_GND_MIC_SWAP,
  212. MBHC_PLUG_TYPE_ANC_HEADPHONE,
  213. };
  214. enum pa_dac_ack_flags {
  215. WCD_MBHC_HPHL_PA_OFF_ACK = 0,
  216. WCD_MBHC_HPHR_PA_OFF_ACK,
  217. };
  218. enum anc_ack_flags {
  219. WCD_MBHC_ANC0_OFF_ACK = 0,
  220. WCD_MBHC_ANC1_OFF_ACK,
  221. };
  222. enum wcd_mbhc_btn_det_mem {
  223. WCD_MBHC_BTN_DET_V_BTN_LOW,
  224. WCD_MBHC_BTN_DET_V_BTN_HIGH
  225. };
  226. enum {
  227. MIC_BIAS_1 = 1,
  228. MIC_BIAS_2,
  229. MIC_BIAS_3,
  230. MIC_BIAS_4
  231. };
  232. enum {
  233. MICB_PULLUP_ENABLE,
  234. MICB_PULLUP_DISABLE,
  235. MICB_ENABLE,
  236. MICB_DISABLE,
  237. };
  238. enum {
  239. MBHC_COMMON_MICB_PRECHARGE,
  240. MBHC_COMMON_MICB_SET_VAL,
  241. MBHC_COMMON_MICB_TAIL_CURR,
  242. };
  243. enum wcd_notify_event {
  244. WCD_EVENT_INVALID,
  245. /* events for micbias ON and OFF */
  246. WCD_EVENT_PRE_MICBIAS_2_OFF,
  247. WCD_EVENT_POST_MICBIAS_2_OFF,
  248. WCD_EVENT_PRE_MICBIAS_2_ON,
  249. WCD_EVENT_POST_MICBIAS_2_ON,
  250. WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF,
  251. WCD_EVENT_POST_DAPM_MICBIAS_2_OFF,
  252. WCD_EVENT_PRE_DAPM_MICBIAS_2_ON,
  253. WCD_EVENT_POST_DAPM_MICBIAS_2_ON,
  254. /* events for PA ON and OFF */
  255. WCD_EVENT_PRE_HPHL_PA_ON,
  256. WCD_EVENT_POST_HPHL_PA_OFF,
  257. WCD_EVENT_PRE_HPHR_PA_ON,
  258. WCD_EVENT_POST_HPHR_PA_OFF,
  259. WCD_EVENT_PRE_HPHL_PA_OFF,
  260. WCD_EVENT_PRE_HPHR_PA_OFF,
  261. WCD_EVENT_OCP_OFF,
  262. WCD_EVENT_OCP_ON,
  263. WCD_EVENT_LAST,
  264. };
  265. enum wcd_mbhc_event_state {
  266. WCD_MBHC_EVENT_PA_HPHL,
  267. WCD_MBHC_EVENT_PA_HPHR,
  268. };
  269. struct wcd_mbhc_general_cfg {
  270. u8 t_ldoh;
  271. u8 t_bg_fast_settle;
  272. u8 t_shutdown_plug_rem;
  273. u8 mbhc_nsa;
  274. u8 mbhc_navg;
  275. u8 v_micbias_l;
  276. u8 v_micbias;
  277. u8 mbhc_reserved;
  278. u16 settle_wait;
  279. u16 t_micbias_rampup;
  280. u16 t_micbias_rampdown;
  281. u16 t_supply_bringup;
  282. } __packed;
  283. struct wcd_mbhc_plug_detect_cfg {
  284. u32 mic_current;
  285. u32 hph_current;
  286. u16 t_mic_pid;
  287. u16 t_ins_complete;
  288. u16 t_ins_retry;
  289. u16 v_removal_delta;
  290. u8 micbias_slow_ramp;
  291. u8 reserved0;
  292. u8 reserved1;
  293. u8 reserved2;
  294. } __packed;
  295. struct wcd_mbhc_plug_type_cfg {
  296. u8 av_detect;
  297. u8 mono_detect;
  298. u8 num_ins_tries;
  299. u8 reserved0;
  300. s16 v_no_mic;
  301. s16 v_av_min;
  302. s16 v_av_max;
  303. s16 v_hs_min;
  304. s16 v_hs_max;
  305. u16 reserved1;
  306. } __packed;
  307. struct wcd_mbhc_btn_detect_cfg {
  308. s8 c[8];
  309. u8 nc;
  310. u8 n_meas;
  311. u8 mbhc_nsc;
  312. u8 n_btn_meas;
  313. u8 n_btn_con;
  314. u8 num_btn;
  315. u8 reserved0;
  316. u8 reserved1;
  317. u16 t_poll;
  318. u16 t_bounce_wait;
  319. u16 t_rel_timeout;
  320. s16 v_btn_press_delta_sta;
  321. s16 v_btn_press_delta_cic;
  322. u16 t_btn0_timeout;
  323. s16 _v_btn_low[0]; /* v_btn_low[num_btn] */
  324. s16 _v_btn_high[0]; /* v_btn_high[num_btn] */
  325. u8 _n_ready[2];
  326. u8 _n_cic[2];
  327. u8 _gain[2];
  328. } __packed;
  329. struct wcd_mbhc_imped_detect_cfg {
  330. u8 _hs_imped_detect;
  331. u8 _n_rload;
  332. u8 _hph_keep_on;
  333. u8 _repeat_rload_calc;
  334. u16 _t_dac_ramp_time;
  335. u16 _rhph_high;
  336. u16 _rhph_low;
  337. u16 _rload[0]; /* rload[n_rload] */
  338. u16 _alpha[0]; /* alpha[n_rload] */
  339. u16 _beta[3];
  340. } __packed;
  341. enum wcd_mbhc_hph_type {
  342. WCD_MBHC_HPH_NONE = 0,
  343. WCD_MBHC_HPH_MONO,
  344. WCD_MBHC_HPH_STEREO,
  345. };
  346. /*
  347. * These enum definitions are directly mapped to the register
  348. * definitions
  349. */
  350. enum mbhc_moisture_vref {
  351. V_OFF,
  352. V_45_MV,
  353. V_100_MV,
  354. V_225_MV,
  355. };
  356. enum mbhc_hs_pullup_iref {
  357. I_DEFAULT = -1,
  358. I_OFF = 0,
  359. I_1P0_UA,
  360. I_2P0_UA,
  361. I_3P0_UA,
  362. };
  363. enum mbhc_hs_pullup_iref_v2 {
  364. HS_PULLUP_I_DEFAULT = -1,
  365. HS_PULLUP_I_3P0_UA = 0,
  366. HS_PULLUP_I_2P25_UA,
  367. HS_PULLUP_I_1P5_UA,
  368. HS_PULLUP_I_0P75_UA,
  369. HS_PULLUP_I_1P125_UA = 0x05,
  370. HS_PULLUP_I_0P375_UA = 0x07,
  371. HS_PULLUP_I_2P0_UA,
  372. HS_PULLUP_I_1P0_UA = 0x0A,
  373. HS_PULLUP_I_0P5_UA,
  374. HS_PULLUP_I_0P25_UA = 0x0F,
  375. HS_PULLUP_I_0P125_UA = 0x17,
  376. HS_PULLUP_I_OFF,
  377. };
  378. enum mbhc_moisture_rref {
  379. R_OFF,
  380. R_24_KOHM,
  381. R_84_KOHM,
  382. R_184_KOHM,
  383. };
  384. struct usbc_ana_audio_config {
  385. int usbc_en1_gpio;
  386. int usbc_en2_gpio;
  387. int usbc_force_gpio;
  388. struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */
  389. struct device_node *usbc_en2_gpio_p; /* used by pinctrl API */
  390. struct device_node *usbc_force_gpio_p; /* used by pinctrl API */
  391. };
  392. struct wcd_mbhc_config {
  393. bool read_fw_bin;
  394. void *calibration;
  395. bool detect_extn_cable;
  396. bool mono_stero_detection;
  397. bool (*swap_gnd_mic)(struct snd_soc_codec *codec, bool active);
  398. bool hs_ext_micbias;
  399. bool gnd_det_en;
  400. int key_code[WCD_MBHC_KEYCODE_NUM];
  401. uint32_t linein_th;
  402. bool moisture_en;
  403. int mbhc_micbias;
  404. int anc_micbias;
  405. bool enable_anc_mic_detect;
  406. u32 enable_usbc_analog;
  407. struct usbc_ana_audio_config usbc_analog_cfg;
  408. };
  409. struct wcd_mbhc_intr {
  410. int mbhc_sw_intr;
  411. int mbhc_btn_press_intr;
  412. int mbhc_btn_release_intr;
  413. int mbhc_hs_ins_intr;
  414. int mbhc_hs_rem_intr;
  415. int hph_left_ocp;
  416. int hph_right_ocp;
  417. };
  418. struct wcd_mbhc_register {
  419. const char *id;
  420. u16 reg;
  421. u8 mask;
  422. u8 offset;
  423. u8 invert;
  424. };
  425. struct wcd_mbhc_cb {
  426. int (*enable_mb_source)(struct wcd_mbhc *, bool);
  427. void (*trim_btn_reg)(struct snd_soc_codec *);
  428. void (*compute_impedance)(struct wcd_mbhc *, uint32_t *, uint32_t *);
  429. void (*set_micbias_value)(struct snd_soc_codec *);
  430. void (*set_auto_zeroing)(struct snd_soc_codec *, bool);
  431. struct firmware_cal * (*get_hwdep_fw_cal)(struct wcd_mbhc *,
  432. enum wcd_cal_type);
  433. void (*set_cap_mode)(struct snd_soc_codec *, bool, bool);
  434. int (*register_notifier)(struct wcd_mbhc *,
  435. struct notifier_block *nblock,
  436. bool enable);
  437. int (*request_irq)(struct snd_soc_codec *,
  438. int, irq_handler_t, const char *, void *);
  439. void (*irq_control)(struct snd_soc_codec *,
  440. int irq, bool enable);
  441. int (*free_irq)(struct snd_soc_codec *,
  442. int irq, void *);
  443. void (*clk_setup)(struct snd_soc_codec *, bool);
  444. int (*map_btn_code_to_num)(struct snd_soc_codec *);
  445. bool (*lock_sleep)(struct wcd_mbhc *, bool);
  446. bool (*micbias_enable_status)(struct wcd_mbhc *, int);
  447. void (*mbhc_bias)(struct snd_soc_codec *, bool);
  448. void (*mbhc_common_micb_ctrl)(struct snd_soc_codec *,
  449. int event, bool);
  450. void (*micb_internal)(struct snd_soc_codec *,
  451. int micb_num, bool);
  452. bool (*hph_pa_on_status)(struct snd_soc_codec *);
  453. void (*set_btn_thr)(struct snd_soc_codec *, s16 *, s16 *,
  454. int num_btn, bool);
  455. void (*hph_pull_up_control)(struct snd_soc_codec *,
  456. enum mbhc_hs_pullup_iref);
  457. int (*mbhc_micbias_control)(struct snd_soc_codec *, int, int req);
  458. void (*mbhc_micb_ramp_control)(struct snd_soc_codec *, bool);
  459. void (*skip_imped_detect)(struct snd_soc_codec *);
  460. bool (*extn_use_mb)(struct snd_soc_codec *);
  461. int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_codec *, int, bool);
  462. void (*mbhc_gnd_det_ctrl)(struct snd_soc_codec *, bool);
  463. void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool);
  464. void (*mbhc_moisture_config)(struct wcd_mbhc *);
  465. bool (*hph_register_recovery)(struct wcd_mbhc *);
  466. void (*update_anc_state)(struct snd_soc_codec *codec,
  467. bool enable, int anc_num);
  468. bool (*is_anc_on)(struct wcd_mbhc *mbhc);
  469. void (*hph_pull_up_control_v2)(struct snd_soc_codec *, int);
  470. };
  471. struct wcd_mbhc_fn {
  472. irqreturn_t (*wcd_mbhc_hs_ins_irq)(int irq, void *data);
  473. irqreturn_t (*wcd_mbhc_hs_rem_irq)(int irq, void *data);
  474. void (*wcd_mbhc_detect_plug_type)(struct wcd_mbhc *mbhc);
  475. bool (*wcd_mbhc_detect_anc_plug_type)(struct wcd_mbhc *mbhc);
  476. void (*wcd_cancel_hs_detect_plug)(struct wcd_mbhc *mbhc,
  477. struct work_struct *work);
  478. };
  479. struct wcd_mbhc {
  480. /* Delayed work to report long button press */
  481. struct delayed_work mbhc_btn_dwork;
  482. int buttons_pressed;
  483. struct wcd_mbhc_config *mbhc_cfg;
  484. const struct wcd_mbhc_cb *mbhc_cb;
  485. u32 hph_status; /* track headhpone status */
  486. u8 hphlocp_cnt; /* headphone left ocp retry */
  487. u8 hphrocp_cnt; /* headphone right ocp retry */
  488. wait_queue_head_t wait_btn_press;
  489. bool is_btn_press;
  490. u8 current_plug;
  491. bool in_swch_irq_handler;
  492. bool hphl_swh; /*track HPHL switch NC / NO */
  493. bool gnd_swh; /*track GND switch NC / NO */
  494. u32 hs_thr;
  495. u32 hph_thr;
  496. u32 swap_thr;
  497. u32 moist_vref;
  498. u32 moist_iref;
  499. u32 moist_rref;
  500. u8 micbias1_cap_mode; /* track ext cap setting */
  501. u8 micbias2_cap_mode; /* track ext cap setting */
  502. bool hs_detect_work_stop;
  503. bool micbias_enable;
  504. bool btn_press_intr;
  505. bool is_hs_recording;
  506. bool is_extn_cable;
  507. bool skip_imped_detection;
  508. bool is_btn_already_regd;
  509. bool extn_cable_hph_rem;
  510. struct snd_soc_codec *codec;
  511. /* Work to perform MBHC Firmware Read */
  512. struct delayed_work mbhc_firmware_dwork;
  513. const struct firmware *mbhc_fw;
  514. struct firmware_cal *mbhc_cal;
  515. /* track PA/DAC state to sync with userspace */
  516. unsigned long hph_pa_dac_state;
  517. unsigned long hph_anc_state;
  518. unsigned long event_state;
  519. unsigned long jiffies_atreport;
  520. /* impedance of hphl and hphr */
  521. uint32_t zl, zr;
  522. bool impedance_detect;
  523. /* Holds type of Headset - Mono/Stereo */
  524. enum wcd_mbhc_hph_type hph_type;
  525. struct snd_soc_jack headset_jack;
  526. struct snd_soc_jack button_jack;
  527. struct mutex codec_resource_lock;
  528. /* Holds codec specific interrupt mapping */
  529. const struct wcd_mbhc_intr *intr_ids;
  530. /* Work to correct accessory type */
  531. struct work_struct correct_plug_swch;
  532. struct notifier_block nblock;
  533. struct wcd_mbhc_register *wcd_mbhc_regs;
  534. struct completion btn_press_compl;
  535. struct mutex hphl_pa_lock;
  536. struct mutex hphr_pa_lock;
  537. /* Holds mbhc detection method - ADC/Legacy */
  538. unsigned int mbhc_detection_logic;
  539. unsigned long intr_status;
  540. bool is_hph_ocp_pending;
  541. bool usbc_force_pr_mode;
  542. int usbc_mode;
  543. struct notifier_block psy_nb;
  544. struct power_supply *usb_psy;
  545. struct work_struct usbc_analog_work;
  546. struct wcd_mbhc_fn *mbhc_fn;
  547. bool force_linein;
  548. };
  549. void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc,
  550. enum wcd_mbhc_plug_type plug_type);
  551. void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, bool enable);
  552. void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc);
  553. bool wcd_swch_level_remove(struct wcd_mbhc *mbhc);
  554. void wcd_enable_curr_micbias(const struct wcd_mbhc *mbhc,
  555. const enum wcd_mbhc_cs_mb_en_flag cs_mb_en);
  556. void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc,
  557. struct snd_soc_jack *jack, int status, int mask);
  558. int wcd_cancel_btn_work(struct wcd_mbhc *mbhc);
  559. int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc);
  560. void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
  561. enum snd_jack_types jack_type);
  562. #endif /* __WCD_MBHC_V2_H__ */