diff options
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r-- | sound/soc/codecs/twl4030.c | 376 |
1 files changed, 134 insertions, 242 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index dfc51bb425da..00665ada23e2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -48,86 +48,6 @@ | |||
48 | 48 | ||
49 | #define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) | 49 | #define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) |
50 | 50 | ||
51 | /* | ||
52 | * twl4030 register cache & default register settings | ||
53 | */ | ||
54 | static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { | ||
55 | 0x00, /* this register not used */ | ||
56 | 0x00, /* REG_CODEC_MODE (0x1) */ | ||
57 | 0x00, /* REG_OPTION (0x2) */ | ||
58 | 0x00, /* REG_UNKNOWN (0x3) */ | ||
59 | 0x00, /* REG_MICBIAS_CTL (0x4) */ | ||
60 | 0x00, /* REG_ANAMICL (0x5) */ | ||
61 | 0x00, /* REG_ANAMICR (0x6) */ | ||
62 | 0x00, /* REG_AVADC_CTL (0x7) */ | ||
63 | 0x00, /* REG_ADCMICSEL (0x8) */ | ||
64 | 0x00, /* REG_DIGMIXING (0x9) */ | ||
65 | 0x0f, /* REG_ATXL1PGA (0xA) */ | ||
66 | 0x0f, /* REG_ATXR1PGA (0xB) */ | ||
67 | 0x0f, /* REG_AVTXL2PGA (0xC) */ | ||
68 | 0x0f, /* REG_AVTXR2PGA (0xD) */ | ||
69 | 0x00, /* REG_AUDIO_IF (0xE) */ | ||
70 | 0x00, /* REG_VOICE_IF (0xF) */ | ||
71 | 0x3f, /* REG_ARXR1PGA (0x10) */ | ||
72 | 0x3f, /* REG_ARXL1PGA (0x11) */ | ||
73 | 0x3f, /* REG_ARXR2PGA (0x12) */ | ||
74 | 0x3f, /* REG_ARXL2PGA (0x13) */ | ||
75 | 0x25, /* REG_VRXPGA (0x14) */ | ||
76 | 0x00, /* REG_VSTPGA (0x15) */ | ||
77 | 0x00, /* REG_VRX2ARXPGA (0x16) */ | ||
78 | 0x00, /* REG_AVDAC_CTL (0x17) */ | ||
79 | 0x00, /* REG_ARX2VTXPGA (0x18) */ | ||
80 | 0x32, /* REG_ARXL1_APGA_CTL (0x19) */ | ||
81 | 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */ | ||
82 | 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */ | ||
83 | 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */ | ||
84 | 0x00, /* REG_ATX2ARXPGA (0x1D) */ | ||
85 | 0x00, /* REG_BT_IF (0x1E) */ | ||
86 | 0x55, /* REG_BTPGA (0x1F) */ | ||
87 | 0x00, /* REG_BTSTPGA (0x20) */ | ||
88 | 0x00, /* REG_EAR_CTL (0x21) */ | ||
89 | 0x00, /* REG_HS_SEL (0x22) */ | ||
90 | 0x00, /* REG_HS_GAIN_SET (0x23) */ | ||
91 | 0x00, /* REG_HS_POPN_SET (0x24) */ | ||
92 | 0x00, /* REG_PREDL_CTL (0x25) */ | ||
93 | 0x00, /* REG_PREDR_CTL (0x26) */ | ||
94 | 0x00, /* REG_PRECKL_CTL (0x27) */ | ||
95 | 0x00, /* REG_PRECKR_CTL (0x28) */ | ||
96 | 0x00, /* REG_HFL_CTL (0x29) */ | ||
97 | 0x00, /* REG_HFR_CTL (0x2A) */ | ||
98 | 0x05, /* REG_ALC_CTL (0x2B) */ | ||
99 | 0x00, /* REG_ALC_SET1 (0x2C) */ | ||
100 | 0x00, /* REG_ALC_SET2 (0x2D) */ | ||
101 | 0x00, /* REG_BOOST_CTL (0x2E) */ | ||
102 | 0x00, /* REG_SOFTVOL_CTL (0x2F) */ | ||
103 | 0x13, /* REG_DTMF_FREQSEL (0x30) */ | ||
104 | 0x00, /* REG_DTMF_TONEXT1H (0x31) */ | ||
105 | 0x00, /* REG_DTMF_TONEXT1L (0x32) */ | ||
106 | 0x00, /* REG_DTMF_TONEXT2H (0x33) */ | ||
107 | 0x00, /* REG_DTMF_TONEXT2L (0x34) */ | ||
108 | 0x79, /* REG_DTMF_TONOFF (0x35) */ | ||
109 | 0x11, /* REG_DTMF_WANONOFF (0x36) */ | ||
110 | 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ | ||
111 | 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ | ||
112 | 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ | ||
113 | 0x06, /* REG_APLL_CTL (0x3A) */ | ||
114 | 0x00, /* REG_DTMF_CTL (0x3B) */ | ||
115 | 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */ | ||
116 | 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */ | ||
117 | 0x00, /* REG_MISC_SET_1 (0x3E) */ | ||
118 | 0x00, /* REG_PCMBTMUX (0x3F) */ | ||
119 | 0x00, /* not used (0x40) */ | ||
120 | 0x00, /* not used (0x41) */ | ||
121 | 0x00, /* not used (0x42) */ | ||
122 | 0x00, /* REG_RX_PATH_SEL (0x43) */ | ||
123 | 0x32, /* REG_VDL_APGA_CTL (0x44) */ | ||
124 | 0x00, /* REG_VIBRA_CTL (0x45) */ | ||
125 | 0x00, /* REG_VIBRA_SET (0x46) */ | ||
126 | 0x00, /* REG_VIBRA_PWM_SET (0x47) */ | ||
127 | 0x00, /* REG_ANAMIC_GAIN (0x48) */ | ||
128 | 0x00, /* REG_MISC_SET_2 (0x49) */ | ||
129 | }; | ||
130 | |||
131 | /* codec private data */ | 51 | /* codec private data */ |
132 | struct twl4030_priv { | 52 | struct twl4030_priv { |
133 | unsigned int codec_powered; | 53 | unsigned int codec_powered; |
@@ -150,81 +70,108 @@ struct twl4030_priv { | |||
150 | u8 earpiece_enabled; | 70 | u8 earpiece_enabled; |
151 | u8 predrivel_enabled, predriver_enabled; | 71 | u8 predrivel_enabled, predriver_enabled; |
152 | u8 carkitl_enabled, carkitr_enabled; | 72 | u8 carkitl_enabled, carkitr_enabled; |
73 | u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1]; | ||
153 | 74 | ||
154 | struct twl4030_codec_data *pdata; | 75 | struct twl4030_codec_data *pdata; |
155 | }; | 76 | }; |
156 | 77 | ||
157 | /* | 78 | static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030) |
158 | * read twl4030 register cache | ||
159 | */ | ||
160 | static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, | ||
161 | unsigned int reg) | ||
162 | { | 79 | { |
163 | u8 *cache = codec->reg_cache; | 80 | int i; |
164 | 81 | u8 byte; | |
165 | if (reg >= TWL4030_CACHEREGNUM) | ||
166 | return -EIO; | ||
167 | 82 | ||
168 | return cache[reg]; | 83 | for (i = TWL4030_REG_EAR_CTL; i <= TWL4030_REG_PRECKR_CTL; i++) { |
84 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, i); | ||
85 | twl4030->ctl_cache[i - TWL4030_REG_EAR_CTL] = byte; | ||
86 | } | ||
169 | } | 87 | } |
170 | 88 | ||
171 | /* | 89 | static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg) |
172 | * write twl4030 register cache | ||
173 | */ | ||
174 | static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec, | ||
175 | u8 reg, u8 value) | ||
176 | { | 90 | { |
177 | u8 *cache = codec->reg_cache; | 91 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
92 | u8 value = 0; | ||
178 | 93 | ||
179 | if (reg >= TWL4030_CACHEREGNUM) | 94 | if (reg >= TWL4030_CACHEREGNUM) |
180 | return; | 95 | return -EIO; |
181 | cache[reg] = value; | 96 | |
97 | switch (reg) { | ||
98 | case TWL4030_REG_EAR_CTL: | ||
99 | case TWL4030_REG_PREDL_CTL: | ||
100 | case TWL4030_REG_PREDR_CTL: | ||
101 | case TWL4030_REG_PRECKL_CTL: | ||
102 | case TWL4030_REG_PRECKR_CTL: | ||
103 | case TWL4030_REG_HS_GAIN_SET: | ||
104 | value = twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL]; | ||
105 | break; | ||
106 | default: | ||
107 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg); | ||
108 | break; | ||
109 | } | ||
110 | |||
111 | return value; | ||
182 | } | 112 | } |
183 | 113 | ||
184 | /* | 114 | static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030, |
185 | * write to the twl4030 register space | 115 | unsigned int reg) |
186 | */ | ||
187 | static int twl4030_write(struct snd_soc_codec *codec, | ||
188 | unsigned int reg, unsigned int value) | ||
189 | { | 116 | { |
190 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 117 | bool write_to_reg = false; |
191 | int write_to_reg = 0; | ||
192 | 118 | ||
193 | twl4030_write_reg_cache(codec, reg, value); | ||
194 | /* Decide if the given register can be written */ | 119 | /* Decide if the given register can be written */ |
195 | switch (reg) { | 120 | switch (reg) { |
196 | case TWL4030_REG_EAR_CTL: | 121 | case TWL4030_REG_EAR_CTL: |
197 | if (twl4030->earpiece_enabled) | 122 | if (twl4030->earpiece_enabled) |
198 | write_to_reg = 1; | 123 | write_to_reg = true; |
199 | break; | 124 | break; |
200 | case TWL4030_REG_PREDL_CTL: | 125 | case TWL4030_REG_PREDL_CTL: |
201 | if (twl4030->predrivel_enabled) | 126 | if (twl4030->predrivel_enabled) |
202 | write_to_reg = 1; | 127 | write_to_reg = true; |
203 | break; | 128 | break; |
204 | case TWL4030_REG_PREDR_CTL: | 129 | case TWL4030_REG_PREDR_CTL: |
205 | if (twl4030->predriver_enabled) | 130 | if (twl4030->predriver_enabled) |
206 | write_to_reg = 1; | 131 | write_to_reg = true; |
207 | break; | 132 | break; |
208 | case TWL4030_REG_PRECKL_CTL: | 133 | case TWL4030_REG_PRECKL_CTL: |
209 | if (twl4030->carkitl_enabled) | 134 | if (twl4030->carkitl_enabled) |
210 | write_to_reg = 1; | 135 | write_to_reg = true; |
211 | break; | 136 | break; |
212 | case TWL4030_REG_PRECKR_CTL: | 137 | case TWL4030_REG_PRECKR_CTL: |
213 | if (twl4030->carkitr_enabled) | 138 | if (twl4030->carkitr_enabled) |
214 | write_to_reg = 1; | 139 | write_to_reg = true; |
215 | break; | 140 | break; |
216 | case TWL4030_REG_HS_GAIN_SET: | 141 | case TWL4030_REG_HS_GAIN_SET: |
217 | if (twl4030->hsl_enabled || twl4030->hsr_enabled) | 142 | if (twl4030->hsl_enabled || twl4030->hsr_enabled) |
218 | write_to_reg = 1; | 143 | write_to_reg = true; |
219 | break; | 144 | break; |
220 | default: | 145 | default: |
221 | /* All other register can be written */ | 146 | /* All other register can be written */ |
222 | write_to_reg = 1; | 147 | write_to_reg = true; |
148 | break; | ||
149 | } | ||
150 | |||
151 | return write_to_reg; | ||
152 | } | ||
153 | |||
154 | static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg, | ||
155 | unsigned int value) | ||
156 | { | ||
157 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
158 | |||
159 | /* Update the ctl cache */ | ||
160 | switch (reg) { | ||
161 | case TWL4030_REG_EAR_CTL: | ||
162 | case TWL4030_REG_PREDL_CTL: | ||
163 | case TWL4030_REG_PREDR_CTL: | ||
164 | case TWL4030_REG_PRECKL_CTL: | ||
165 | case TWL4030_REG_PRECKR_CTL: | ||
166 | case TWL4030_REG_HS_GAIN_SET: | ||
167 | twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL] = value; | ||
168 | break; | ||
169 | default: | ||
223 | break; | 170 | break; |
224 | } | 171 | } |
225 | if (write_to_reg) | 172 | |
226 | return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | 173 | if (twl4030_can_write_to_chip(twl4030, reg)) |
227 | value, reg); | 174 | return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); |
228 | 175 | ||
229 | return 0; | 176 | return 0; |
230 | } | 177 | } |
@@ -252,46 +199,14 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) | |||
252 | else | 199 | else |
253 | mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER); | 200 | mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER); |
254 | 201 | ||
255 | if (mode >= 0) { | 202 | if (mode >= 0) |
256 | twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode); | ||
257 | twl4030->codec_powered = enable; | 203 | twl4030->codec_powered = enable; |
258 | } | ||
259 | 204 | ||
260 | /* REVISIT: this delay is present in TI sample drivers */ | 205 | /* REVISIT: this delay is present in TI sample drivers */ |
261 | /* but there seems to be no TRM requirement for it */ | 206 | /* but there seems to be no TRM requirement for it */ |
262 | udelay(10); | 207 | udelay(10); |
263 | } | 208 | } |
264 | 209 | ||
265 | static inline void twl4030_check_defaults(struct snd_soc_codec *codec) | ||
266 | { | ||
267 | int i, difference = 0; | ||
268 | u8 val; | ||
269 | |||
270 | dev_dbg(codec->dev, "Checking TWL audio default configuration\n"); | ||
271 | for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) { | ||
272 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i); | ||
273 | if (val != twl4030_reg[i]) { | ||
274 | difference++; | ||
275 | dev_dbg(codec->dev, | ||
276 | "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n", | ||
277 | i, val, twl4030_reg[i]); | ||
278 | } | ||
279 | } | ||
280 | dev_dbg(codec->dev, "Found %d non-matching registers. %s\n", | ||
281 | difference, difference ? "Not OK" : "OK"); | ||
282 | } | ||
283 | |||
284 | static inline void twl4030_reset_registers(struct snd_soc_codec *codec) | ||
285 | { | ||
286 | int i; | ||
287 | |||
288 | /* set all audio section registers to reasonable defaults */ | ||
289 | for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) | ||
290 | if (i != TWL4030_REG_APLL_CTL) | ||
291 | twl4030_write(codec, i, twl4030_reg[i]); | ||
292 | |||
293 | } | ||
294 | |||
295 | static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, | 210 | static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, |
296 | struct device_node *node) | 211 | struct device_node *node) |
297 | { | 212 | { |
@@ -372,27 +287,17 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
372 | } | 287 | } |
373 | } | 288 | } |
374 | 289 | ||
375 | /* Check defaults, if instructed before anything else */ | 290 | /* Initialize the local ctl register cache */ |
376 | if (pdata && pdata->check_defaults) | 291 | tw4030_init_ctl_cache(twl4030); |
377 | twl4030_check_defaults(codec); | ||
378 | |||
379 | /* Reset registers, if no setup data or if instructed to do so */ | ||
380 | if (!pdata || (pdata && pdata->reset_registers)) | ||
381 | twl4030_reset_registers(codec); | ||
382 | |||
383 | /* Refresh APLL_CTL register from HW */ | ||
384 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, | ||
385 | TWL4030_REG_APLL_CTL); | ||
386 | twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte); | ||
387 | 292 | ||
388 | /* anti-pop when changing analog gain */ | 293 | /* anti-pop when changing analog gain */ |
389 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); | 294 | reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1); |
390 | twl4030_write(codec, TWL4030_REG_MISC_SET_1, | 295 | twl4030_write(codec, TWL4030_REG_MISC_SET_1, |
391 | reg | TWL4030_SMOOTH_ANAVOL_EN); | 296 | reg | TWL4030_SMOOTH_ANAVOL_EN); |
392 | 297 | ||
393 | twl4030_write(codec, TWL4030_REG_OPTION, | 298 | twl4030_write(codec, TWL4030_REG_OPTION, |
394 | TWL4030_ATXL1_EN | TWL4030_ATXR1_EN | | 299 | TWL4030_ATXL1_EN | TWL4030_ATXR1_EN | |
395 | TWL4030_ARXL2_EN | TWL4030_ARXR2_EN); | 300 | TWL4030_ARXL2_EN | TWL4030_ARXR2_EN); |
396 | 301 | ||
397 | /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */ | 302 | /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */ |
398 | twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); | 303 | twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); |
@@ -403,19 +308,19 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
403 | 308 | ||
404 | twl4030->pdata = pdata; | 309 | twl4030->pdata = pdata; |
405 | 310 | ||
406 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); | 311 | reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET); |
407 | reg &= ~TWL4030_RAMP_DELAY; | 312 | reg &= ~TWL4030_RAMP_DELAY; |
408 | reg |= (pdata->ramp_delay_value << 2); | 313 | reg |= (pdata->ramp_delay_value << 2); |
409 | twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg); | 314 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg); |
410 | 315 | ||
411 | /* initiate offset cancellation */ | 316 | /* initiate offset cancellation */ |
412 | twl4030_codec_enable(codec, 1); | 317 | twl4030_codec_enable(codec, 1); |
413 | 318 | ||
414 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); | 319 | reg = twl4030_read(codec, TWL4030_REG_ANAMICL); |
415 | reg &= ~TWL4030_OFFSET_CNCL_SEL; | 320 | reg &= ~TWL4030_OFFSET_CNCL_SEL; |
416 | reg |= pdata->offset_cncl_path; | 321 | reg |= pdata->offset_cncl_path; |
417 | twl4030_write(codec, TWL4030_REG_ANAMICL, | 322 | twl4030_write(codec, TWL4030_REG_ANAMICL, |
418 | reg | TWL4030_CNCL_OFFSET_START); | 323 | reg | TWL4030_CNCL_OFFSET_START); |
419 | 324 | ||
420 | /* | 325 | /* |
421 | * Wait for offset cancellation to complete. | 326 | * Wait for offset cancellation to complete. |
@@ -425,15 +330,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) | |||
425 | msleep(20); | 330 | msleep(20); |
426 | do { | 331 | do { |
427 | usleep_range(1000, 2000); | 332 | usleep_range(1000, 2000); |
333 | twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, true); | ||
428 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, | 334 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, |
429 | TWL4030_REG_ANAMICL); | 335 | TWL4030_REG_ANAMICL); |
336 | twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, false); | ||
430 | } while ((i++ < 100) && | 337 | } while ((i++ < 100) && |
431 | ((byte & TWL4030_CNCL_OFFSET_START) == | 338 | ((byte & TWL4030_CNCL_OFFSET_START) == |
432 | TWL4030_CNCL_OFFSET_START)); | 339 | TWL4030_CNCL_OFFSET_START)); |
433 | 340 | ||
434 | /* Make sure that the reg_cache has the same value as the HW */ | ||
435 | twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); | ||
436 | |||
437 | twl4030_codec_enable(codec, 0); | 341 | twl4030_codec_enable(codec, 0); |
438 | } | 342 | } |
439 | 343 | ||
@@ -453,9 +357,6 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) | |||
453 | status = twl4030_audio_disable_resource( | 357 | status = twl4030_audio_disable_resource( |
454 | TWL4030_AUDIO_RES_APLL); | 358 | TWL4030_AUDIO_RES_APLL); |
455 | } | 359 | } |
456 | |||
457 | if (status >= 0) | ||
458 | twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); | ||
459 | } | 360 | } |
460 | 361 | ||
461 | /* Earpiece */ | 362 | /* Earpiece */ |
@@ -671,20 +572,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control = | |||
671 | */ | 572 | */ |
672 | #define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ | 573 | #define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ |
673 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ | 574 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ |
674 | struct snd_kcontrol *kcontrol, int event) \ | 575 | struct snd_kcontrol *kcontrol, int event) \ |
675 | { \ | 576 | { \ |
676 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ | 577 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ |
677 | \ | 578 | \ |
678 | switch (event) { \ | 579 | switch (event) { \ |
679 | case SND_SOC_DAPM_POST_PMU: \ | 580 | case SND_SOC_DAPM_POST_PMU: \ |
680 | twl4030->pin_name##_enabled = 1; \ | 581 | twl4030->pin_name##_enabled = 1; \ |
681 | twl4030_write(w->codec, reg, \ | 582 | twl4030_write(w->codec, reg, twl4030_read(w->codec, reg)); \ |
682 | twl4030_read_reg_cache(w->codec, reg)); \ | ||
683 | break; \ | 583 | break; \ |
684 | case SND_SOC_DAPM_POST_PMD: \ | 584 | case SND_SOC_DAPM_POST_PMD: \ |
685 | twl4030->pin_name##_enabled = 0; \ | 585 | twl4030->pin_name##_enabled = 0; \ |
686 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ | 586 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 0, reg); \ |
687 | 0, reg); \ | ||
688 | break; \ | 587 | break; \ |
689 | } \ | 588 | } \ |
690 | return 0; \ | 589 | return 0; \ |
@@ -700,7 +599,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) | |||
700 | { | 599 | { |
701 | unsigned char hs_ctl; | 600 | unsigned char hs_ctl; |
702 | 601 | ||
703 | hs_ctl = twl4030_read_reg_cache(codec, reg); | 602 | hs_ctl = twl4030_read(codec, reg); |
704 | 603 | ||
705 | if (ramp) { | 604 | if (ramp) { |
706 | /* HF ramp-up */ | 605 | /* HF ramp-up */ |
@@ -727,7 +626,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) | |||
727 | } | 626 | } |
728 | 627 | ||
729 | static int handsfreelpga_event(struct snd_soc_dapm_widget *w, | 628 | static int handsfreelpga_event(struct snd_soc_dapm_widget *w, |
730 | struct snd_kcontrol *kcontrol, int event) | 629 | struct snd_kcontrol *kcontrol, int event) |
731 | { | 630 | { |
732 | switch (event) { | 631 | switch (event) { |
733 | case SND_SOC_DAPM_POST_PMU: | 632 | case SND_SOC_DAPM_POST_PMU: |
@@ -741,7 +640,7 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w, | |||
741 | } | 640 | } |
742 | 641 | ||
743 | static int handsfreerpga_event(struct snd_soc_dapm_widget *w, | 642 | static int handsfreerpga_event(struct snd_soc_dapm_widget *w, |
744 | struct snd_kcontrol *kcontrol, int event) | 643 | struct snd_kcontrol *kcontrol, int event) |
745 | { | 644 | { |
746 | switch (event) { | 645 | switch (event) { |
747 | case SND_SOC_DAPM_POST_PMU: | 646 | case SND_SOC_DAPM_POST_PMU: |
@@ -755,14 +654,14 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w, | |||
755 | } | 654 | } |
756 | 655 | ||
757 | static int vibramux_event(struct snd_soc_dapm_widget *w, | 656 | static int vibramux_event(struct snd_soc_dapm_widget *w, |
758 | struct snd_kcontrol *kcontrol, int event) | 657 | struct snd_kcontrol *kcontrol, int event) |
759 | { | 658 | { |
760 | twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff); | 659 | twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff); |
761 | return 0; | 660 | return 0; |
762 | } | 661 | } |
763 | 662 | ||
764 | static int apll_event(struct snd_soc_dapm_widget *w, | 663 | static int apll_event(struct snd_soc_dapm_widget *w, |
765 | struct snd_kcontrol *kcontrol, int event) | 664 | struct snd_kcontrol *kcontrol, int event) |
766 | { | 665 | { |
767 | switch (event) { | 666 | switch (event) { |
768 | case SND_SOC_DAPM_PRE_PMU: | 667 | case SND_SOC_DAPM_PRE_PMU: |
@@ -776,11 +675,11 @@ static int apll_event(struct snd_soc_dapm_widget *w, | |||
776 | } | 675 | } |
777 | 676 | ||
778 | static int aif_event(struct snd_soc_dapm_widget *w, | 677 | static int aif_event(struct snd_soc_dapm_widget *w, |
779 | struct snd_kcontrol *kcontrol, int event) | 678 | struct snd_kcontrol *kcontrol, int event) |
780 | { | 679 | { |
781 | u8 audio_if; | 680 | u8 audio_if; |
782 | 681 | ||
783 | audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF); | 682 | audio_if = twl4030_read(w->codec, TWL4030_REG_AUDIO_IF); |
784 | switch (event) { | 683 | switch (event) { |
785 | case SND_SOC_DAPM_PRE_PMU: | 684 | case SND_SOC_DAPM_PRE_PMU: |
786 | /* Enable AIF */ | 685 | /* Enable AIF */ |
@@ -788,12 +687,12 @@ static int aif_event(struct snd_soc_dapm_widget *w, | |||
788 | twl4030_apll_enable(w->codec, 1); | 687 | twl4030_apll_enable(w->codec, 1); |
789 | 688 | ||
790 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | 689 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, |
791 | audio_if | TWL4030_AIF_EN); | 690 | audio_if | TWL4030_AIF_EN); |
792 | break; | 691 | break; |
793 | case SND_SOC_DAPM_POST_PMD: | 692 | case SND_SOC_DAPM_POST_PMD: |
794 | /* disable the DAI before we stop it's source PLL */ | 693 | /* disable the DAI before we stop it's source PLL */ |
795 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | 694 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, |
796 | audio_if & ~TWL4030_AIF_EN); | 695 | audio_if & ~TWL4030_AIF_EN); |
797 | twl4030_apll_enable(w->codec, 0); | 696 | twl4030_apll_enable(w->codec, 0); |
798 | break; | 697 | break; |
799 | } | 698 | } |
@@ -810,8 +709,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
810 | 8388608, 16777216, 33554432, 67108864}; | 709 | 8388608, 16777216, 33554432, 67108864}; |
811 | unsigned int delay; | 710 | unsigned int delay; |
812 | 711 | ||
813 | hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); | 712 | hs_gain = twl4030_read(codec, TWL4030_REG_HS_GAIN_SET); |
814 | hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); | 713 | hs_pop = twl4030_read(codec, TWL4030_REG_HS_POPN_SET); |
815 | delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / | 714 | delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / |
816 | twl4030->sysclk) + 1; | 715 | twl4030->sysclk) + 1; |
817 | 716 | ||
@@ -831,9 +730,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
831 | hs_pop |= TWL4030_VMID_EN; | 730 | hs_pop |= TWL4030_VMID_EN; |
832 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 731 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
833 | /* Actually write to the register */ | 732 | /* Actually write to the register */ |
834 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | 733 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain, |
835 | hs_gain, | 734 | TWL4030_REG_HS_GAIN_SET); |
836 | TWL4030_REG_HS_GAIN_SET); | ||
837 | hs_pop |= TWL4030_RAMP_EN; | 735 | hs_pop |= TWL4030_RAMP_EN; |
838 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 736 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
839 | /* Wait ramp delay time + 1, so the VMID can settle */ | 737 | /* Wait ramp delay time + 1, so the VMID can settle */ |
@@ -846,9 +744,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
846 | /* Wait ramp delay time + 1, so the VMID can settle */ | 744 | /* Wait ramp delay time + 1, so the VMID can settle */ |
847 | twl4030_wait_ms(delay); | 745 | twl4030_wait_ms(delay); |
848 | /* Bypass the reg_cache to mute the headset */ | 746 | /* Bypass the reg_cache to mute the headset */ |
849 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | 747 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), |
850 | hs_gain & (~0x0f), | 748 | TWL4030_REG_HS_GAIN_SET); |
851 | TWL4030_REG_HS_GAIN_SET); | ||
852 | 749 | ||
853 | hs_pop &= ~TWL4030_VMID_EN; | 750 | hs_pop &= ~TWL4030_VMID_EN; |
854 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); | 751 | twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); |
@@ -866,7 +763,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
866 | } | 763 | } |
867 | 764 | ||
868 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, | 765 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, |
869 | struct snd_kcontrol *kcontrol, int event) | 766 | struct snd_kcontrol *kcontrol, int event) |
870 | { | 767 | { |
871 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 768 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
872 | 769 | ||
@@ -890,7 +787,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w, | |||
890 | } | 787 | } |
891 | 788 | ||
892 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, | 789 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, |
893 | struct snd_kcontrol *kcontrol, int event) | 790 | struct snd_kcontrol *kcontrol, int event) |
894 | { | 791 | { |
895 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 792 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
896 | 793 | ||
@@ -914,7 +811,7 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w, | |||
914 | } | 811 | } |
915 | 812 | ||
916 | static int digimic_event(struct snd_soc_dapm_widget *w, | 813 | static int digimic_event(struct snd_soc_dapm_widget *w, |
917 | struct snd_kcontrol *kcontrol, int event) | 814 | struct snd_kcontrol *kcontrol, int event) |
918 | { | 815 | { |
919 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 816 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); |
920 | struct twl4030_codec_data *pdata = twl4030->pdata; | 817 | struct twl4030_codec_data *pdata = twl4030->pdata; |
@@ -935,7 +832,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w, | |||
935 | * Custom volsw and volsw_2r get/put functions to handle these gain bits. | 832 | * Custom volsw and volsw_2r get/put functions to handle these gain bits. |
936 | */ | 833 | */ |
937 | static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, | 834 | static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, |
938 | struct snd_ctl_elem_value *ucontrol) | 835 | struct snd_ctl_elem_value *ucontrol) |
939 | { | 836 | { |
940 | struct soc_mixer_control *mc = | 837 | struct soc_mixer_control *mc = |
941 | (struct soc_mixer_control *)kcontrol->private_value; | 838 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -964,7 +861,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, | |||
964 | } | 861 | } |
965 | 862 | ||
966 | static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, | 863 | static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, |
967 | struct snd_ctl_elem_value *ucontrol) | 864 | struct snd_ctl_elem_value *ucontrol) |
968 | { | 865 | { |
969 | struct soc_mixer_control *mc = | 866 | struct soc_mixer_control *mc = |
970 | (struct soc_mixer_control *)kcontrol->private_value; | 867 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -993,7 +890,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, | |||
993 | } | 890 | } |
994 | 891 | ||
995 | static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | 892 | static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, |
996 | struct snd_ctl_elem_value *ucontrol) | 893 | struct snd_ctl_elem_value *ucontrol) |
997 | { | 894 | { |
998 | struct soc_mixer_control *mc = | 895 | struct soc_mixer_control *mc = |
999 | (struct soc_mixer_control *)kcontrol->private_value; | 896 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -1020,7 +917,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | |||
1020 | } | 917 | } |
1021 | 918 | ||
1022 | static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | 919 | static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, |
1023 | struct snd_ctl_elem_value *ucontrol) | 920 | struct snd_ctl_elem_value *ucontrol) |
1024 | { | 921 | { |
1025 | struct soc_mixer_control *mc = | 922 | struct soc_mixer_control *mc = |
1026 | (struct soc_mixer_control *)kcontrol->private_value; | 923 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -1751,11 +1648,11 @@ static void twl4030_constraints(struct twl4030_priv *twl4030, | |||
1751 | /* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for | 1648 | /* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for |
1752 | * capture has to be enabled/disabled. */ | 1649 | * capture has to be enabled/disabled. */ |
1753 | static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, | 1650 | static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, |
1754 | int enable) | 1651 | int enable) |
1755 | { | 1652 | { |
1756 | u8 reg, mask; | 1653 | u8 reg, mask; |
1757 | 1654 | ||
1758 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); | 1655 | reg = twl4030_read(codec, TWL4030_REG_OPTION); |
1759 | 1656 | ||
1760 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) | 1657 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) |
1761 | mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; | 1658 | mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; |
@@ -1784,14 +1681,14 @@ static int twl4030_startup(struct snd_pcm_substream *substream, | |||
1784 | if (twl4030->configured) | 1681 | if (twl4030->configured) |
1785 | twl4030_constraints(twl4030, twl4030->master_substream); | 1682 | twl4030_constraints(twl4030, twl4030->master_substream); |
1786 | } else { | 1683 | } else { |
1787 | if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & | 1684 | if (!(twl4030_read(codec, TWL4030_REG_CODEC_MODE) & |
1788 | TWL4030_OPTION_1)) { | 1685 | TWL4030_OPTION_1)) { |
1789 | /* In option2 4 channel is not supported, set the | 1686 | /* In option2 4 channel is not supported, set the |
1790 | * constraint for the first stream for channels, the | 1687 | * constraint for the first stream for channels, the |
1791 | * second stream will 'inherit' this cosntraint */ | 1688 | * second stream will 'inherit' this cosntraint */ |
1792 | snd_pcm_hw_constraint_minmax(substream->runtime, | 1689 | snd_pcm_hw_constraint_minmax(substream->runtime, |
1793 | SNDRV_PCM_HW_PARAM_CHANNELS, | 1690 | SNDRV_PCM_HW_PARAM_CHANNELS, |
1794 | 2, 2); | 1691 | 2, 2); |
1795 | } | 1692 | } |
1796 | twl4030->master_substream = substream; | 1693 | twl4030->master_substream = substream; |
1797 | } | 1694 | } |
@@ -1823,8 +1720,8 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, | |||
1823 | } | 1720 | } |
1824 | 1721 | ||
1825 | static int twl4030_hw_params(struct snd_pcm_substream *substream, | 1722 | static int twl4030_hw_params(struct snd_pcm_substream *substream, |
1826 | struct snd_pcm_hw_params *params, | 1723 | struct snd_pcm_hw_params *params, |
1827 | struct snd_soc_dai *dai) | 1724 | struct snd_soc_dai *dai) |
1828 | { | 1725 | { |
1829 | struct snd_soc_codec *codec = dai->codec; | 1726 | struct snd_soc_codec *codec = dai->codec; |
1830 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1727 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
@@ -1832,8 +1729,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1832 | 1729 | ||
1833 | /* If the substream has 4 channel, do the necessary setup */ | 1730 | /* If the substream has 4 channel, do the necessary setup */ |
1834 | if (params_channels(params) == 4) { | 1731 | if (params_channels(params) == 4) { |
1835 | format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); | 1732 | format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); |
1836 | mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); | 1733 | mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE); |
1837 | 1734 | ||
1838 | /* Safety check: are we in the correct operating mode and | 1735 | /* Safety check: are we in the correct operating mode and |
1839 | * the interface is in TDM mode? */ | 1736 | * the interface is in TDM mode? */ |
@@ -1849,8 +1746,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1849 | return 0; | 1746 | return 0; |
1850 | 1747 | ||
1851 | /* bit rate */ | 1748 | /* bit rate */ |
1852 | old_mode = twl4030_read_reg_cache(codec, | 1749 | old_mode = twl4030_read(codec, |
1853 | TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; | 1750 | TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; |
1854 | mode = old_mode & ~TWL4030_APLL_RATE; | 1751 | mode = old_mode & ~TWL4030_APLL_RATE; |
1855 | 1752 | ||
1856 | switch (params_rate(params)) { | 1753 | switch (params_rate(params)) { |
@@ -1891,7 +1788,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1891 | } | 1788 | } |
1892 | 1789 | ||
1893 | /* sample size */ | 1790 | /* sample size */ |
1894 | old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); | 1791 | old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); |
1895 | format = old_format; | 1792 | format = old_format; |
1896 | format &= ~TWL4030_DATA_WIDTH; | 1793 | format &= ~TWL4030_DATA_WIDTH; |
1897 | switch (params_format(params)) { | 1794 | switch (params_format(params)) { |
@@ -1940,8 +1837,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1940 | return 0; | 1837 | return 0; |
1941 | } | 1838 | } |
1942 | 1839 | ||
1943 | static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, | 1840 | static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, |
1944 | int clk_id, unsigned int freq, int dir) | 1841 | unsigned int freq, int dir) |
1945 | { | 1842 | { |
1946 | struct snd_soc_codec *codec = codec_dai->codec; | 1843 | struct snd_soc_codec *codec = codec_dai->codec; |
1947 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1844 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
@@ -1966,15 +1863,14 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1966 | return 0; | 1863 | return 0; |
1967 | } | 1864 | } |
1968 | 1865 | ||
1969 | static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | 1866 | static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
1970 | unsigned int fmt) | ||
1971 | { | 1867 | { |
1972 | struct snd_soc_codec *codec = codec_dai->codec; | 1868 | struct snd_soc_codec *codec = codec_dai->codec; |
1973 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1869 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1974 | u8 old_format, format; | 1870 | u8 old_format, format; |
1975 | 1871 | ||
1976 | /* get format */ | 1872 | /* get format */ |
1977 | old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); | 1873 | old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); |
1978 | format = old_format; | 1874 | format = old_format; |
1979 | 1875 | ||
1980 | /* set master/slave audio interface */ | 1876 | /* set master/slave audio interface */ |
@@ -2024,7 +1920,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
2024 | static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) | 1920 | static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) |
2025 | { | 1921 | { |
2026 | struct snd_soc_codec *codec = dai->codec; | 1922 | struct snd_soc_codec *codec = dai->codec; |
2027 | u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); | 1923 | u8 reg = twl4030_read(codec, TWL4030_REG_AUDIO_IF); |
2028 | 1924 | ||
2029 | if (tristate) | 1925 | if (tristate) |
2030 | reg |= TWL4030_AIF_TRI_EN; | 1926 | reg |= TWL4030_AIF_TRI_EN; |
@@ -2037,11 +1933,11 @@ static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) | |||
2037 | /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R | 1933 | /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R |
2038 | * (VTXL, VTXR) for uplink has to be enabled/disabled. */ | 1934 | * (VTXL, VTXR) for uplink has to be enabled/disabled. */ |
2039 | static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, | 1935 | static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, |
2040 | int enable) | 1936 | int enable) |
2041 | { | 1937 | { |
2042 | u8 reg, mask; | 1938 | u8 reg, mask; |
2043 | 1939 | ||
2044 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); | 1940 | reg = twl4030_read(codec, TWL4030_REG_OPTION); |
2045 | 1941 | ||
2046 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) | 1942 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) |
2047 | mask = TWL4030_ARXL1_VRX_EN; | 1943 | mask = TWL4030_ARXL1_VRX_EN; |
@@ -2057,7 +1953,7 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, | |||
2057 | } | 1953 | } |
2058 | 1954 | ||
2059 | static int twl4030_voice_startup(struct snd_pcm_substream *substream, | 1955 | static int twl4030_voice_startup(struct snd_pcm_substream *substream, |
2060 | struct snd_soc_dai *dai) | 1956 | struct snd_soc_dai *dai) |
2061 | { | 1957 | { |
2062 | struct snd_soc_codec *codec = dai->codec; | 1958 | struct snd_soc_codec *codec = dai->codec; |
2063 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1959 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
@@ -2076,7 +1972,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
2076 | /* If the codec mode is not option2, the voice PCM interface is not | 1972 | /* If the codec mode is not option2, the voice PCM interface is not |
2077 | * available. | 1973 | * available. |
2078 | */ | 1974 | */ |
2079 | mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) | 1975 | mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE) |
2080 | & TWL4030_OPT_MODE; | 1976 | & TWL4030_OPT_MODE; |
2081 | 1977 | ||
2082 | if (mode != TWL4030_OPTION_2) { | 1978 | if (mode != TWL4030_OPTION_2) { |
@@ -2089,7 +1985,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
2089 | } | 1985 | } |
2090 | 1986 | ||
2091 | static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, | 1987 | static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, |
2092 | struct snd_soc_dai *dai) | 1988 | struct snd_soc_dai *dai) |
2093 | { | 1989 | { |
2094 | struct snd_soc_codec *codec = dai->codec; | 1990 | struct snd_soc_codec *codec = dai->codec; |
2095 | 1991 | ||
@@ -2098,7 +1994,8 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, | |||
2098 | } | 1994 | } |
2099 | 1995 | ||
2100 | static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | 1996 | static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, |
2101 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 1997 | struct snd_pcm_hw_params *params, |
1998 | struct snd_soc_dai *dai) | ||
2102 | { | 1999 | { |
2103 | struct snd_soc_codec *codec = dai->codec; | 2000 | struct snd_soc_codec *codec = dai->codec; |
2104 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2001 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
@@ -2108,8 +2005,8 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
2108 | twl4030_voice_enable(codec, substream->stream, 1); | 2005 | twl4030_voice_enable(codec, substream->stream, 1); |
2109 | 2006 | ||
2110 | /* bit rate */ | 2007 | /* bit rate */ |
2111 | old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) | 2008 | old_mode = twl4030_read(codec, |
2112 | & ~(TWL4030_CODECPDZ); | 2009 | TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; |
2113 | mode = old_mode; | 2010 | mode = old_mode; |
2114 | 2011 | ||
2115 | switch (params_rate(params)) { | 2012 | switch (params_rate(params)) { |
@@ -2143,7 +2040,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
2143 | } | 2040 | } |
2144 | 2041 | ||
2145 | static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, | 2042 | static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
2146 | int clk_id, unsigned int freq, int dir) | 2043 | int clk_id, unsigned int freq, int dir) |
2147 | { | 2044 | { |
2148 | struct snd_soc_codec *codec = codec_dai->codec; | 2045 | struct snd_soc_codec *codec = codec_dai->codec; |
2149 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2046 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
@@ -2164,14 +2061,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
2164 | } | 2061 | } |
2165 | 2062 | ||
2166 | static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, | 2063 | static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, |
2167 | unsigned int fmt) | 2064 | unsigned int fmt) |
2168 | { | 2065 | { |
2169 | struct snd_soc_codec *codec = codec_dai->codec; | 2066 | struct snd_soc_codec *codec = codec_dai->codec; |
2170 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2067 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
2171 | u8 old_format, format; | 2068 | u8 old_format, format; |
2172 | 2069 | ||
2173 | /* get format */ | 2070 | /* get format */ |
2174 | old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); | 2071 | old_format = twl4030_read(codec, TWL4030_REG_VOICE_IF); |
2175 | format = old_format; | 2072 | format = old_format; |
2176 | 2073 | ||
2177 | /* set master/slave audio interface */ | 2074 | /* set master/slave audio interface */ |
@@ -2218,7 +2115,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
2218 | static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) | 2115 | static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) |
2219 | { | 2116 | { |
2220 | struct snd_soc_codec *codec = dai->codec; | 2117 | struct snd_soc_codec *codec = dai->codec; |
2221 | u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); | 2118 | u8 reg = twl4030_read(codec, TWL4030_REG_VOICE_IF); |
2222 | 2119 | ||
2223 | if (tristate) | 2120 | if (tristate) |
2224 | reg |= TWL4030_VIF_TRI_EN; | 2121 | reg |= TWL4030_VIF_TRI_EN; |
@@ -2310,8 +2207,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) | |||
2310 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2207 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
2311 | struct twl4030_codec_data *pdata = twl4030->pdata; | 2208 | struct twl4030_codec_data *pdata = twl4030->pdata; |
2312 | 2209 | ||
2313 | /* Reset registers to their chip default before leaving */ | ||
2314 | twl4030_reset_registers(codec); | ||
2315 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2210 | twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2316 | 2211 | ||
2317 | if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) | 2212 | if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) |
@@ -2323,13 +2218,10 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) | |||
2323 | static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | 2218 | static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { |
2324 | .probe = twl4030_soc_probe, | 2219 | .probe = twl4030_soc_probe, |
2325 | .remove = twl4030_soc_remove, | 2220 | .remove = twl4030_soc_remove, |
2326 | .read = twl4030_read_reg_cache, | 2221 | .read = twl4030_read, |
2327 | .write = twl4030_write, | 2222 | .write = twl4030_write, |
2328 | .set_bias_level = twl4030_set_bias_level, | 2223 | .set_bias_level = twl4030_set_bias_level, |
2329 | .idle_bias_off = true, | 2224 | .idle_bias_off = true, |
2330 | .reg_cache_size = sizeof(twl4030_reg), | ||
2331 | .reg_word_size = sizeof(u8), | ||
2332 | .reg_cache_default = twl4030_reg, | ||
2333 | 2225 | ||
2334 | .controls = twl4030_snd_controls, | 2226 | .controls = twl4030_snd_controls, |
2335 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), | 2227 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), |
@@ -2342,7 +2234,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2342 | static int twl4030_codec_probe(struct platform_device *pdev) | 2234 | static int twl4030_codec_probe(struct platform_device *pdev) |
2343 | { | 2235 | { |
2344 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, | 2236 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, |
2345 | twl4030_dai, ARRAY_SIZE(twl4030_dai)); | 2237 | twl4030_dai, ARRAY_SIZE(twl4030_dai)); |
2346 | } | 2238 | } |
2347 | 2239 | ||
2348 | static int twl4030_codec_remove(struct platform_device *pdev) | 2240 | static int twl4030_codec_remove(struct platform_device *pdev) |