aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8731.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r--sound/soc/codecs/wm8731.c217
1 files changed, 66 insertions, 151 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b6355297..7da360ee1fee 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -32,9 +32,6 @@
32 32
33#include "wm8731.h" 33#include "wm8731.h"
34 34
35static struct snd_soc_codec *wm8731_codec;
36struct snd_soc_codec_device soc_codec_dev_wm8731;
37
38#define WM8731_NUM_SUPPLIES 4 35#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { 36static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD", 37 "AVDD",
@@ -45,7 +42,8 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45 42
46/* codec private data */ 43/* codec private data */
47struct wm8731_priv { 44struct wm8731_priv {
48 struct snd_soc_codec codec; 45 enum snd_soc_control_type control_type;
46 void *control_data;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 47 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
50 u16 reg_cache[WM8731_CACHEREGNUM]; 48 u16 reg_cache[WM8731_CACHEREGNUM];
51 unsigned int sysclk; 49 unsigned int sysclk;
@@ -222,9 +220,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params, 220 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai) 221 struct snd_soc_dai *dai)
224{ 222{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_codec *codec = dai->codec;
226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 224 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 225 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 226 int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -252,9 +248,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
252static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 248static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai) 249 struct snd_soc_dai *dai)
254{ 250{
255 struct snd_soc_pcm_runtime *rtd = substream->private_data; 251 struct snd_soc_codec *codec = dai->codec;
256 struct snd_soc_device *socdev = rtd->socdev;
257 struct snd_soc_codec *codec = socdev->card->codec;
258 252
259 /* set active */ 253 /* set active */
260 snd_soc_write(codec, WM8731_ACTIVE, 0x0001); 254 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
@@ -265,9 +259,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
265static void wm8731_shutdown(struct snd_pcm_substream *substream, 259static void wm8731_shutdown(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai) 260 struct snd_soc_dai *dai)
267{ 261{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 262 struct snd_soc_codec *codec = dai->codec;
269 struct snd_soc_device *socdev = rtd->socdev;
270 struct snd_soc_codec *codec = socdev->card->codec;
271 263
272 /* deactivate */ 264 /* deactivate */
273 if (!codec->active) { 265 if (!codec->active) {
@@ -428,8 +420,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = {
428 .set_fmt = wm8731_set_dai_fmt, 420 .set_fmt = wm8731_set_dai_fmt,
429}; 421};
430 422
431struct snd_soc_dai wm8731_dai = { 423static struct snd_soc_dai_driver wm8731_dai = {
432 .name = "WM8731", 424 .name = "wm8731-hifi",
433 .playback = { 425 .playback = {
434 .stream_name = "Playback", 426 .stream_name = "Playback",
435 .channels_min = 1, 427 .channels_min = 1,
@@ -445,24 +437,17 @@ struct snd_soc_dai wm8731_dai = {
445 .ops = &wm8731_dai_ops, 437 .ops = &wm8731_dai_ops,
446 .symmetric_rates = 1, 438 .symmetric_rates = 1,
447}; 439};
448EXPORT_SYMBOL_GPL(wm8731_dai);
449 440
450#ifdef CONFIG_PM 441#ifdef CONFIG_PM
451static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 442static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
452{ 443{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec = socdev->card->codec;
455
456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 444 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
457 445
458 return 0; 446 return 0;
459} 447}
460 448
461static int wm8731_resume(struct platform_device *pdev) 449static int wm8731_resume(struct snd_soc_codec *codec)
462{ 450{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 451 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
467 452
468 return 0; 453 return 0;
@@ -472,88 +457,18 @@ static int wm8731_resume(struct platform_device *pdev)
472#define wm8731_resume NULL 457#define wm8731_resume NULL
473#endif 458#endif
474 459
475static int wm8731_probe(struct platform_device *pdev) 460static int wm8731_probe(struct snd_soc_codec *codec)
476{
477 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
478 struct snd_soc_codec *codec;
479 int ret = 0;
480
481 if (wm8731_codec == NULL) {
482 dev_err(&pdev->dev, "Codec device not registered\n");
483 return -ENODEV;
484 }
485
486 socdev->card->codec = wm8731_codec;
487 codec = wm8731_codec;
488
489 /* register pcms */
490 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
491 if (ret < 0) {
492 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
493 goto pcm_err;
494 }
495
496 snd_soc_add_controls(codec, wm8731_snd_controls,
497 ARRAY_SIZE(wm8731_snd_controls));
498 wm8731_add_widgets(codec);
499
500 return ret;
501
502pcm_err:
503 return ret;
504}
505
506/* power down chip */
507static int wm8731_remove(struct platform_device *pdev)
508{ 461{
509 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 462 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
510 463 int ret = 0, i;
511 snd_soc_free_pcms(socdev);
512 snd_soc_dapm_free(socdev);
513
514 return 0;
515}
516
517struct snd_soc_codec_device soc_codec_dev_wm8731 = {
518 .probe = wm8731_probe,
519 .remove = wm8731_remove,
520 .suspend = wm8731_suspend,
521 .resume = wm8731_resume,
522};
523EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
524
525static int wm8731_register(struct wm8731_priv *wm8731,
526 enum snd_soc_control_type control)
527{
528 int ret, i;
529 struct snd_soc_codec *codec = &wm8731->codec;
530
531 if (wm8731_codec) {
532 dev_err(codec->dev, "Another WM8731 is registered\n");
533 ret = -EINVAL;
534 goto err;
535 }
536
537 mutex_init(&codec->mutex);
538 INIT_LIST_HEAD(&codec->dapm_widgets);
539 INIT_LIST_HEAD(&codec->dapm_paths);
540
541 snd_soc_codec_set_drvdata(codec, wm8731);
542 codec->name = "WM8731";
543 codec->owner = THIS_MODULE;
544 codec->bias_level = SND_SOC_BIAS_OFF;
545 codec->set_bias_level = wm8731_set_bias_level;
546 codec->dai = &wm8731_dai;
547 codec->num_dai = 1;
548 codec->reg_cache_size = WM8731_CACHEREGNUM;
549 codec->reg_cache = &wm8731->reg_cache;
550 464
551 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 465 codec->bias_level = SND_SOC_BIAS_OFF,
466 codec->control_data = wm8731->control_data;
552 467
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 468 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
554 if (ret < 0) { 469 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
556 goto err; 471 return ret;
557 } 472 }
558 473
559 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) 474 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +478,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
563 wm8731->supplies); 478 wm8731->supplies);
564 if (ret != 0) { 479 if (ret != 0) {
565 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
566 goto err; 481 return ret;
567 } 482 }
568 483
569 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +494,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
579 goto err_regulator_enable; 494 goto err_regulator_enable;
580 } 495 }
581 496
582 wm8731_dai.dev = codec->dev;
583
584 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 497 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
585 498
586 /* Latch the update bits */ 499 /* Latch the update bits */
@@ -592,78 +505,79 @@ static int wm8731_register(struct wm8731_priv *wm8731,
592 /* Disable bypass path by default */ 505 /* Disable bypass path by default */
593 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); 506 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
594 507
595 wm8731_codec = codec; 508 snd_soc_add_controls(codec, wm8731_snd_controls,
596 509 ARRAY_SIZE(wm8731_snd_controls));
597 ret = snd_soc_register_codec(codec); 510 wm8731_add_widgets(codec);
598 if (ret != 0) {
599 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
600 goto err_regulator_enable;
601 }
602
603 ret = snd_soc_register_dai(&wm8731_dai);
604 if (ret != 0) {
605 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
606 snd_soc_unregister_codec(codec);
607 goto err_codec;
608 }
609 511
610 /* Regulators will have been enabled by bias management */ 512 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 513 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612 514
613 return 0; 515 return 0;
614 516
615err_codec:
616 snd_soc_unregister_codec(codec);
617err_regulator_enable: 517err_regulator_enable:
618 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 518 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
619err_regulator_get: 519err_regulator_get:
620 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 520 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
621err: 521
622 kfree(wm8731); 522 kfree(wm8731);
623 return ret; 523 return ret;
624} 524}
625 525
626static void wm8731_unregister(struct wm8731_priv *wm8731) 526/* power down chip */
527static int wm8731_remove(struct snd_soc_codec *codec)
627{ 528{
628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 529 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
629 snd_soc_unregister_dai(&wm8731_dai); 530
630 snd_soc_unregister_codec(&wm8731->codec); 531 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
532
533 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 534 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 535
633 wm8731_codec = NULL; 536 return 0;
634} 537}
635 538
539static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
540 .probe = wm8731_probe,
541 .remove = wm8731_remove,
542 .suspend = wm8731_suspend,
543 .resume = wm8731_resume,
544 .set_bias_level = wm8731_set_bias_level,
545 .reg_cache_size = sizeof(wm8731_reg),
546 .reg_word_size = sizeof(u16),
547 .reg_cache_default = wm8731_reg,
548};
549
636#if defined(CONFIG_SPI_MASTER) 550#if defined(CONFIG_SPI_MASTER)
637static int __devinit wm8731_spi_probe(struct spi_device *spi) 551static int __devinit wm8731_spi_probe(struct spi_device *spi)
638{ 552{
639 struct snd_soc_codec *codec;
640 struct wm8731_priv *wm8731; 553 struct wm8731_priv *wm8731;
554 int ret;
641 555
642 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 556 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
643 if (wm8731 == NULL) 557 if (wm8731 == NULL)
644 return -ENOMEM; 558 return -ENOMEM;
645 559
646 codec = &wm8731->codec; 560 wm8731->control_data = spi;
647 codec->control_data = spi; 561 wm8731->control_type = SND_SOC_SPI;
648 codec->dev = &spi->dev; 562 spi_set_drvdata(spi, wm8731);
649
650 dev_set_drvdata(&spi->dev, wm8731);
651 563
652 return wm8731_register(wm8731, SND_SOC_SPI); 564 ret = snd_soc_register_codec(&spi->dev,
565 &soc_codec_dev_wm8731, &wm8731_dai, 1);
566 if (ret < 0)
567 kfree(wm8731);
568 return ret;
653} 569}
654 570
655static int __devexit wm8731_spi_remove(struct spi_device *spi) 571static int __devexit wm8731_spi_remove(struct spi_device *spi)
656{ 572{
657 struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); 573 snd_soc_unregister_codec(&spi->dev);
658 574 kfree(spi_get_drvdata(spi));
659 wm8731_unregister(wm8731);
660
661 return 0; 575 return 0;
662} 576}
663 577
664static struct spi_driver wm8731_spi_driver = { 578static struct spi_driver wm8731_spi_driver = {
665 .driver = { 579 .driver = {
666 .name = "wm8731", 580 .name = "wm8731-codec",
667 .bus = &spi_bus_type, 581 .bus = &spi_bus_type,
668 .owner = THIS_MODULE, 582 .owner = THIS_MODULE,
669 }, 583 },
@@ -677,26 +591,27 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
677 const struct i2c_device_id *id) 591 const struct i2c_device_id *id)
678{ 592{
679 struct wm8731_priv *wm8731; 593 struct wm8731_priv *wm8731;
680 struct snd_soc_codec *codec; 594 int ret;
681 595
682 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 596 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
683 if (wm8731 == NULL) 597 if (wm8731 == NULL)
684 return -ENOMEM; 598 return -ENOMEM;
685 599
686 codec = &wm8731->codec;
687
688 i2c_set_clientdata(i2c, wm8731); 600 i2c_set_clientdata(i2c, wm8731);
689 codec->control_data = i2c; 601 wm8731->control_data = i2c;
602 wm8731->control_type = SND_SOC_I2C;
690 603
691 codec->dev = &i2c->dev; 604 ret = snd_soc_register_codec(&i2c->dev,
692 605 &soc_codec_dev_wm8731, &wm8731_dai, 1);
693 return wm8731_register(wm8731, SND_SOC_I2C); 606 if (ret < 0)
607 kfree(wm8731);
608 return ret;
694} 609}
695 610
696static __devexit int wm8731_i2c_remove(struct i2c_client *client) 611static __devexit int wm8731_i2c_remove(struct i2c_client *client)
697{ 612{
698 struct wm8731_priv *wm8731 = i2c_get_clientdata(client); 613 snd_soc_unregister_codec(&client->dev);
699 wm8731_unregister(wm8731); 614 kfree(i2c_get_clientdata(client));
700 return 0; 615 return 0;
701} 616}
702 617
@@ -708,7 +623,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 623
709static struct i2c_driver wm8731_i2c_driver = { 624static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 625 .driver = {
711 .name = "wm8731", 626 .name = "wm8731-codec",
712 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
713 }, 628 },
714 .probe = wm8731_i2c_probe, 629 .probe = wm8731_i2c_probe,
@@ -719,7 +634,7 @@ static struct i2c_driver wm8731_i2c_driver = {
719 634
720static int __init wm8731_modinit(void) 635static int __init wm8731_modinit(void)
721{ 636{
722 int ret; 637 int ret = 0;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 638#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8731_i2c_driver); 639 ret = i2c_add_driver(&wm8731_i2c_driver);
725 if (ret != 0) { 640 if (ret != 0) {
@@ -734,7 +649,7 @@ static int __init wm8731_modinit(void)
734 ret); 649 ret);
735 } 650 }
736#endif 651#endif
737 return 0; 652 return ret;
738} 653}
739module_init(wm8731_modinit); 654module_init(wm8731_modinit);
740 655