wcd9xxx-mbhc.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /* Copyright (c) 2012-2014, 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 __WCD9XXX_MBHC_H__
  13. #define __WCD9XXX_MBHC_H__
  14. #include "wcd9xxx-resmgr.h"
  15. #include "wcdcal-hwdep.h"
  16. #define WCD9XXX_CFILT_FAST_MODE 0x00
  17. #define WCD9XXX_CFILT_SLOW_MODE 0x40
  18. #define WCD9XXX_CFILT_EXT_PRCHG_EN 0x30
  19. #define WCD9XXX_CFILT_EXT_PRCHG_DSBL 0x00
  20. #define WCD9XXX_USLEEP_RANGE_MARGIN_US 100
  21. struct mbhc_micbias_regs {
  22. u16 cfilt_val;
  23. u16 cfilt_ctl;
  24. u16 mbhc_reg;
  25. u16 int_rbias;
  26. u16 ctl_reg;
  27. u8 cfilt_sel;
  28. };
  29. enum mbhc_v_index {
  30. MBHC_V_IDX_CFILT,
  31. MBHC_V_IDX_VDDIO,
  32. MBHC_V_IDX_NUM,
  33. };
  34. enum mbhc_cal_type {
  35. MBHC_CAL_MCLK,
  36. MBHC_CAL_RCO,
  37. MBHC_CAL_NUM,
  38. };
  39. enum mbhc_impedance_detect_stages {
  40. PRE_MEAS,
  41. POST_MEAS,
  42. PA_DISABLE,
  43. };
  44. /* Data used by MBHC */
  45. struct mbhc_internal_cal_data {
  46. u16 dce_z;
  47. u16 dce_nsc_cs_z;
  48. u16 dce_mb;
  49. u16 sta_z;
  50. u16 sta_mb;
  51. u32 t_sta_dce;
  52. u32 t_dce;
  53. u32 t_sta;
  54. u32 micb_mv;
  55. u16 v_ins_hu[MBHC_V_IDX_NUM];
  56. u16 v_ins_h[MBHC_V_IDX_NUM];
  57. u16 v_b1_hu[MBHC_V_IDX_NUM];
  58. u16 v_b1_h[MBHC_V_IDX_NUM];
  59. u16 v_brh[MBHC_V_IDX_NUM];
  60. u16 v_brl;
  61. u16 v_no_mic;
  62. s16 v_inval_ins_low;
  63. s16 v_inval_ins_high;
  64. u16 v_cs_ins_h;
  65. };
  66. enum wcd9xxx_mbhc_plug_type {
  67. PLUG_TYPE_INVALID = -1,
  68. PLUG_TYPE_NONE,
  69. PLUG_TYPE_HEADSET,
  70. PLUG_TYPE_HEADPHONE,
  71. PLUG_TYPE_HIGH_HPH,
  72. PLUG_TYPE_GND_MIC_SWAP,
  73. PLUG_TYPE_ANC_HEADPHONE,
  74. };
  75. enum wcd9xxx_mbhc_micbias_type {
  76. MBHC_PRIMARY_MIC_MB,
  77. MBHC_ANC_MIC_MB,
  78. };
  79. enum wcd9xxx_micbias_num {
  80. MBHC_MICBIAS_INVALID = -1,
  81. MBHC_MICBIAS1,
  82. MBHC_MICBIAS2,
  83. MBHC_MICBIAS3,
  84. MBHC_MICBIAS4,
  85. };
  86. enum hw_jack_type {
  87. FOUR_POLE_JACK = 0,
  88. FIVE_POLE_JACK,
  89. SIX_POLE_JACK,
  90. };
  91. enum wcd9xx_mbhc_micbias_enable_bits {
  92. MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
  93. MBHC_MICBIAS_ENABLE_REGULAR_HEADSET,
  94. };
  95. enum wcd9xx_mbhc_cs_enable_bits {
  96. MBHC_CS_ENABLE_POLLING,
  97. MBHC_CS_ENABLE_INSERTION,
  98. MBHC_CS_ENABLE_REMOVAL,
  99. MBHC_CS_ENABLE_DET_ANC,
  100. };
  101. enum wcd9xxx_mbhc_state {
  102. MBHC_STATE_NONE = -1,
  103. MBHC_STATE_POTENTIAL,
  104. MBHC_STATE_POTENTIAL_RECOVERY,
  105. MBHC_STATE_RELEASE,
  106. };
  107. enum wcd9xxx_mbhc_btn_det_mem {
  108. MBHC_BTN_DET_V_BTN_LOW,
  109. MBHC_BTN_DET_V_BTN_HIGH,
  110. MBHC_BTN_DET_N_READY,
  111. MBHC_BTN_DET_N_CIC,
  112. MBHC_BTN_DET_GAIN
  113. };
  114. enum wcd9xxx_mbhc_clk_freq {
  115. TAIKO_MCLK_12P2MHZ = 0,
  116. TAIKO_MCLK_9P6MHZ,
  117. TAIKO_NUM_CLK_FREQS,
  118. };
  119. enum wcd9xxx_mbhc_event_state {
  120. MBHC_EVENT_PA_HPHL,
  121. MBHC_EVENT_PA_HPHR,
  122. MBHC_EVENT_PRE_TX_1_3_ON,
  123. MBHC_EVENT_POST_TX_1_3_OFF,
  124. };
  125. struct wcd9xxx_mbhc_general_cfg {
  126. u8 t_ldoh;
  127. u8 t_bg_fast_settle;
  128. u8 t_shutdown_plug_rem;
  129. u8 mbhc_nsa;
  130. u8 mbhc_navg;
  131. u8 v_micbias_l;
  132. u8 v_micbias;
  133. u8 mbhc_reserved;
  134. u16 settle_wait;
  135. u16 t_micbias_rampup;
  136. u16 t_micbias_rampdown;
  137. u16 t_supply_bringup;
  138. } __packed;
  139. struct wcd9xxx_mbhc_plug_detect_cfg {
  140. u32 mic_current;
  141. u32 hph_current;
  142. u16 t_mic_pid;
  143. u16 t_ins_complete;
  144. u16 t_ins_retry;
  145. u16 v_removal_delta;
  146. u8 micbias_slow_ramp;
  147. u8 reserved0;
  148. u8 reserved1;
  149. u8 reserved2;
  150. } __packed;
  151. struct wcd9xxx_mbhc_plug_type_cfg {
  152. u8 av_detect;
  153. u8 mono_detect;
  154. u8 num_ins_tries;
  155. u8 reserved0;
  156. s16 v_no_mic;
  157. s16 v_av_min;
  158. s16 v_av_max;
  159. s16 v_hs_min;
  160. s16 v_hs_max;
  161. u16 reserved1;
  162. } __packed;
  163. struct wcd9xxx_mbhc_btn_detect_cfg {
  164. s8 c[8];
  165. u8 nc;
  166. u8 n_meas;
  167. u8 mbhc_nsc;
  168. u8 n_btn_meas;
  169. u8 n_btn_con;
  170. u8 num_btn;
  171. u8 reserved0;
  172. u8 reserved1;
  173. u16 t_poll;
  174. u16 t_bounce_wait;
  175. u16 t_rel_timeout;
  176. s16 v_btn_press_delta_sta;
  177. s16 v_btn_press_delta_cic;
  178. u16 t_btn0_timeout;
  179. s16 _v_btn_low[0]; /* v_btn_low[num_btn] */
  180. s16 _v_btn_high[0]; /* v_btn_high[num_btn] */
  181. u8 _n_ready[TAIKO_NUM_CLK_FREQS];
  182. u8 _n_cic[TAIKO_NUM_CLK_FREQS];
  183. u8 _gain[TAIKO_NUM_CLK_FREQS];
  184. } __packed;
  185. struct wcd9xxx_mbhc_imped_detect_cfg {
  186. u8 _hs_imped_detect;
  187. u8 _n_rload;
  188. u8 _hph_keep_on;
  189. u8 _repeat_rload_calc;
  190. u16 _t_dac_ramp_time;
  191. u16 _rhph_high;
  192. u16 _rhph_low;
  193. u16 _rload[0]; /* rload[n_rload] */
  194. u16 _alpha[0]; /* alpha[n_rload] */
  195. u16 _beta[3];
  196. } __packed;
  197. struct wcd9xxx_mbhc_config {
  198. bool read_fw_bin;
  199. /*
  200. * void* calibration contains:
  201. * struct wcd9xxx_mbhc_general_cfg generic;
  202. * struct wcd9xxx_mbhc_plug_detect_cfg plug_det;
  203. * struct wcd9xxx_mbhc_plug_type_cfg plug_type;
  204. * struct wcd9xxx_mbhc_btn_detect_cfg btn_det;
  205. * struct wcd9xxx_mbhc_imped_detect_cfg imped_det;
  206. * Note: various size depends on btn_det->num_btn
  207. */
  208. void *calibration;
  209. enum wcd9xxx_micbias_num micbias;
  210. enum wcd9xxx_micbias_num anc_micbias;
  211. int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
  212. unsigned int mclk_rate;
  213. unsigned int gpio;
  214. unsigned int gpio_irq;
  215. int gpio_level_insert;
  216. bool insert_detect; /* codec has own MBHC_INSERT_DETECT */
  217. bool detect_extn_cable;
  218. /* bit mask of enum wcd9xx_mbhc_micbias_enable_bits */
  219. unsigned long micbias_enable_flags;
  220. /* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
  221. bool (*swap_gnd_mic) (struct snd_soc_codec *);
  222. unsigned long cs_enable_flags;
  223. bool use_int_rbias;
  224. bool do_recalibration;
  225. bool use_vddio_meas;
  226. bool enable_anc_mic_detect;
  227. enum hw_jack_type hw_jack_type;
  228. };
  229. struct wcd9xxx_cfilt_mode {
  230. u8 reg_mode_val;
  231. u8 cur_mode_val;
  232. u8 reg_mask;
  233. };
  234. struct wcd9xxx_mbhc_intr {
  235. int poll_plug_rem;
  236. int shortavg_complete;
  237. int potential_button_press;
  238. int button_release;
  239. int dce_est_complete;
  240. int insertion;
  241. int hph_left_ocp;
  242. int hph_right_ocp;
  243. int hs_jack_switch;
  244. };
  245. struct wcd9xxx_mbhc_cb {
  246. void (*enable_mux_bias_block) (struct snd_soc_codec *);
  247. void (*cfilt_fast_mode) (struct snd_soc_codec *, struct wcd9xxx_mbhc *);
  248. void (*codec_specific_cal) (struct snd_soc_codec *,
  249. struct wcd9xxx_mbhc *);
  250. struct wcd9xxx_cfilt_mode (*switch_cfilt_mode) (struct wcd9xxx_mbhc *,
  251. bool);
  252. void (*select_cfilt) (struct snd_soc_codec *, struct wcd9xxx_mbhc *);
  253. enum wcd9xxx_cdc_type (*get_cdc_type) (void);
  254. void (*enable_clock_gate) (struct snd_soc_codec *, bool);
  255. int (*setup_zdet) (struct wcd9xxx_mbhc *,
  256. enum mbhc_impedance_detect_stages stage);
  257. void (*compute_impedance) (s16 *, s16 *, uint32_t *, uint32_t *);
  258. void (*enable_mbhc_txfe) (struct snd_soc_codec *, bool);
  259. int (*enable_mb_source) (struct snd_soc_codec *, bool, bool);
  260. void (*setup_int_rbias) (struct snd_soc_codec *, bool);
  261. void (*pull_mb_to_vddio) (struct snd_soc_codec *, bool);
  262. struct firmware_cal * (*get_hwdep_fw_cal) (struct snd_soc_codec *,
  263. enum wcd_cal_type);
  264. };
  265. struct wcd9xxx_mbhc {
  266. bool polling_active;
  267. /* Delayed work to report long button press */
  268. struct delayed_work mbhc_btn_dwork;
  269. int buttons_pressed;
  270. enum wcd9xxx_mbhc_state mbhc_state;
  271. struct wcd9xxx_mbhc_config *mbhc_cfg;
  272. const struct wcd9xxx_mbhc_cb *mbhc_cb;
  273. struct mbhc_internal_cal_data mbhc_data;
  274. struct mbhc_micbias_regs mbhc_bias_regs;
  275. struct mbhc_micbias_regs mbhc_anc_bias_regs;
  276. bool mbhc_micbias_switched;
  277. u32 hph_status; /* track headhpone status */
  278. u8 hphlocp_cnt; /* headphone left ocp retry */
  279. u8 hphrocp_cnt; /* headphone right ocp retry */
  280. /* Work to perform MBHC Firmware Read */
  281. struct delayed_work mbhc_firmware_dwork;
  282. const struct firmware *mbhc_fw;
  283. struct delayed_work mbhc_insert_dwork;
  284. struct firmware_cal *mbhc_cal;
  285. u8 current_plug;
  286. struct work_struct correct_plug_swch;
  287. /*
  288. * Work to perform polling on microphone voltage
  289. * in order to correct plug type once plug type
  290. * is detected as headphone
  291. */
  292. struct work_struct correct_plug_noswch;
  293. bool hs_detect_work_stop;
  294. bool lpi_enabled; /* low power insertion detection */
  295. bool in_swch_irq_handler;
  296. struct wcd9xxx_resmgr *resmgr;
  297. struct snd_soc_codec *codec;
  298. bool no_mic_headset_override;
  299. /* track PA/DAC state to sync with userspace */
  300. unsigned long hph_pa_dac_state;
  301. /*
  302. * save codec's state with resmgr event notification
  303. * bit flags of enum wcd9xxx_mbhc_event_state
  304. */
  305. unsigned long event_state;
  306. unsigned long mbhc_last_resume; /* in jiffies */
  307. bool insert_detect_level_insert;
  308. struct snd_soc_jack headset_jack;
  309. struct snd_soc_jack button_jack;
  310. struct notifier_block nblock;
  311. bool micbias_enable;
  312. int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
  313. enum wcd9xxx_micbias_num);
  314. bool impedance_detect;
  315. /* impedance of hphl and hphr */
  316. uint32_t zl, zr;
  317. u32 rco_clk_rate;
  318. bool update_z;
  319. u8 scaling_mux_in;
  320. /* Holds codec specific interrupt mapping */
  321. const struct wcd9xxx_mbhc_intr *intr_ids;
  322. #ifdef CONFIG_DEBUG_FS
  323. struct dentry *debugfs_poke;
  324. struct dentry *debugfs_mbhc;
  325. #endif
  326. struct mutex mbhc_lock;
  327. };
  328. #define WCD9XXX_MBHC_CAL_SIZE(buttons, rload) ( \
  329. sizeof(enum wcd9xxx_micbias_num) + \
  330. sizeof(struct wcd9xxx_mbhc_general_cfg) + \
  331. sizeof(struct wcd9xxx_mbhc_plug_detect_cfg) + \
  332. ((sizeof(s16) + sizeof(s16)) * buttons) + \
  333. sizeof(struct wcd9xxx_mbhc_plug_type_cfg) + \
  334. sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
  335. sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
  336. ((sizeof(u16) + sizeof(u16)) * rload) \
  337. )
  338. #define WCD9XXX_MBHC_CAL_GENERAL_PTR(cali) ( \
  339. (struct wcd9xxx_mbhc_general_cfg *) cali)
  340. #define WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali) ( \
  341. (struct wcd9xxx_mbhc_plug_detect_cfg *) \
  342. &(WCD9XXX_MBHC_CAL_GENERAL_PTR(cali)[1]))
  343. #define WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \
  344. (struct wcd9xxx_mbhc_plug_type_cfg *) \
  345. &(WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali)[1]))
  346. #define WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali) ( \
  347. (struct wcd9xxx_mbhc_btn_detect_cfg *) \
  348. &(WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali)[1]))
  349. #define WCD9XXX_MBHC_CAL_IMPED_DET_PTR(cali) ( \
  350. (struct wcd9xxx_mbhc_imped_detect_cfg *) \
  351. (((void *)&WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \
  352. (WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \
  353. (sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \
  354. sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
  355. )
  356. /* minimum size of calibration data assuming there is only one button and
  357. * one rload.
  358. */
  359. #define WCD9XXX_MBHC_CAL_MIN_SIZE ( \
  360. sizeof(struct wcd9xxx_mbhc_general_cfg) + \
  361. sizeof(struct wcd9xxx_mbhc_plug_detect_cfg) + \
  362. sizeof(struct wcd9xxx_mbhc_plug_type_cfg) + \
  363. sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
  364. sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
  365. (sizeof(u16) * 2) \
  366. )
  367. #define WCD9XXX_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
  368. sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
  369. (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
  370. sizeof(cfg_ptr->_v_btn_high[0]))))
  371. #define WCD9XXX_MBHC_CAL_IMPED_MIN_SZ ( \
  372. sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + sizeof(u16) * 2)
  373. #define WCD9XXX_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
  374. sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
  375. (cfg_ptr->_n_rload * \
  376. (sizeof(cfg_ptr->_rload[0]) + sizeof(cfg_ptr->_alpha[0]))))
  377. int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc,
  378. struct wcd9xxx_mbhc_config *mbhc_cfg);
  379. void wcd9xxx_mbhc_stop(struct wcd9xxx_mbhc *mbhc);
  380. int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
  381. struct snd_soc_codec *codec,
  382. int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
  383. enum wcd9xxx_micbias_num),
  384. const struct wcd9xxx_mbhc_cb *mbhc_cb,
  385. const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
  386. int rco_clk_rate,
  387. bool impedance_det_en);
  388. void wcd9xxx_mbhc_deinit(struct wcd9xxx_mbhc *mbhc);
  389. void *wcd9xxx_mbhc_cal_btn_det_mp(
  390. const struct wcd9xxx_mbhc_btn_detect_cfg *btn_det,
  391. const enum wcd9xxx_mbhc_btn_det_mem mem);
  392. int wcd9xxx_mbhc_get_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
  393. uint32_t *zr);
  394. #endif /* __WCD9XXX_MBHC_H__ */