aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8731.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-07 06:43:58 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-07 06:43:58 -0400
commit06cddefc1f25b847dafe392f3d5781482b3395b5 (patch)
tree97f4df2e4ae6a1e8194ca67ede1b552802ba2334 /sound/soc/codecs/wm8731.c
parentb9b5cc26d0b3a9b361cc56c3a3b0d6f819b9195f (diff)
parent27ded041f03026e8c6be9efc626e11ddfb4620c1 (diff)
Merge branch 'reg-cache' into for-2.6.32
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r--sound/soc/codecs/wm8731.c141
1 files changed, 33 insertions, 108 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 156002852078..2b980ccb6032 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -51,60 +51,12 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
51 * There is no point in caching the reset register 51 * There is no point in caching the reset register
52 */ 52 */
53static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 53static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
54 0x0097, 0x0097, 0x0079, 0x0079, 54 0x0097, 0x0097, 0x0079, 0x0079,
55 0x000a, 0x0008, 0x009f, 0x000a, 55 0x000a, 0x0008, 0x009f, 0x000a,
56 0x0000, 0x0000 56 0x0000, 0x0000
57}; 57};
58 58
59/* 59#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
60 * read wm8731 register cache
61 */
62static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec,
63 unsigned int reg)
64{
65 u16 *cache = codec->reg_cache;
66 if (reg == WM8731_RESET)
67 return 0;
68 if (reg >= WM8731_CACHEREGNUM)
69 return -1;
70 return cache[reg];
71}
72
73/*
74 * write wm8731 register cache
75 */
76static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec,
77 u16 reg, unsigned int value)
78{
79 u16 *cache = codec->reg_cache;
80 if (reg >= WM8731_CACHEREGNUM)
81 return;
82 cache[reg] = value;
83}
84
85/*
86 * write to the WM8731 register space
87 */
88static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg,
89 unsigned int value)
90{
91 u8 data[2];
92
93 /* data is
94 * D15..D9 WM8731 register offset
95 * D8...D0 register data
96 */
97 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
98 data[1] = value & 0x00ff;
99
100 wm8731_write_reg_cache(codec, reg, value);
101 if (codec->hw_write(codec->control_data, data, 2) == 2)
102 return 0;
103 else
104 return -EIO;
105}
106
107#define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0)
108 60
109static const char *wm8731_input_select[] = {"Line In", "Mic"}; 61static const char *wm8731_input_select[] = {"Line In", "Mic"};
110static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 62static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
@@ -267,12 +219,12 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
267 struct snd_soc_device *socdev = rtd->socdev; 219 struct snd_soc_device *socdev = rtd->socdev;
268 struct snd_soc_codec *codec = socdev->card->codec; 220 struct snd_soc_codec *codec = socdev->card->codec;
269 struct wm8731_priv *wm8731 = codec->private_data; 221 struct wm8731_priv *wm8731 = codec->private_data;
270 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; 222 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
271 int i = get_coeff(wm8731->sysclk, params_rate(params)); 223 int i = get_coeff(wm8731->sysclk, params_rate(params));
272 u16 srate = (coeff_div[i].sr << 2) | 224 u16 srate = (coeff_div[i].sr << 2) |
273 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 225 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
274 226
275 wm8731_write(codec, WM8731_SRATE, srate); 227 snd_soc_write(codec, WM8731_SRATE, srate);
276 228
277 /* bit size */ 229 /* bit size */
278 switch (params_format(params)) { 230 switch (params_format(params)) {
@@ -286,7 +238,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
286 break; 238 break;
287 } 239 }
288 240
289 wm8731_write(codec, WM8731_IFACE, iface); 241 snd_soc_write(codec, WM8731_IFACE, iface);
290 return 0; 242 return 0;
291} 243}
292 244
@@ -298,7 +250,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
298 struct snd_soc_codec *codec = socdev->card->codec; 250 struct snd_soc_codec *codec = socdev->card->codec;
299 251
300 /* set active */ 252 /* set active */
301 wm8731_write(codec, WM8731_ACTIVE, 0x0001); 253 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
302 254
303 return 0; 255 return 0;
304} 256}
@@ -313,19 +265,19 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream,
313 /* deactivate */ 265 /* deactivate */
314 if (!codec->active) { 266 if (!codec->active) {
315 udelay(50); 267 udelay(50);
316 wm8731_write(codec, WM8731_ACTIVE, 0x0); 268 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
317 } 269 }
318} 270}
319 271
320static int wm8731_mute(struct snd_soc_dai *dai, int mute) 272static int wm8731_mute(struct snd_soc_dai *dai, int mute)
321{ 273{
322 struct snd_soc_codec *codec = dai->codec; 274 struct snd_soc_codec *codec = dai->codec;
323 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; 275 u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
324 276
325 if (mute) 277 if (mute)
326 wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8); 278 snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
327 else 279 else
328 wm8731_write(codec, WM8731_APDIGI, mute_reg); 280 snd_soc_write(codec, WM8731_APDIGI, mute_reg);
329 return 0; 281 return 0;
330} 282}
331 283
@@ -403,7 +355,7 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
403 } 355 }
404 356
405 /* set iface */ 357 /* set iface */
406 wm8731_write(codec, WM8731_IFACE, iface); 358 snd_soc_write(codec, WM8731_IFACE, iface);
407 return 0; 359 return 0;
408} 360}
409 361
@@ -419,12 +371,12 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
419 break; 371 break;
420 case SND_SOC_BIAS_STANDBY: 372 case SND_SOC_BIAS_STANDBY:
421 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 373 /* Clear PWROFF, gate CLKOUT, everything else as-is */
422 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 374 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
423 wm8731_write(codec, WM8731_PWR, reg | 0x0040); 375 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
424 break; 376 break;
425 case SND_SOC_BIAS_OFF: 377 case SND_SOC_BIAS_OFF:
426 wm8731_write(codec, WM8731_ACTIVE, 0x0); 378 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_write(codec, WM8731_PWR, 0xffff); 379 snd_soc_write(codec, WM8731_PWR, 0xffff);
428 break; 380 break;
429 } 381 }
430 codec->bias_level = level; 382 codec->bias_level = level;
@@ -474,7 +426,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
474 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 426 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
475 struct snd_soc_codec *codec = socdev->card->codec; 427 struct snd_soc_codec *codec = socdev->card->codec;
476 428
477 wm8731_write(codec, WM8731_ACTIVE, 0x0); 429 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
478 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 430 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
479 return 0; 431 return 0;
480} 432}
@@ -560,11 +512,11 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
560}; 512};
561EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 513EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
562 514
563static int wm8731_register(struct wm8731_priv *wm8731) 515static int wm8731_register(struct wm8731_priv *wm8731,
516 enum snd_soc_control_type control)
564{ 517{
565 int ret; 518 int ret;
566 struct snd_soc_codec *codec = &wm8731->codec; 519 struct snd_soc_codec *codec = &wm8731->codec;
567 u16 reg;
568 520
569 if (wm8731_codec) { 521 if (wm8731_codec) {
570 dev_err(codec->dev, "Another WM8731 is registered\n"); 522 dev_err(codec->dev, "Another WM8731 is registered\n");
@@ -579,8 +531,6 @@ static int wm8731_register(struct wm8731_priv *wm8731)
579 codec->private_data = wm8731; 531 codec->private_data = wm8731;
580 codec->name = "WM8731"; 532 codec->name = "WM8731";
581 codec->owner = THIS_MODULE; 533 codec->owner = THIS_MODULE;
582 codec->read = wm8731_read_reg_cache;
583 codec->write = wm8731_write;
584 codec->bias_level = SND_SOC_BIAS_OFF; 534 codec->bias_level = SND_SOC_BIAS_OFF;
585 codec->set_bias_level = wm8731_set_bias_level; 535 codec->set_bias_level = wm8731_set_bias_level;
586 codec->dai = &wm8731_dai; 536 codec->dai = &wm8731_dai;
@@ -590,6 +540,12 @@ static int wm8731_register(struct wm8731_priv *wm8731)
590 540
591 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 541 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
592 542
543 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
544 if (ret < 0) {
545 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
546 goto err;
547 }
548
593 ret = wm8731_reset(codec); 549 ret = wm8731_reset(codec);
594 if (ret < 0) { 550 if (ret < 0) {
595 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 551 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
@@ -601,18 +557,13 @@ static int wm8731_register(struct wm8731_priv *wm8731)
601 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 557 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
602 558
603 /* Latch the update bits */ 559 /* Latch the update bits */
604 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); 560 snd_soc_update_bits(codec, WM8731_LOUT1V, 0x100, 0);
605 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); 561 snd_soc_update_bits(codec, WM8731_ROUT1V, 0x100, 0);
606 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); 562 snd_soc_update_bits(codec, WM8731_LINVOL, 0x100, 0);
607 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); 563 snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
608 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
609 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
610 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
611 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
612 564
613 /* Disable bypass path by default */ 565 /* Disable bypass path by default */
614 reg = wm8731_read_reg_cache(codec, WM8731_APANA); 566 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
615 wm8731_write(codec, WM8731_APANA, reg & ~0x4);
616 567
617 wm8731_codec = codec; 568 wm8731_codec = codec;
618 569
@@ -648,30 +599,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
648} 599}
649 600
650#if defined(CONFIG_SPI_MASTER) 601#if defined(CONFIG_SPI_MASTER)
651static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
652{
653 struct spi_transfer t;
654 struct spi_message m;
655 u8 msg[2];
656
657 if (len <= 0)
658 return 0;
659
660 msg[0] = data[0];
661 msg[1] = data[1];
662
663 spi_message_init(&m);
664 memset(&t, 0, (sizeof t));
665
666 t.tx_buf = &msg[0];
667 t.len = len;
668
669 spi_message_add_tail(&t, &m);
670 spi_sync(spi, &m);
671
672 return len;
673}
674
675static int __devinit wm8731_spi_probe(struct spi_device *spi) 602static int __devinit wm8731_spi_probe(struct spi_device *spi)
676{ 603{
677 struct snd_soc_codec *codec; 604 struct snd_soc_codec *codec;
@@ -683,12 +610,11 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
683 610
684 codec = &wm8731->codec; 611 codec = &wm8731->codec;
685 codec->control_data = spi; 612 codec->control_data = spi;
686 codec->hw_write = (hw_write_t)wm8731_spi_write;
687 codec->dev = &spi->dev; 613 codec->dev = &spi->dev;
688 614
689 dev_set_drvdata(&spi->dev, wm8731); 615 dev_set_drvdata(&spi->dev, wm8731);
690 616
691 return wm8731_register(wm8731); 617 return wm8731_register(wm8731, SND_SOC_SPI);
692} 618}
693 619
694static int __devexit wm8731_spi_remove(struct spi_device *spi) 620static int __devexit wm8731_spi_remove(struct spi_device *spi)
@@ -740,14 +666,13 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
740 return -ENOMEM; 666 return -ENOMEM;
741 667
742 codec = &wm8731->codec; 668 codec = &wm8731->codec;
743 codec->hw_write = (hw_write_t)i2c_master_send;
744 669
745 i2c_set_clientdata(i2c, wm8731); 670 i2c_set_clientdata(i2c, wm8731);
746 codec->control_data = i2c; 671 codec->control_data = i2c;
747 672
748 codec->dev = &i2c->dev; 673 codec->dev = &i2c->dev;
749 674
750 return wm8731_register(wm8731); 675 return wm8731_register(wm8731, SND_SOC_I2C);
751} 676}
752 677
753static __devexit int wm8731_i2c_remove(struct i2c_client *client) 678static __devexit int wm8731_i2c_remove(struct i2c_client *client)