| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 1 | /* Copyright (c) 2012, Code Aurora Forum. 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 |  | 
 | 13 | #include <sound/soc.h> | 
 | 14 | #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> | 
 | 15 |  | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 16 | #define SITAR_NUM_REGISTERS 0x400 | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 17 | #define SITAR_MAX_REGISTER (SITAR_NUM_REGISTERS-1) | 
 | 18 | #define SITAR_CACHE_SIZE SITAR_NUM_REGISTERS | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 19 | #define SITAR_1_X_ONLY_REGISTERS 3 | 
 | 20 | #define SITAR_2_HIGHER_ONLY_REGISTERS 3 | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 21 |  | 
 | 22 | #define SITAR_REG_VAL(reg, val)		{reg, 0, val} | 
 | 23 |  | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 24 | #define DEFAULT_DCE_STA_WAIT 55 | 
 | 25 | #define DEFAULT_DCE_WAIT 60000 | 
 | 26 | #define DEFAULT_STA_WAIT 5000 | 
 | 27 |  | 
 | 28 | #define STA 0 | 
 | 29 | #define DCE 1 | 
 | 30 |  | 
 | 31 | #define SITAR_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ | 
 | 32 | 				SND_JACK_BTN_2 | SND_JACK_BTN_3 | \ | 
 | 33 | 				SND_JACK_BTN_4 | SND_JACK_BTN_5 | \ | 
 | 34 | 				SND_JACK_BTN_6 | SND_JACK_BTN_7) | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 35 |  | 
 | 36 | extern const u8 sitar_reg_readable[SITAR_CACHE_SIZE]; | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 37 | extern const u32 sitar_1_reg_readable[SITAR_1_X_ONLY_REGISTERS]; | 
 | 38 | extern const u32 sitar_2_reg_readable[SITAR_2_HIGHER_ONLY_REGISTERS]; | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 39 | extern const u8 sitar_reg_defaults[SITAR_CACHE_SIZE]; | 
 | 40 |  | 
 | 41 | enum sitar_micbias_num { | 
 | 42 | 	SITAR_MICBIAS1, | 
 | 43 | 	SITAR_MICBIAS2, | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 44 | 	SITAR_MICBIAS3, | 
 | 45 | 	SITAR_MICBIAS4, | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 46 | }; | 
 | 47 |  | 
 | 48 | enum sitar_pid_current { | 
 | 49 | 	SITAR_PID_MIC_2P5_UA, | 
 | 50 | 	SITAR_PID_MIC_5_UA, | 
 | 51 | 	SITAR_PID_MIC_10_UA, | 
 | 52 | 	SITAR_PID_MIC_20_UA, | 
 | 53 | }; | 
 | 54 |  | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 55 | struct sitar_reg_mask_val { | 
 | 56 | 	u16	reg; | 
 | 57 | 	u8	mask; | 
 | 58 | 	u8	val; | 
 | 59 | }; | 
 | 60 |  | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 61 | enum sitar_mbhc_clk_freq { | 
 | 62 | 	SITAR_MCLK_12P2MHZ = 0, | 
 | 63 | 	SITAR_MCLK_9P6MHZ, | 
 | 64 | 	SITAR_NUM_CLK_FREQS, | 
 | 65 | }; | 
 | 66 |  | 
 | 67 | enum sitar_mbhc_analog_pwr_cfg { | 
 | 68 | 	SITAR_ANALOG_PWR_COLLAPSED = 0, | 
 | 69 | 	SITAR_ANALOG_PWR_ON, | 
 | 70 | 	SITAR_NUM_ANALOG_PWR_CONFIGS, | 
 | 71 | }; | 
 | 72 |  | 
 | 73 | enum sitar_mbhc_btn_det_mem { | 
 | 74 | 	SITAR_BTN_DET_V_BTN_LOW, | 
 | 75 | 	SITAR_BTN_DET_V_BTN_HIGH, | 
 | 76 | 	SITAR_BTN_DET_N_READY, | 
 | 77 | 	SITAR_BTN_DET_N_CIC, | 
 | 78 | 	SITAR_BTN_DET_GAIN | 
 | 79 | }; | 
 | 80 |  | 
 | 81 | struct sitar_mbhc_general_cfg { | 
 | 82 | 	u8 t_ldoh; | 
 | 83 | 	u8 t_bg_fast_settle; | 
 | 84 | 	u8 t_shutdown_plug_rem; | 
 | 85 | 	u8 mbhc_nsa; | 
 | 86 | 	u8 mbhc_navg; | 
 | 87 | 	u8 v_micbias_l; | 
 | 88 | 	u8 v_micbias; | 
 | 89 | 	u8 mbhc_reserved; | 
 | 90 | 	u16 settle_wait; | 
 | 91 | 	u16 t_micbias_rampup; | 
 | 92 | 	u16 t_micbias_rampdown; | 
 | 93 | 	u16 t_supply_bringup; | 
 | 94 | } __packed; | 
 | 95 |  | 
 | 96 | struct sitar_mbhc_plug_detect_cfg { | 
 | 97 | 	u32 mic_current; | 
 | 98 | 	u32 hph_current; | 
 | 99 | 	u16 t_mic_pid; | 
 | 100 | 	u16 t_ins_complete; | 
 | 101 | 	u16 t_ins_retry; | 
 | 102 | 	u16 v_removal_delta; | 
 | 103 | 	u8 micbias_slow_ramp; | 
 | 104 | 	u8 reserved0; | 
 | 105 | 	u8 reserved1; | 
 | 106 | 	u8 reserved2; | 
 | 107 | } __packed; | 
 | 108 |  | 
 | 109 | struct sitar_mbhc_plug_type_cfg { | 
 | 110 | 	u8 av_detect; | 
 | 111 | 	u8 mono_detect; | 
 | 112 | 	u8 num_ins_tries; | 
 | 113 | 	u8 reserved0; | 
 | 114 | 	s16 v_no_mic; | 
 | 115 | 	s16 v_av_min; | 
 | 116 | 	s16 v_av_max; | 
 | 117 | 	s16 v_hs_min; | 
 | 118 | 	s16 v_hs_max; | 
 | 119 | 	u16 reserved1; | 
 | 120 | } __packed; | 
 | 121 |  | 
 | 122 |  | 
 | 123 | struct sitar_mbhc_btn_detect_cfg { | 
 | 124 | 	s8 c[8]; | 
 | 125 | 	u8 nc; | 
 | 126 | 	u8 n_meas; | 
 | 127 | 	u8 mbhc_nsc; | 
 | 128 | 	u8 n_btn_meas; | 
 | 129 | 	u8 n_btn_con; | 
 | 130 | 	u8 num_btn; | 
 | 131 | 	u8 reserved0; | 
 | 132 | 	u8 reserved1; | 
 | 133 | 	u16 t_poll; | 
 | 134 | 	u16 t_bounce_wait; | 
 | 135 | 	u16 t_rel_timeout; | 
 | 136 | 	s16 v_btn_press_delta_sta; | 
 | 137 | 	s16 v_btn_press_delta_cic; | 
 | 138 | 	u16 t_btn0_timeout; | 
 | 139 | 	s16 _v_btn_low[0]; /* v_btn_low[num_btn] */ | 
 | 140 | 	s16 _v_btn_high[0]; /* v_btn_high[num_btn] */ | 
 | 141 | 	u8 _n_ready[SITAR_NUM_CLK_FREQS]; | 
 | 142 | 	u8 _n_cic[SITAR_NUM_CLK_FREQS]; | 
 | 143 | 	u8 _gain[SITAR_NUM_CLK_FREQS]; | 
 | 144 | } __packed; | 
 | 145 |  | 
 | 146 | struct sitar_mbhc_imped_detect_cfg { | 
 | 147 | 	u8 _hs_imped_detect; | 
 | 148 | 	u8 _n_rload; | 
 | 149 | 	u8 _hph_keep_on; | 
 | 150 | 	u8 _repeat_rload_calc; | 
 | 151 | 	u16 _t_dac_ramp_time; | 
 | 152 | 	u16 _rhph_high; | 
 | 153 | 	u16 _rhph_low; | 
 | 154 | 	u16 _rload[0]; /* rload[n_rload] */ | 
 | 155 | 	u16 _alpha[0]; /* alpha[n_rload] */ | 
 | 156 | 	u16 _beta[3]; | 
 | 157 | } __packed; | 
 | 158 |  | 
