diff options
Diffstat (limited to 'sound/soc/codecs/twl6040.c')
-rw-r--r-- | sound/soc/codecs/twl6040.c | 114 |
1 files changed, 22 insertions, 92 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 443032b3b329..81645c632447 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -118,8 +118,8 @@ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { | |||
118 | 0x4A, /* TWL6040_LPPLLDIV 0x09 */ | 118 | 0x4A, /* TWL6040_LPPLLDIV 0x09 */ |
119 | 0x00, /* TWL6040_AMICBCTL 0x0A */ | 119 | 0x00, /* TWL6040_AMICBCTL 0x0A */ |
120 | 0x00, /* TWL6040_DMICBCTL 0x0B */ | 120 | 0x00, /* TWL6040_DMICBCTL 0x0B */ |
121 | 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ | 121 | 0x00, /* TWL6040_MICLCTL 0x0C */ |
122 | 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ | 122 | 0x00, /* TWL6040_MICRCTL 0x0D */ |
123 | 0x00, /* TWL6040_MICGAIN 0x0E */ | 123 | 0x00, /* TWL6040_MICGAIN 0x0E */ |
124 | 0x1B, /* TWL6040_LINEGAIN 0x0F */ | 124 | 0x1B, /* TWL6040_LINEGAIN 0x0F */ |
125 | 0x00, /* TWL6040_HSLCTL 0x10 */ | 125 | 0x00, /* TWL6040_HSLCTL 0x10 */ |
@@ -155,41 +155,8 @@ static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { | |||
155 | 0x00, /* TWL6040_STATUS (ro) 0x2E */ | 155 | 0x00, /* TWL6040_STATUS (ro) 0x2E */ |
156 | }; | 156 | }; |
157 | 157 | ||
158 | /* | 158 | /* List of registers to be restored after power up */ |
159 | * twl6040 vio/gnd registers: | 159 | static const int twl6040_restore_list[] = { |
160 | * registers under vio/gnd supply can be accessed | ||
161 | * before the power-up sequence, after NRESPWRON goes high | ||
162 | */ | ||
163 | static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = { | ||
164 | TWL6040_REG_ASICID, | ||
165 | TWL6040_REG_ASICREV, | ||
166 | TWL6040_REG_INTID, | ||
167 | TWL6040_REG_INTMR, | ||
168 | TWL6040_REG_NCPCTL, | ||
169 | TWL6040_REG_LDOCTL, | ||
170 | TWL6040_REG_AMICBCTL, | ||
171 | TWL6040_REG_DMICBCTL, | ||
172 | TWL6040_REG_HKCTL1, | ||
173 | TWL6040_REG_HKCTL2, | ||
174 | TWL6040_REG_GPOCTL, | ||
175 | TWL6040_REG_TRIM1, | ||
176 | TWL6040_REG_TRIM2, | ||
177 | TWL6040_REG_TRIM3, | ||
178 | TWL6040_REG_HSOTRIM, | ||
179 | TWL6040_REG_HFOTRIM, | ||
180 | TWL6040_REG_ACCCTL, | ||
181 | TWL6040_REG_STATUS, | ||
182 | }; | ||
183 | |||
184 | /* | ||
185 | * twl6040 vdd/vss registers: | ||
186 | * registers under vdd/vss supplies can only be accessed | ||
187 | * after the power-up sequence | ||
188 | */ | ||
189 | static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { | ||
190 | TWL6040_REG_HPPLLCTL, | ||
191 | TWL6040_REG_LPPLLCTL, | ||
192 | TWL6040_REG_LPPLLDIV, | ||
193 | TWL6040_REG_MICLCTL, | 160 | TWL6040_REG_MICLCTL, |
194 | TWL6040_REG_MICRCTL, | 161 | TWL6040_REG_MICRCTL, |
195 | TWL6040_REG_MICGAIN, | 162 | TWL6040_REG_MICGAIN, |
@@ -202,12 +169,6 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { | |||
202 | TWL6040_REG_HFLGAIN, | 169 | TWL6040_REG_HFLGAIN, |
203 | TWL6040_REG_HFRCTL, | 170 | TWL6040_REG_HFRCTL, |
204 | TWL6040_REG_HFRGAIN, | 171 | TWL6040_REG_HFRGAIN, |
205 | TWL6040_REG_VIBCTLL, | ||
206 | TWL6040_REG_VIBDATL, | ||
207 | TWL6040_REG_VIBCTLR, | ||
208 | TWL6040_REG_VIBDATR, | ||
209 | TWL6040_REG_ALB, | ||
210 | TWL6040_REG_DLB, | ||
211 | }; | 172 | }; |
212 | 173 | ||
213 | /* set of rates for each pll: low-power and high-performance */ | 174 | /* set of rates for each pll: low-power and high-performance */ |
@@ -296,56 +257,27 @@ static int twl6040_write(struct snd_soc_codec *codec, | |||
296 | return twl6040_reg_write(twl6040, reg, value); | 257 | return twl6040_reg_write(twl6040, reg, value); |
297 | } | 258 | } |
298 | 259 | ||
299 | static void twl6040_init_vio_regs(struct snd_soc_codec *codec) | 260 | static void twl6040_init_chip(struct snd_soc_codec *codec) |
300 | { | 261 | { |
301 | u8 *cache = codec->reg_cache; | 262 | struct twl6040 *twl6040 = codec->control_data; |
302 | int reg, i; | 263 | u8 val; |
303 | 264 | ||
304 | for (i = 0; i < TWL6040_VIOREGNUM; i++) { | 265 | val = twl6040_get_revid(twl6040); |
305 | reg = twl6040_vio_reg[i]; | 266 | twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val); |
306 | /* | 267 | |
307 | * skip read-only registers (ASICID, ASICREV, STATUS) | 268 | /* Change chip defaults */ |
308 | * and registers shared among MFD children | 269 | /* No imput selected for microphone amplifiers */ |
309 | */ | 270 | twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18); |
310 | switch (reg) { | 271 | twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18); |
311 | case TWL6040_REG_ASICID: | ||
312 | case TWL6040_REG_ASICREV: | ||
313 | case TWL6040_REG_INTID: | ||
314 | case TWL6040_REG_INTMR: | ||
315 | case TWL6040_REG_NCPCTL: | ||
316 | case TWL6040_REG_LDOCTL: | ||
317 | case TWL6040_REG_GPOCTL: | ||
318 | case TWL6040_REG_ACCCTL: | ||
319 | case TWL6040_REG_STATUS: | ||
320 | continue; | ||
321 | default: | ||
322 | break; | ||
323 | } | ||
324 | twl6040_write(codec, reg, cache[reg]); | ||
325 | } | ||
326 | } | 272 | } |
327 | 273 | ||
328 | static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) | 274 | static void twl6040_restore_regs(struct snd_soc_codec *codec) |
329 | { | 275 | { |
330 | u8 *cache = codec->reg_cache; | 276 | u8 *cache = codec->reg_cache; |
331 | int reg, i; | 277 | int reg, i; |
332 | 278 | ||
333 | for (i = 0; i < TWL6040_VDDREGNUM; i++) { | 279 | for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) { |
334 | reg = twl6040_vdd_reg[i]; | 280 | reg = twl6040_restore_list[i]; |
335 | /* skip vibra and PLL registers */ | ||
336 | switch (reg) { | ||
337 | case TWL6040_REG_VIBCTLL: | ||
338 | case TWL6040_REG_VIBDATL: | ||
339 | case TWL6040_REG_VIBCTLR: | ||
340 | case TWL6040_REG_VIBDATR: | ||
341 | case TWL6040_REG_HPPLLCTL: | ||
342 | case TWL6040_REG_LPPLLCTL: | ||
343 | case TWL6040_REG_LPPLLDIV: | ||
344 | continue; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | twl6040_write(codec, reg, cache[reg]); | 281 | twl6040_write(codec, reg, cache[reg]); |
350 | } | 282 | } |
351 | } | 283 | } |
@@ -1325,8 +1257,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, | |||
1325 | 1257 | ||
1326 | priv->codec_powered = 1; | 1258 | priv->codec_powered = 1; |
1327 | 1259 | ||
1328 | /* initialize vdd/vss registers with reg_cache */ | 1260 | twl6040_restore_regs(codec); |
1329 | twl6040_init_vdd_regs(codec); | ||
1330 | 1261 | ||
1331 | /* Set external boost GPO */ | 1262 | /* Set external boost GPO */ |
1332 | twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); | 1263 | twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); |
@@ -1468,7 +1399,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = { | |||
1468 | .playback = { | 1399 | .playback = { |
1469 | .stream_name = "Playback", | 1400 | .stream_name = "Playback", |
1470 | .channels_min = 1, | 1401 | .channels_min = 1, |
1471 | .channels_max = 2, | 1402 | .channels_max = 5, |
1472 | .rates = TWL6040_RATES, | 1403 | .rates = TWL6040_RATES, |
1473 | .formats = TWL6040_FORMATS, | 1404 | .formats = TWL6040_FORMATS, |
1474 | }, | 1405 | }, |
@@ -1518,8 +1449,8 @@ static struct snd_soc_dai_driver twl6040_dai[] = { | |||
1518 | .name = "twl6040-vib", | 1449 | .name = "twl6040-vib", |
1519 | .playback = { | 1450 | .playback = { |
1520 | .stream_name = "Vibra Playback", | 1451 | .stream_name = "Vibra Playback", |
1521 | .channels_min = 2, | 1452 | .channels_min = 1, |
1522 | .channels_max = 2, | 1453 | .channels_max = 1, |
1523 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | 1454 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
1524 | .formats = TWL6040_FORMATS, | 1455 | .formats = TWL6040_FORMATS, |
1525 | }, | 1456 | }, |
@@ -1620,8 +1551,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
1620 | goto plugirq_err; | 1551 | goto plugirq_err; |
1621 | } | 1552 | } |
1622 | 1553 | ||
1623 | /* init vio registers */ | 1554 | twl6040_init_chip(codec); |
1624 | twl6040_init_vio_regs(codec); | ||
1625 | 1555 | ||
1626 | /* power on device */ | 1556 | /* power on device */ |
1627 | ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1557 | ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |