blob: 300e34e993b89157bb37e08c97765d94ab023790 [file] [log] [blame]
Simmi Pateriya0a44d842013-04-03 01:12:42 +05301/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Joonwoo Parka8890262012-10-15 12:04:27 -07002 *
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
15#include "wcd9xxx-resmgr.h"
16
17#define WCD9XXX_CFILT_FAST_MODE 0x00
18#define WCD9XXX_CFILT_SLOW_MODE 0x40
Simmi Pateriya0a44d842013-04-03 01:12:42 +053019#define WCD9XXX_CFILT_EXT_PRCHG_EN 0x70
20#define WCD9XXX_CFILT_EXT_PRCHG_DSBL 0x40
Joonwoo Parka8890262012-10-15 12:04:27 -070021
22struct mbhc_micbias_regs {
23 u16 cfilt_val;
24 u16 cfilt_ctl;
25 u16 mbhc_reg;
26 u16 int_rbias;
27 u16 ctl_reg;
28 u8 cfilt_sel;
29};
30
31/* Data used by MBHC */
32struct mbhc_internal_cal_data {
33 u16 dce_z;
34 u16 dce_mb;
35 u16 sta_z;
36 u16 sta_mb;
37 u32 t_sta_dce;
38 u32 t_dce;
39 u32 t_sta;
40 u32 micb_mv;
41 u16 v_ins_hu;
42 u16 v_ins_h;
43 u16 v_b1_hu;
44 u16 v_b1_h;
45 u16 v_b1_huc;
46 u16 v_brh;
47 u16 v_brl;
48 u16 v_no_mic;
49 s16 adj_v_hs_max;
50 u16 adj_v_ins_hu;
51 u16 adj_v_ins_h;
52 s16 v_inval_ins_low;
53 s16 v_inval_ins_high;
54};
55
Simmi Pateriya0a44d842013-04-03 01:12:42 +053056enum wcd9xxx_mbhc_version {
57 WCD9XXX_MBHC_VERSION_UNKNOWN = 0,
58 WCD9XXX_MBHC_VERSION_TAIKO,
59 WCD9XXX_MBHC_VERSION_TAPAN,
60};
61
Joonwoo Parka8890262012-10-15 12:04:27 -070062enum wcd9xxx_mbhc_plug_type {
63 PLUG_TYPE_INVALID = -1,
64 PLUG_TYPE_NONE,
65 PLUG_TYPE_HEADSET,
66 PLUG_TYPE_HEADPHONE,
67 PLUG_TYPE_HIGH_HPH,
68 PLUG_TYPE_GND_MIC_SWAP,
69};
70
71enum wcd9xxx_micbias_num {
72 MBHC_MICBIAS_INVALID = -1,
73 MBHC_MICBIAS1,
74 MBHC_MICBIAS2,
75 MBHC_MICBIAS3,
76 MBHC_MICBIAS4,
77};
78
79enum wcd9xxx_mbhc_state {
80 MBHC_STATE_NONE = -1,
81 MBHC_STATE_POTENTIAL,
82 MBHC_STATE_POTENTIAL_RECOVERY,
83 MBHC_STATE_RELEASE,
84};
85
86enum wcd9xxx_mbhc_btn_det_mem {
87 MBHC_BTN_DET_V_BTN_LOW,
88 MBHC_BTN_DET_V_BTN_HIGH,
89 MBHC_BTN_DET_N_READY,
90 MBHC_BTN_DET_N_CIC,
91 MBHC_BTN_DET_GAIN
92};
93
94enum wcd9xxx_mbhc_clk_freq {
95 TAIKO_MCLK_12P2MHZ = 0,
96 TAIKO_MCLK_9P6MHZ,
97 TAIKO_NUM_CLK_FREQS,
98};
99
100struct wcd9xxx_mbhc_general_cfg {
101 u8 t_ldoh;
102 u8 t_bg_fast_settle;
103 u8 t_shutdown_plug_rem;
104 u8 mbhc_nsa;
105 u8 mbhc_navg;
106 u8 v_micbias_l;
107 u8 v_micbias;
108 u8 mbhc_reserved;
109 u16 settle_wait;
110 u16 t_micbias_rampup;
111 u16 t_micbias_rampdown;
112 u16 t_supply_bringup;
113} __packed;
114
115struct wcd9xxx_mbhc_plug_detect_cfg {
116 u32 mic_current;
117 u32 hph_current;
118 u16 t_mic_pid;
119 u16 t_ins_complete;
120 u16 t_ins_retry;
121 u16 v_removal_delta;
122 u8 micbias_slow_ramp;
123 u8 reserved0;
124 u8 reserved1;
125 u8 reserved2;
126} __packed;
127
128struct wcd9xxx_mbhc_plug_type_cfg {
129 u8 av_detect;
130 u8 mono_detect;
131 u8 num_ins_tries;
132 u8 reserved0;
133 s16 v_no_mic;
134 s16 v_av_min;
135 s16 v_av_max;
136 s16 v_hs_min;
137 s16 v_hs_max;
138 u16 reserved1;
139} __packed;
140
141struct wcd9xxx_mbhc_btn_detect_cfg {
142 s8 c[8];
143 u8 nc;
144 u8 n_meas;
145 u8 mbhc_nsc;
146 u8 n_btn_meas;
147 u8 n_btn_con;
148 u8 num_btn;
149 u8 reserved0;
150 u8 reserved1;
151 u16 t_poll;
152 u16 t_bounce_wait;
153 u16 t_rel_timeout;
154 s16 v_btn_press_delta_sta;
155 s16 v_btn_press_delta_cic;
156 u16 t_btn0_timeout;
157 s16 _v_btn_low[0]; /* v_btn_low[num_btn] */
158 s16 _v_btn_high[0]; /* v_btn_high[num_btn] */
159 u8 _n_ready[TAIKO_NUM_CLK_FREQS];
160 u8 _n_cic[TAIKO_NUM_CLK_FREQS];
161 u8 _gain[TAIKO_NUM_CLK_FREQS];
162} __packed;
163
164struct wcd9xxx_mbhc_imped_detect_cfg {
165 u8 _hs_imped_detect;
166 u8 _n_rload;
167 u8 _hph_keep_on;
168 u8 _repeat_rload_calc;
169 u16 _t_dac_ramp_time;
170 u16 _rhph_high;
171 u16 _rhph_low;
172 u16 _rload[0]; /* rload[n_rload] */
173 u16 _alpha[0]; /* alpha[n_rload] */
174 u16 _beta[3];
175} __packed;
176
177struct wcd9xxx_mbhc_config {
178 bool read_fw_bin;
179 /*
180 * void* calibration contains:
181 * struct wcd9xxx_mbhc_general_cfg generic;
182 * struct wcd9xxx_mbhc_plug_detect_cfg plug_det;
183 * struct wcd9xxx_mbhc_plug_type_cfg plug_type;
184 * struct wcd9xxx_mbhc_btn_detect_cfg btn_det;
185 * struct wcd9xxx_mbhc_imped_detect_cfg imped_det;
186 * Note: various size depends on btn_det->num_btn
187 */
188 void *calibration;
189 enum wcd9xxx_micbias_num micbias;
190 int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
191 unsigned int mclk_rate;
192 unsigned int gpio;
193 unsigned int gpio_irq;
194 int gpio_level_insert;
195 bool insert_detect; /* codec has own MBHC_INSERT_DETECT */
Joonwoo Park80a01172012-10-15 16:05:23 -0700196 bool detect_extn_cable;
Joonwoo Parka8890262012-10-15 12:04:27 -0700197 /* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
198 bool (*swap_gnd_mic) (struct snd_soc_codec *);
199};
200
201struct wcd9xxx_mbhc {
202 bool polling_active;
203 /* Delayed work to report long button press */
204 struct delayed_work mbhc_btn_dwork;
205 int buttons_pressed;
206 enum wcd9xxx_mbhc_state mbhc_state;
207 struct wcd9xxx_mbhc_config *mbhc_cfg;
208
209 struct mbhc_internal_cal_data mbhc_data;
210
211 struct mbhc_micbias_regs mbhc_bias_regs;
212 bool mbhc_micbias_switched;
213
214 u32 hph_status; /* track headhpone status */
215 u8 hphlocp_cnt; /* headphone left ocp retry */
216 u8 hphrocp_cnt; /* headphone right ocp retry */
217
218 /* Work to perform MBHC Firmware Read */
219 struct delayed_work mbhc_firmware_dwork;
220 const struct firmware *mbhc_fw;
221
222 struct delayed_work mbhc_insert_dwork;
223
224 u8 current_plug;
225 struct work_struct correct_plug_swch;
226 /*
227 * Work to perform polling on microphone voltage
228 * in order to correct plug type once plug type
229 * is detected as headphone
230 */
231 struct work_struct correct_plug_noswch;
232 bool hs_detect_work_stop;
233
234 bool lpi_enabled; /* low power insertion detection */
235 bool in_swch_irq_handler;
236
237 struct wcd9xxx_resmgr *resmgr;
238 struct snd_soc_codec *codec;
239
240 bool no_mic_headset_override;
241
242 /* track PA/DAC state */
243 unsigned long hph_pa_dac_state;
244
245 unsigned long mbhc_last_resume; /* in jiffies */
246
247 bool insert_detect_level_insert;
248
249 struct snd_soc_jack headset_jack;
250 struct snd_soc_jack button_jack;
251
252 struct notifier_block nblock;
253
Simmi Pateriya0a44d842013-04-03 01:12:42 +0530254 enum wcd9xxx_mbhc_version mbhc_version;
255
Joonwoo Parka8890262012-10-15 12:04:27 -0700256#ifdef CONFIG_DEBUG_FS
257 struct dentry *debugfs_poke;
258 struct dentry *debugfs_mbhc;
259#endif
260};
261
262#define WCD9XXX_MBHC_CAL_SIZE(buttons, rload) ( \
263 sizeof(enum wcd9xxx_micbias_num) + \
264 sizeof(struct wcd9xxx_mbhc_general_cfg) + \
265 sizeof(struct wcd9xxx_mbhc_plug_detect_cfg) + \
266 ((sizeof(s16) + sizeof(s16)) * buttons) + \
267 sizeof(struct wcd9xxx_mbhc_plug_type_cfg) + \
268 sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
269 sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
270 ((sizeof(u16) + sizeof(u16)) * rload) \
271 )
272
273#define WCD9XXX_MBHC_CAL_GENERAL_PTR(cali) ( \
274 (struct wcd9xxx_mbhc_general_cfg *) cali)
275#define WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali) ( \
276 (struct wcd9xxx_mbhc_plug_detect_cfg *) \
277 &(WCD9XXX_MBHC_CAL_GENERAL_PTR(cali)[1]))
278#define WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \
279 (struct wcd9xxx_mbhc_plug_type_cfg *) \
280 &(WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali)[1]))
281#define WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali) ( \
282 (struct wcd9xxx_mbhc_btn_detect_cfg *) \
283 &(WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali)[1]))
284#define WCD9XXX_MBHC_CAL_IMPED_DET_PTR(cali) ( \
285 (struct wcd9xxx_mbhc_imped_detect_cfg *) \
286 (((void *)&WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \
287 (WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \
288 (sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \
289 sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
290 )
291
292/* minimum size of calibration data assuming there is only one button and
293 * one rload.
294 */
295#define WCD9XXX_MBHC_CAL_MIN_SIZE ( \
296 sizeof(struct wcd9xxx_mbhc_general_cfg) + \
297 sizeof(struct wcd9xxx_mbhc_plug_detect_cfg) + \
298 sizeof(struct wcd9xxx_mbhc_plug_type_cfg) + \
299 sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
300 sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
301 (sizeof(u16) * 2) \
302 )
303
304#define WCD9XXX_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
305 sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
306 (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
307 sizeof(cfg_ptr->_v_btn_high[0]))))
308
309#define WCD9XXX_MBHC_CAL_IMPED_MIN_SZ ( \
310 sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + sizeof(u16) * 2)
311
312#define WCD9XXX_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
313 sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
314 (cfg_ptr->_n_rload * \
315 (sizeof(cfg_ptr->_rload[0]) + sizeof(cfg_ptr->_alpha[0]))))
316
317int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc,
318 struct wcd9xxx_mbhc_config *mbhc_cfg);
319int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
Simmi Pateriya0a44d842013-04-03 01:12:42 +0530320 struct snd_soc_codec *codec, int version);
Joonwoo Parka8890262012-10-15 12:04:27 -0700321void wcd9xxx_mbhc_deinit(struct wcd9xxx_mbhc *mbhc);
322void *wcd9xxx_mbhc_cal_btn_det_mp(
323 const struct wcd9xxx_mbhc_btn_detect_cfg *btn_det,
324 const enum wcd9xxx_mbhc_btn_det_mem mem);
325#endif /* __WCD9XXX_MBHC_H__ */