| Bhalchandra Gajare | 466aafe | 2012-05-02 17:55:26 -0700 | [diff] [blame] | 159 | struct sitar_mbhc_config { | 
 | 160 | 	struct snd_soc_jack *headset_jack; | 
 | 161 | 	struct snd_soc_jack *button_jack; | 
 | 162 | 	bool read_fw_bin; | 
 | 163 | 	/* void* calibration contains: | 
 | 164 | 	 *  struct tabla_mbhc_general_cfg generic; | 
 | 165 | 	 *  struct tabla_mbhc_plug_detect_cfg plug_det; | 
 | 166 | 	 *  struct tabla_mbhc_plug_type_cfg plug_type; | 
 | 167 | 	 *  struct tabla_mbhc_btn_detect_cfg btn_det; | 
 | 168 | 	 *  struct tabla_mbhc_imped_detect_cfg imped_det; | 
 | 169 | 	 * Note: various size depends on btn_det->num_btn | 
 | 170 | 	 */ | 
 | 171 | 	void *calibration; | 
 | 172 | 	enum sitar_micbias_num micbias; | 
 | 173 | 	int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool); | 
 | 174 | 	unsigned int mclk_rate; | 
 | 175 | 	unsigned int gpio; | 
 | 176 | 	unsigned int gpio_irq; | 
 | 177 | 	int gpio_level_insert; | 
 | 178 | }; | 
 | 179 |  | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 180 | extern int sitar_hs_detect(struct snd_soc_codec *codec, | 
| Bhalchandra Gajare | 466aafe | 2012-05-02 17:55:26 -0700 | [diff] [blame] | 181 | 			const struct sitar_mbhc_config *cfg); | 
| Asish Bhattacharya | b86c347 | 2012-02-15 08:31:52 +0530 | [diff] [blame] | 182 |  | 
 | 183 | #ifndef anc_header_dec | 
 | 184 | struct anc_header { | 
 | 185 | 	u32 reserved[3]; | 
 | 186 | 	u32 num_anc_slots; | 
 | 187 | }; | 
 | 188 | #define anc_header_dec | 
 | 189 | #endif | 
 | 190 |  | 
