blob: 8e561cfabe79cae9f51e2968afc4391cea11879a [file] [log] [blame]
Kuirong Wang265f3592012-12-05 16:17:41 -08001/* Copyright (c) 2013, 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 MSM8X10_WCD_H
13#define MSM8X10_WCD_H
14
15#include <sound/soc.h>
16#include <sound/jack.h>
17#include "wcd9xxx-mbhc.h"
18#include "wcd9xxx-resmgr.h"
19
20#define MSM8X10_WCD_NUM_REGISTERS 0x600
21#define MSM8X10_WCD_MAX_REGISTER (MSM8X10_WCD_NUM_REGISTERS-1)
22#define MSM8X10_WCD_CACHE_SIZE MSM8X10_WCD_NUM_REGISTERS
23#define MSM8X10_WCD_NUM_IRQ_REGS 3
24#define MAX_REGULATOR 7
25#define MSM8X10_WCD_REG_VAL(reg, val) {reg, 0, val}
Kuirong Wangae340de2013-05-30 18:11:07 -070026#define MSM8X10_DINO_LPASS_AUDIO_CORE_DIG_CODEC_CLK_SEL 0xFE03B004
27#define MSM8X10_DINO_LPASS_DIGCODEC_CMD_RCGR 0xFE02C000
28#define MSM8X10_DINO_LPASS_DIGCODEC_CFG_RCGR 0xFE02C004
29#define MSM8X10_DINO_LPASS_DIGCODEC_M 0xFE02C008
30#define MSM8X10_DINO_LPASS_DIGCODEC_N 0xFE02C00C
31#define MSM8X10_DINO_LPASS_DIGCODEC_D 0xFE02C010
32#define MSM8X10_DINO_LPASS_DIGCODEC_CBCR 0xFE02C014
33#define MSM8X10_DINO_LPASS_DIGCODEC_AHB_CBCR 0xFE02C018
34
Kuirong Wang14b3fb92013-06-27 17:28:17 -070035#define MSM8X10_CODEC_NAME "msm8x10_wcd_codec"
Kuirong Wang265f3592012-12-05 16:17:41 -080036
37#define MSM8X10_WCD_IS_DINO_REG(reg) \
38 (((reg >= 0x400) && (reg <= 0x5FF)) ? 1 : 0)
39#define MSM8X10_WCD_IS_HELICON_REG(reg) \
40 (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0)
41extern const u8 msm8x10_wcd_reg_readable[MSM8X10_WCD_CACHE_SIZE];
42extern const u8 msm8x10_wcd_reset_reg_defaults[MSM8X10_WCD_CACHE_SIZE];
43struct msm8x10_wcd_codec_dai_data {
44 u32 rate;
45 u32 *ch_num;
46 u32 ch_act;
47 u32 ch_tot;
48};
49
50enum msm8x10_wcd_pid_current {
51 MSM8X10_WCD_PID_MIC_2P5_UA,
52 MSM8X10_WCD_PID_MIC_5_UA,
53 MSM8X10_WCD_PID_MIC_10_UA,
54 MSM8X10_WCD_PID_MIC_20_UA,
55};
56
57struct msm8x10_wcd_reg_mask_val {
58 u16 reg;
59 u8 mask;
60 u8 val;
61};
62
63enum msm8x10_wcd_mbhc_analog_pwr_cfg {
64 MSM8X10_WCD_ANALOG_PWR_COLLAPSED = 0,
65 MSM8X10_WCD_ANALOG_PWR_ON,
66 MSM8X10_WCD_NUM_ANALOG_PWR_CONFIGS,
67};
68
69/* Number of input and output Slimbus port */
70enum {
71 MSM8X10_WCD_RX1 = 0,
72 MSM8X10_WCD_RX2,
73 MSM8X10_WCD_RX3,
74 MSM8X10_WCD_RX_MAX,
75};
76
77enum {
78 MSM8X10_WCD_TX1 = 0,
79 MSM8X10_WCD_TX2,
80 MSM8X10_WCD_TX3,
81 MSM8X10_WCD_TX4,
82 MSM8X10_WCD_TX_MAX,
83};
84
85enum {
86 /* INTR_REG 0 */
87 MSM8X10_WCD_IRQ_RESERVED_0 = 0,
88 MSM8X10_WCD_IRQ_MBHC_REMOVAL,
89 MSM8X10_WCD_IRQ_MBHC_SHORT_TERM,
90 MSM8X10_WCD_IRQ_MBHC_PRESS,
91 MSM8X10_WCD_IRQ_MBHC_RELEASE,
92 MSM8X10_WCD_IRQ_MBHC_POTENTIAL,
93 MSM8X10_WCD_IRQ_MBHC_INSERTION,
94 MSM8X10_WCD_IRQ_MBHC_HS_DET,
95 /* INTR_REG 1 */
96 MSM8X10_WCD_IRQ_PA_STARTUP,
97 MSM8X10_WCD_IRQ_BG_PRECHARGE,
98 MSM8X10_WCD_IRQ_RESERVED_1,
99 MSM8X10_WCD_IRQ_EAR_PA_OCPL_FAULT,
100 MSM8X10_WCD_IRQ_EAR_PA_STARTUP,
101 MSM8X10_WCD_IRQ_SPKR_PA_OCPL_FAULT,
102 MSM8X10_WCD_IRQ_SPKR_CLIP_FAULT,
103 MSM8X10_WCD_IRQ_RESERVED_2,
104 /* INTR_REG 2 */
105 MSM8X10_WCD_IRQ_HPH_L_PA_STARTUP,
106 MSM8X10_WCD_IRQ_HPH_R_PA_STARTUP,
107 MSM8X10_WCD_IRQ_HPH_PA_OCPL_FAULT,
108 MSM8X10_WCD_IRQ_HPH_PA_OCPR_FAULT,
109 MSM8X10_WCD_IRQ_RESERVED_3,
110 MSM8X10_WCD_IRQ_RESERVED_4,
111 MSM8X10_WCD_IRQ_RESERVED_5,
112 MSM8X10_WCD_IRQ_RESERVED_6,
113 MSM8X10_WCD_NUM_IRQS,
114};
115
116/*
117 * Each micbias can be assigned to one of three cfilters
118 * Vbatt_min >= .15V + ldoh_v
119 * ldoh_v >= .15v + cfiltx_mv
120 * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv
121 * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv
122 * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv
123 * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv
124 */
125struct msm8x10_wcd_micbias_setting {
126 u8 ldoh_v;
127 u32 cfilt1_mv; /* in mv */
128 /*
129 * Different WCD9xxx series codecs may not
130 * have 4 mic biases. If a codec has fewer
131 * mic biases, some of these properties will
132 * not be used.
133 */
134 u8 bias1_cfilt_sel;
135 u8 bias1_cap_mode;
136};
137
138struct msm8x10_wcd_ocp_setting {
139 unsigned int use_pdata:1; /* 0 - use sys default as recommended */
140 unsigned int num_attempts:4; /* up to 15 attempts */
141 unsigned int run_time:4; /* in duty cycle */
142 unsigned int wait_time:4; /* in duty cycle */
143 unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */
144};
145
146struct msm8x10_wcd_regulator {
147 const char *name;
148 int min_uV;
149 int max_uV;
150 int optimum_uA;
Kuirong Wang49f506a2013-05-22 17:38:26 -0700151 bool ondemand;
Kuirong Wang265f3592012-12-05 16:17:41 -0800152 struct regulator *regulator;
153};
154
155struct msm8x10_wcd_pdata {
156 int irq;
157 int irq_base;
158 int num_irqs;
159 int reset_gpio;
160 void *msm8x10_wcd_ahb_base_vaddr;
161 struct msm8x10_wcd_micbias_setting micbias;
162 struct msm8x10_wcd_ocp_setting ocp;
163 struct msm8x10_wcd_regulator regulator[MAX_REGULATOR];
164 u32 mclk_rate;
165};
166
167enum msm8x10_wcd_micbias_num {
168 MSM8X10_WCD_MICBIAS1 = 0,
169};
170
171struct msm8x10_wcd_mbhc_config {
172 struct snd_soc_jack *headset_jack;
173 struct snd_soc_jack *button_jack;
174 bool read_fw_bin;
175 /*
176 * void* calibration contains:
177 * struct msm8x10_wcd_mbhc_general_cfg generic;
178 * struct msm8x10_wcd_mbhc_plug_detect_cfg plug_det;
179 * struct msm8x10_wcd_mbhc_plug_type_cfg plug_type;
180 * struct msm8x10_wcd_mbhc_btn_detect_cfg btn_det;
181 * struct msm8x10_wcd_mbhc_imped_detect_cfg imped_det;
182 * Note: various size depends on btn_det->num_btn
183 */
184 void *calibration;
185 enum msm8x10_wcd_micbias_num micbias;
186 int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
187 unsigned int mclk_rate;
188 unsigned int gpio;
189 unsigned int gpio_irq;
190 int gpio_level_insert;
191 bool detect_extn_cable;
192 /* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
193 bool (*swap_gnd_mic) (struct snd_soc_codec *);
194};
195
196enum msm8x10_wcd_pm_state {
197 MSM8X10_WCD_PM_SLEEPABLE,
198 MSM8X10_WCD_PM_AWAKE,
199 MSM8X10_WCD_PM_ASLEEP,
200};
201
202struct msm8x10_wcd {
203 struct device *dev;
204 struct mutex io_lock;
205 struct mutex xfer_lock;
206 struct mutex irq_lock;
207 u8 version;
208
209 int reset_gpio;
Kuirong Wang3a6408d2013-02-20 17:46:46 -0800210 int (*read_dev)(struct msm8x10_wcd *msm8x10,
211 unsigned short reg, unsigned int *val);
212 int (*write_dev)(struct msm8x10_wcd *msm8x10,
Kuirong Wang91e52532013-03-31 14:24:22 -0700213 unsigned short reg, u8 val);
Kuirong Wang265f3592012-12-05 16:17:41 -0800214
215 u32 num_of_supplies;
216 struct regulator_bulk_data *supplies;
217
218 enum msm8x10_wcd_pm_state pm_state;
219 struct mutex pm_lock;
220 /* pm_wq notifies change of pm_state */
221 wait_queue_head_t pm_wq;
222 struct pm_qos_request pm_qos_req;
223 int wlock_holders;
224
225 u8 idbyte[4];
226
227 unsigned int irq_base;
228 unsigned int irq;
229 u8 irq_masks_cur[MSM8X10_WCD_NUM_IRQ_REGS];
230 u8 irq_masks_cache[MSM8X10_WCD_NUM_IRQ_REGS];
231 bool irq_level_high[MSM8X10_WCD_NUM_IRQS];
232 int num_irqs;
233 u32 mclk_rate;
234};
235
236extern int msm8x10_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable,
237 bool dapm);
238extern int msm8x10_wcd_hs_detect(struct snd_soc_codec *codec,
239 struct msm8x10_wcd_mbhc_config *mbhc_cfg);
240
241#endif