aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-02-01 14:05:09 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-02-04 05:40:55 -0500
commit3bf6e4217e3c69438f6dc41a009664107eb27ab1 (patch)
tree0827e573f190abc1aef7a1c9cb12b3d4486ad2a0 /sound/soc
parenta3032b47c46920ed3f2fd58e64f484e3dab49f23 (diff)
ASoC: Convert WM8993 to use shared cache I/O code
Saves a little bit of code duplication. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wm8993.c152
1 files changed, 43 insertions, 109 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 61239e0e9556..3c9336cd4eeb 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -231,34 +231,6 @@ struct wm8993_priv {
231 int fll_src; 231 int fll_src;
232}; 232};
233 233
234static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
235{
236 struct i2c_msg xfer[2];
237 u16 data;
238 int ret;
239 struct i2c_client *i2c = codec->control_data;
240
241 /* Write register */
242 xfer[0].addr = i2c->addr;
243 xfer[0].flags = 0;
244 xfer[0].len = 1;
245 xfer[0].buf = &reg;
246
247 /* Read data */
248 xfer[1].addr = i2c->addr;
249 xfer[1].flags = I2C_M_RD;
250 xfer[1].len = 2;
251 xfer[1].buf = (u8 *)&data;
252
253 ret = i2c_transfer(i2c->adapter, xfer, 2);
254 if (ret != 2) {
255 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
256 return 0;
257 }
258
259 return (data >> 8) | ((data & 0xff) << 8);
260}
261
262static int wm8993_volatile(unsigned int reg) 234static int wm8993_volatile(unsigned int reg)
263{ 235{
264 switch (reg) { 236 switch (reg) {
@@ -273,48 +245,6 @@ static int wm8993_volatile(unsigned int reg)
273 } 245 }
274} 246}
275 247
276static unsigned int wm8993_read(struct snd_soc_codec *codec,
277 unsigned int reg)
278{
279 u16 *reg_cache = codec->reg_cache;
280
281 BUG_ON(reg > WM8993_MAX_REGISTER);
282
283 if (wm8993_volatile(reg))
284 return wm8993_read_hw(codec, reg);
285 else
286 return reg_cache[reg];
287}
288
289static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
290 unsigned int value)
291{
292 u16 *reg_cache = codec->reg_cache;
293 u8 data[3];
294 int ret;
295
296 BUG_ON(reg > WM8993_MAX_REGISTER);
297
298 /* data is
299 * D15..D9 WM8993 register offset
300 * D8...D0 register data
301 */
302 data[0] = reg;
303 data[1] = value >> 8;
304 data[2] = value & 0x00ff;
305
306 if (!wm8993_volatile(reg))
307 reg_cache[reg] = value;
308
309 ret = codec->hw_write(codec->control_data, data, 3);
310
311 if (ret == 3)
312 return 0;
313 if (ret < 0)
314 return ret;
315 return -EIO;
316}
317
318struct _fll_div { 248struct _fll_div {
319 u16 fll_fratio; 249 u16 fll_fratio;
320 u16 fll_outdiv; 250 u16 fll_outdiv;
@@ -443,9 +373,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
443 wm8993->fll_fref = 0; 373 wm8993->fll_fref = 0;
444 wm8993->fll_fout = 0; 374 wm8993->fll_fout = 0;
445 375
446 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 376 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
447 reg1 &= ~WM8993_FLL_ENA; 377 reg1 &= ~WM8993_FLL_ENA;
448 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 378 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
449 379
450 return 0; 380 return 0;
451 } 381 }
@@ -454,7 +384,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
454 if (ret != 0) 384 if (ret != 0)
455 return ret; 385 return ret;
456 386
457 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 387 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
458 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 388 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
459 389
460 switch (fll_id) { 390 switch (fll_id) {
@@ -476,33 +406,33 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
476 406
477 /* Any FLL configuration change requires that the FLL be 407 /* Any FLL configuration change requires that the FLL be
478 * disabled first. */ 408 * disabled first. */
479 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 409 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
480 reg1 &= ~WM8993_FLL_ENA; 410 reg1 &= ~WM8993_FLL_ENA;
481 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 411 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
482 412
483 /* Apply the configuration */ 413 /* Apply the configuration */
484 if (fll_div.k) 414 if (fll_div.k)
485 reg1 |= WM8993_FLL_FRAC_MASK; 415 reg1 |= WM8993_FLL_FRAC_MASK;
486 else 416 else
487 reg1 &= ~WM8993_FLL_FRAC_MASK; 417 reg1 &= ~WM8993_FLL_FRAC_MASK;
488 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 418 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
489 419
490 wm8993_write(codec, WM8993_FLL_CONTROL_2, 420 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
491 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 421 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
492 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 422 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
493 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 423 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
494 424
495 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 425 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
496 reg4 &= ~WM8993_FLL_N_MASK; 426 reg4 &= ~WM8993_FLL_N_MASK;
497 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 427 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
498 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 428 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
499 429
500 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 430 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
501 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 431 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
502 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 432 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
503 433
504 /* Enable the FLL */ 434 /* Enable the FLL */
505 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 435 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
506 436
507 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 437 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
508 438
@@ -523,7 +453,7 @@ static int configure_clock(struct snd_soc_codec *codec)
523 case WM8993_SYSCLK_MCLK: 453 case WM8993_SYSCLK_MCLK:
524 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 454 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
525 455
526 reg = wm8993_read(codec, WM8993_CLOCKING_2); 456 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
527 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 457 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
528 if (wm8993->mclk_rate > 13500000) { 458 if (wm8993->mclk_rate > 13500000) {
529 reg |= WM8993_MCLK_DIV; 459 reg |= WM8993_MCLK_DIV;
@@ -532,14 +462,14 @@ static int configure_clock(struct snd_soc_codec *codec)
532 reg &= ~WM8993_MCLK_DIV; 462 reg &= ~WM8993_MCLK_DIV;
533 wm8993->sysclk_rate = wm8993->mclk_rate; 463 wm8993->sysclk_rate = wm8993->mclk_rate;
534 } 464 }
535 wm8993_write(codec, WM8993_CLOCKING_2, reg); 465 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
536 break; 466 break;
537 467
538 case WM8993_SYSCLK_FLL: 468 case WM8993_SYSCLK_FLL:
539 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 469 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
540 wm8993->fll_fout); 470 wm8993->fll_fout);
541 471
542 reg = wm8993_read(codec, WM8993_CLOCKING_2); 472 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
543 reg |= WM8993_SYSCLK_SRC; 473 reg |= WM8993_SYSCLK_SRC;
544 if (wm8993->fll_fout > 13500000) { 474 if (wm8993->fll_fout > 13500000) {
545 reg |= WM8993_MCLK_DIV; 475 reg |= WM8993_MCLK_DIV;
@@ -548,7 +478,7 @@ static int configure_clock(struct snd_soc_codec *codec)
548 reg &= ~WM8993_MCLK_DIV; 478 reg &= ~WM8993_MCLK_DIV;
549 wm8993->sysclk_rate = wm8993->fll_fout; 479 wm8993->sysclk_rate = wm8993->fll_fout;
550 } 480 }
551 wm8993_write(codec, WM8993_CLOCKING_2, reg); 481 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
552 break; 482 break;
553 483
554 default: 484 default:
@@ -1083,8 +1013,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1083{ 1013{
1084 struct snd_soc_codec *codec = dai->codec; 1014 struct snd_soc_codec *codec = dai->codec;
1085 struct wm8993_priv *wm8993 = codec->private_data; 1015 struct wm8993_priv *wm8993 = codec->private_data;
1086 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1016 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1087 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1017 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1088 1018
1089 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1019 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1090 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1020 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1167,8 +1097,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1167 return -EINVAL; 1097 return -EINVAL;
1168 } 1098 }
1169 1099
1170 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1100 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1171 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1101 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1172 1102
1173 return 0; 1103 return 0;
1174} 1104}
@@ -1182,16 +1112,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1182 int ret, i, best, best_val, cur_val; 1112 int ret, i, best, best_val, cur_val;
1183 unsigned int clocking1, clocking3, aif1, aif4; 1113 unsigned int clocking1, clocking3, aif1, aif4;
1184 1114
1185 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1115 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1186 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1116 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1187 1117
1188 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1118 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1189 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1119 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1190 1120
1191 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1121 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1192 aif1 &= ~WM8993_AIF_WL_MASK; 1122 aif1 &= ~WM8993_AIF_WL_MASK;
1193 1123
1194 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1124 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1195 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1125 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1196 1126
1197 /* What BCLK do we need? */ 1127 /* What BCLK do we need? */
@@ -1284,14 +1214,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1284 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); 1214 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1285 aif4 |= wm8993->bclk / wm8993->fs; 1215 aif4 |= wm8993->bclk / wm8993->fs;
1286 1216
1287 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1217 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1288 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1218 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1289 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1219 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1290 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1220 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1291 1221
1292 /* ReTune Mobile? */ 1222 /* ReTune Mobile? */
1293 if (wm8993->pdata.num_retune_configs) { 1223 if (wm8993->pdata.num_retune_configs) {
1294 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1224 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1295 struct wm8993_retune_mobile_setting *s; 1225 struct wm8993_retune_mobile_setting *s;
1296 1226
1297 best = 0; 1227 best = 0;
@@ -1314,7 +1244,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1314 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1244 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1315 1245
1316 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1246 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1317 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1247 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1318 1248
1319 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1249 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1320 } 1250 }
@@ -1327,14 +1257,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1327 struct snd_soc_codec *codec = codec_dai->codec; 1257 struct snd_soc_codec *codec = codec_dai->codec;
1328 unsigned int reg; 1258 unsigned int reg;
1329 1259
1330 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1260 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1331 1261
1332 if (mute) 1262 if (mute)
1333 reg |= WM8993_DAC_MUTE; 1263 reg |= WM8993_DAC_MUTE;
1334 else 1264 else
1335 reg &= ~WM8993_DAC_MUTE; 1265 reg &= ~WM8993_DAC_MUTE;
1336 1266
1337 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1267 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1338 1268
1339 return 0; 1269 return 0;
1340} 1270}
@@ -1586,9 +1516,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1586 INIT_LIST_HEAD(&codec->dapm_paths); 1516 INIT_LIST_HEAD(&codec->dapm_paths);
1587 1517
1588 codec->name = "WM8993"; 1518 codec->name = "WM8993";
1589 codec->read = wm8993_read; 1519 codec->volatile_register = wm8993_volatile;
1590 codec->write = wm8993_write;
1591 codec->hw_write = (hw_write_t)i2c_master_send;
1592 codec->reg_cache = wm8993->reg_cache; 1520 codec->reg_cache = wm8993->reg_cache;
1593 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1521 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1594 codec->bias_level = SND_SOC_BIAS_OFF; 1522 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1603,20 +1531,26 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1603 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1531 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1604 sizeof(wm8993->reg_cache)); 1532 sizeof(wm8993->reg_cache));
1605 1533
1534 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1535 if (ret != 0) {
1536 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1537 goto err;
1538 }
1539
1606 i2c_set_clientdata(i2c, wm8993); 1540 i2c_set_clientdata(i2c, wm8993);
1607 codec->control_data = i2c; 1541 codec->control_data = i2c;
1608 wm8993_codec = codec; 1542 wm8993_codec = codec;
1609 1543
1610 codec->dev = &i2c->dev; 1544 codec->dev = &i2c->dev;
1611 1545
1612 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1546 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1613 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1547 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1614 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1548 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1615 ret = -EINVAL; 1549 ret = -EINVAL;
1616 goto err; 1550 goto err;
1617 } 1551 }
1618 1552
1619 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1553 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1620 if (ret != 0) 1554 if (ret != 0)
1621 goto err; 1555 goto err;
1622 1556