| Bhalchandra Gajare | 466aafe | 2012-05-02 17:55:26 -0700 | [diff] [blame] | 191 | extern int sitar_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, | 
 | 192 | 							 bool dapm); | 
| Asish Bhattacharya | f868a1f | 2012-03-05 10:07:44 -0800 | [diff] [blame] | 193 |  | 
 | 194 | extern void *sitar_mbhc_cal_btn_det_mp(const struct sitar_mbhc_btn_detect_cfg | 
 | 195 | 				       *btn_det, | 
 | 196 | 				       const enum sitar_mbhc_btn_det_mem mem); | 
 | 197 |  | 
 | 198 | #define SITAR_MBHC_CAL_SIZE(buttons, rload) ( \ | 
 | 199 | 	sizeof(enum sitar_micbias_num) + \ | 
 | 200 | 	sizeof(struct sitar_mbhc_general_cfg) + \ | 
 | 201 | 	sizeof(struct sitar_mbhc_plug_detect_cfg) + \ | 
 | 202 | 	    ((sizeof(s16) + sizeof(s16)) * buttons) + \ | 
 | 203 | 	sizeof(struct sitar_mbhc_plug_type_cfg) + \ | 
 | 204 | 	sizeof(struct sitar_mbhc_btn_detect_cfg) + \ | 
 | 205 | 	sizeof(struct sitar_mbhc_imped_detect_cfg) + \ | 
 | 206 | 	    ((sizeof(u16) + sizeof(u16)) * rload) \ | 
 | 207 | 	) | 
 | 208 |  | 
 | 209 | #define SITAR_MBHC_CAL_GENERAL_PTR(cali) ( \ | 
 | 210 | 	    (struct sitar_mbhc_general_cfg *) cali) | 
 | 211 | #define SITAR_MBHC_CAL_PLUG_DET_PTR(cali) ( \ | 
 | 212 | 	    (struct sitar_mbhc_plug_detect_cfg *) \ | 
 | 213 | 	    &(SITAR_MBHC_CAL_GENERAL_PTR(cali)[1])) | 
 | 214 | #define SITAR_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \ | 
 | 215 | 	    (struct sitar_mbhc_plug_type_cfg *) \ | 
 | 216 | 	    &(SITAR_MBHC_CAL_PLUG_DET_PTR(cali)[1])) | 
 | 217 | #define SITAR_MBHC_CAL_BTN_DET_PTR(cali) ( \ | 
 | 218 | 	    (struct sitar_mbhc_btn_detect_cfg *) \ | 
 | 219 | 	    &(SITAR_MBHC_CAL_PLUG_TYPE_PTR(cali)[1])) | 
 | 220 | #define SITAR_MBHC_CAL_IMPED_DET_PTR(cali) ( \ | 
 | 221 | 	    (struct sitar_mbhc_imped_detect_cfg *) \ | 
 | 222 | 	    (((void *)&SITAR_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \ | 
 | 223 | 	     (SITAR_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \ | 
 | 224 | 	      (sizeof(SITAR_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \ | 
 | 225 | 	       sizeof(SITAR_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \ | 
 | 226 | 	) | 
 | 227 |  | 
 | 228 | /* minimum size of calibration data assuming there is only one button and | 
 | 229 |  * one rload. | 
 | 230 |  */ | 
 | 231 | #define SITAR_MBHC_CAL_MIN_SIZE ( \ | 
 | 232 | 	sizeof(struct sitar_mbhc_general_cfg) + \ | 
 | 233 | 	sizeof(struct sitar_mbhc_plug_detect_cfg) + \ | 
 | 234 | 	sizeof(struct sitar_mbhc_plug_type_cfg) + \ | 
 | 235 | 	sizeof(struct sitar_mbhc_btn_detect_cfg) + \ | 
 | 236 | 	sizeof(struct sitar_mbhc_imped_detect_cfg) + \ | 
 | 237 | 	(sizeof(u16) * 2)) | 
 | 238 |  | 
 | 239 | #define SITAR_MBHC_CAL_BTN_SZ(cfg_ptr) ( \ | 
 | 240 | 	    sizeof(struct sitar_mbhc_btn_detect_cfg) + \ | 
 | 241 | 	    (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \ | 
 | 242 | 				 sizeof(cfg_ptr->_v_btn_high[0])))) | 
 | 243 |  | 
 | 244 | #define SITAR_MBHC_CAL_IMPED_MIN_SZ ( \ | 
 | 245 | 	    sizeof(struct sitar_mbhc_imped_detect_cfg) + \ | 
 | 246 | 	    sizeof(u16) * 2) | 
 | 247 |  | 
 | 248 | #define SITAR_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \ | 
 | 249 | 	    sizeof(struct sitar_mbhc_imped_detect_cfg) + \ | 
 | 250 | 	    (cfg_ptr->_n_rload * (sizeof(cfg_ptr->_rload[0]) + \ | 
 | 251 | 				 sizeof(cfg_ptr->_alpha[0])))) |