aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl6040.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2011-09-15 08:39:27 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-19 18:15:57 -0400
commita52762eee97d42344691c190cf8786dd9edde4d7 (patch)
tree2aae3f80b46004cb010245c97870894dc78ef660 /sound/soc/codecs/twl6040.c
parent77f63e06cb5d5127e6f78347db01e092b97e111e (diff)
ASoC: twl6040: Chip initialization cleanup
There is no need to write to the vio registers at probe time, since most them either read only, or shared with MFD or not used. On the other hand it is a good idea to updated the ASICREV register in the cache at this time. After power up we need to restore some registers. Clean up the list to contain only the registers we are going to restore. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/twl6040.c')
-rw-r--r--sound/soc/codecs/twl6040.c100
1 files changed, 13 insertions, 87 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 443032b3b329..8bbd46a9bfd5 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -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: 159static 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 */
163static 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 */
189static 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,23 @@ 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
299static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 260static 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;
264
265 val = twl6040_get_revid(twl6040);
266 twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
303 267
304 for (i = 0; i < TWL6040_VIOREGNUM; i++) {
305 reg = twl6040_vio_reg[i];
306 /*
307 * skip read-only registers (ASICID, ASICREV, STATUS)
308 * and registers shared among MFD children
309 */
310 switch (reg) {
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} 268}
327 269
328static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) 270static void twl6040_restore_regs(struct snd_soc_codec *codec)
329{ 271{
330 u8 *cache = codec->reg_cache; 272 u8 *cache = codec->reg_cache;
331 int reg, i; 273 int reg, i;
332 274
333 for (i = 0; i < TWL6040_VDDREGNUM; i++) { 275 for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) {
334 reg = twl6040_vdd_reg[i]; 276 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]); 277 twl6040_write(codec, reg, cache[reg]);
350 } 278 }
351} 279}
@@ -1325,8 +1253,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1325 1253
1326 priv->codec_powered = 1; 1254 priv->codec_powered = 1;
1327 1255
1328 /* initialize vdd/vss registers with reg_cache */ 1256 twl6040_restore_regs(codec);
1329 twl6040_init_vdd_regs(codec);
1330 1257
1331 /* Set external boost GPO */ 1258 /* Set external boost GPO */
1332 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); 1259 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
@@ -1620,8 +1547,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1620 goto plugirq_err; 1547 goto plugirq_err;
1621 } 1548 }
1622 1549
1623 /* init vio registers */ 1550 twl6040_init_chip(codec);
1624 twl6040_init_vio_regs(codec);
1625 1551
1626 /* power on device */ 1552 /* power on device */
1627 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1553 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);