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.c245
1 files changed, 90 insertions, 155 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b6355297..631385802eb4 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,10 +42,11 @@ 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;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 46 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
50 u16 reg_cache[WM8731_CACHEREGNUM]; 47 u16 reg_cache[WM8731_CACHEREGNUM];
51 unsigned int sysclk; 48 unsigned int sysclk;
49 int sysclk_type;
52}; 50};
53 51
54 52
@@ -113,6 +111,7 @@ static const struct snd_kcontrol_new wm8731_input_mux_controls =
113SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); 111SOC_DAPM_ENUM("Input Select", wm8731_enum[0]);
114 112
115static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { 113static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
114SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
116SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, 115SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
117 &wm8731_output_mixer_controls[0], 116 &wm8731_output_mixer_controls[0],
118 ARRAY_SIZE(wm8731_output_mixer_controls)), 117 ARRAY_SIZE(wm8731_output_mixer_controls)),
@@ -130,7 +129,18 @@ SND_SOC_DAPM_INPUT("RLINEIN"),
130SND_SOC_DAPM_INPUT("LLINEIN"), 129SND_SOC_DAPM_INPUT("LLINEIN"),
131}; 130};
132 131
132static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
133 struct snd_soc_dapm_widget *sink)
134{
135 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec);
136
137 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK;
138}
139
133static const struct snd_soc_dapm_route intercon[] = { 140static const struct snd_soc_dapm_route intercon[] = {
141 {"DAC", NULL, "OSC", wm8731_check_osc},
142 {"ADC", NULL, "OSC", wm8731_check_osc},
143
134 /* output mixer */ 144 /* output mixer */
135 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 145 {"Output Mixer", "Line Bypass Switch", "Line Input"},
136 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 146 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -222,9 +232,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params, 232 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai) 233 struct snd_soc_dai *dai)
224{ 234{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 235 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); 236 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 237 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 238 int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -252,9 +260,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
252static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 260static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai) 261 struct snd_soc_dai *dai)
254{ 262{
255 struct snd_soc_pcm_runtime *rtd = substream->private_data; 263 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 264
259 /* set active */ 265 /* set active */
260 snd_soc_write(codec, WM8731_ACTIVE, 0x0001); 266 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
@@ -265,9 +271,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
265static void wm8731_shutdown(struct snd_pcm_substream *substream, 271static void wm8731_shutdown(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai) 272 struct snd_soc_dai *dai)
267{ 273{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 274 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 275
272 /* deactivate */ 276 /* deactivate */
273 if (!codec->active) { 277 if (!codec->active) {
@@ -294,6 +298,15 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
294 struct snd_soc_codec *codec = codec_dai->codec; 298 struct snd_soc_codec *codec = codec_dai->codec;
295 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 299 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
296 300
301 switch (clk_id) {
302 case WM8731_SYSCLK_XTAL:
303 case WM8731_SYSCLK_MCLK:
304 wm8731->sysclk_type = clk_id;
305 break;
306 default:
307 return -EINVAL;
308 }
309
297 switch (freq) { 310 switch (freq) {
298 case 11289600: 311 case 11289600:
299 case 12000000: 312 case 12000000:
@@ -301,9 +314,14 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
301 case 16934400: 314 case 16934400:
302 case 18432000: 315 case 18432000:
303 wm8731->sysclk = freq; 316 wm8731->sysclk = freq;
304 return 0; 317 break;
318 default:
319 return -EINVAL;
305 } 320 }
306 return -EINVAL; 321
322 snd_soc_dapm_sync(codec);
323
324 return 0;
307} 325}
308 326
309 327
@@ -428,8 +446,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = {
428 .set_fmt = wm8731_set_dai_fmt, 446 .set_fmt = wm8731_set_dai_fmt,
429}; 447};
430 448
431struct snd_soc_dai wm8731_dai = { 449static struct snd_soc_dai_driver wm8731_dai = {
432 .name = "WM8731", 450 .name = "wm8731-hifi",
433 .playback = { 451 .playback = {
434 .stream_name = "Playback", 452 .stream_name = "Playback",
435 .channels_min = 1, 453 .channels_min = 1,
@@ -445,24 +463,17 @@ struct snd_soc_dai wm8731_dai = {
445 .ops = &wm8731_dai_ops, 463 .ops = &wm8731_dai_ops,
446 .symmetric_rates = 1, 464 .symmetric_rates = 1,
447}; 465};
448EXPORT_SYMBOL_GPL(wm8731_dai);
449 466
450#ifdef CONFIG_PM 467#ifdef CONFIG_PM
451static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 468static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
452{ 469{
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); 470 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
457 471
458 return 0; 472 return 0;
459} 473}
460 474
461static int wm8731_resume(struct platform_device *pdev) 475static int wm8731_resume(struct snd_soc_codec *codec)
462{ 476{
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); 477 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
467 478
468 return 0; 479 return 0;
@@ -472,88 +483,15 @@ static int wm8731_resume(struct platform_device *pdev)
472#define wm8731_resume NULL 483#define wm8731_resume NULL
473#endif 484#endif
474 485
475static int wm8731_probe(struct platform_device *pdev) 486static int wm8731_probe(struct snd_soc_codec *codec)
476{ 487{
477 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 488 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
478 struct snd_soc_codec *codec; 489 int ret = 0, i;
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{
509 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
510
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
551 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
552 490
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 491 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
554 if (ret < 0) { 492 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 493 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
556 goto err; 494 return ret;
557 } 495 }
558 496
559 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) 497 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +501,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
563 wm8731->supplies); 501 wm8731->supplies);
564 if (ret != 0) { 502 if (ret != 0) {
565 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 503 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
566 goto err; 504 return ret;
567 } 505 }
568 506
569 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 507 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +517,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
579 goto err_regulator_enable; 517 goto err_regulator_enable;
580 } 518 }
581 519
582 wm8731_dai.dev = codec->dev;
583
584 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 520 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
585 521
586 /* Latch the update bits */ 522 /* Latch the update bits */
@@ -592,79 +528,78 @@ static int wm8731_register(struct wm8731_priv *wm8731,
592 /* Disable bypass path by default */ 528 /* Disable bypass path by default */
593 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); 529 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
594 530
595 wm8731_codec = codec; 531 snd_soc_add_controls(codec, wm8731_snd_controls,
596 532 ARRAY_SIZE(wm8731_snd_controls));
597 ret = snd_soc_register_codec(codec); 533 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 534
610 /* Regulators will have been enabled by bias management */ 535 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 536 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612 537
613 return 0; 538 return 0;
614 539
615err_codec:
616 snd_soc_unregister_codec(codec);
617err_regulator_enable: 540err_regulator_enable:
618 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 541 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
619err_regulator_get: 542err_regulator_get:
620 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 543 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
621err: 544
622 kfree(wm8731); 545 kfree(wm8731);
623 return ret; 546 return ret;
624} 547}
625 548
626static void wm8731_unregister(struct wm8731_priv *wm8731) 549/* power down chip */
550static int wm8731_remove(struct snd_soc_codec *codec)
627{ 551{
628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 552 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
629 snd_soc_unregister_dai(&wm8731_dai); 553
630 snd_soc_unregister_codec(&wm8731->codec); 554 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
555
556 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 557 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 558
633 wm8731_codec = NULL; 559 return 0;
634} 560}
635 561
562static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
563 .probe = wm8731_probe,
564 .remove = wm8731_remove,
565 .suspend = wm8731_suspend,
566 .resume = wm8731_resume,
567 .set_bias_level = wm8731_set_bias_level,
568 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
569 .reg_word_size = sizeof(u16),
570 .reg_cache_default = wm8731_reg,
571};
572
636#if defined(CONFIG_SPI_MASTER) 573#if defined(CONFIG_SPI_MASTER)
637static int __devinit wm8731_spi_probe(struct spi_device *spi) 574static int __devinit wm8731_spi_probe(struct spi_device *spi)
638{ 575{
639 struct snd_soc_codec *codec;
640 struct wm8731_priv *wm8731; 576 struct wm8731_priv *wm8731;
577 int ret;
641 578
642 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 579 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
643 if (wm8731 == NULL) 580 if (wm8731 == NULL)
644 return -ENOMEM; 581 return -ENOMEM;
645 582
646 codec = &wm8731->codec; 583 wm8731->control_type = SND_SOC_SPI;
647 codec->control_data = spi; 584 spi_set_drvdata(spi, wm8731);
648 codec->dev = &spi->dev;
649
650 dev_set_drvdata(&spi->dev, wm8731);
651 585
652 return wm8731_register(wm8731, SND_SOC_SPI); 586 ret = snd_soc_register_codec(&spi->dev,
587 &soc_codec_dev_wm8731, &wm8731_dai, 1);
588 if (ret < 0)
589 kfree(wm8731);
590 return ret;
653} 591}
654 592
655static int __devexit wm8731_spi_remove(struct spi_device *spi) 593static int __devexit wm8731_spi_remove(struct spi_device *spi)
656{ 594{
657 struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); 595 snd_soc_unregister_codec(&spi->dev);
658 596 kfree(spi_get_drvdata(spi));
659 wm8731_unregister(wm8731);
660
661 return 0; 597 return 0;
662} 598}
663 599
664static struct spi_driver wm8731_spi_driver = { 600static struct spi_driver wm8731_spi_driver = {
665 .driver = { 601 .driver = {
666 .name = "wm8731", 602 .name = "wm8731-codec",
667 .bus = &spi_bus_type,
668 .owner = THIS_MODULE, 603 .owner = THIS_MODULE,
669 }, 604 },
670 .probe = wm8731_spi_probe, 605 .probe = wm8731_spi_probe,
@@ -677,26 +612,26 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
677 const struct i2c_device_id *id) 612 const struct i2c_device_id *id)
678{ 613{
679 struct wm8731_priv *wm8731; 614 struct wm8731_priv *wm8731;
680 struct snd_soc_codec *codec; 615 int ret;
681 616
682 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 617 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
683 if (wm8731 == NULL) 618 if (wm8731 == NULL)
684 return -ENOMEM; 619 return -ENOMEM;
685 620
686 codec = &wm8731->codec;
687
688 i2c_set_clientdata(i2c, wm8731); 621 i2c_set_clientdata(i2c, wm8731);
689 codec->control_data = i2c; 622 wm8731->control_type = SND_SOC_I2C;
690
691 codec->dev = &i2c->dev;
692 623
693 return wm8731_register(wm8731, SND_SOC_I2C); 624 ret = snd_soc_register_codec(&i2c->dev,
625 &soc_codec_dev_wm8731, &wm8731_dai, 1);
626 if (ret < 0)
627 kfree(wm8731);
628 return ret;
694} 629}
695 630
696static __devexit int wm8731_i2c_remove(struct i2c_client *client) 631static __devexit int wm8731_i2c_remove(struct i2c_client *client)
697{ 632{
698 struct wm8731_priv *wm8731 = i2c_get_clientdata(client); 633 snd_soc_unregister_codec(&client->dev);
699 wm8731_unregister(wm8731); 634 kfree(i2c_get_clientdata(client));
700 return 0; 635 return 0;
701} 636}
702 637
@@ -708,7 +643,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 643
709static struct i2c_driver wm8731_i2c_driver = { 644static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 645 .driver = {
711 .name = "wm8731", 646 .name = "wm8731-codec",
712 .owner = THIS_MODULE, 647 .owner = THIS_MODULE,
713 }, 648 },
714 .probe = wm8731_i2c_probe, 649 .probe = wm8731_i2c_probe,
@@ -719,7 +654,7 @@ static struct i2c_driver wm8731_i2c_driver = {
719 654
720static int __init wm8731_modinit(void) 655static int __init wm8731_modinit(void)
721{ 656{
722 int ret; 657 int ret = 0;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 658#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8731_i2c_driver); 659 ret = i2c_add_driver(&wm8731_i2c_driver);
725 if (ret != 0) { 660 if (ret != 0) {
@@ -734,7 +669,7 @@ static int __init wm8731_modinit(void)
734 ret); 669 ret);
735 } 670 }
736#endif 671#endif
737 return 0; 672 return ret;
738} 673}
739module_init(wm8731_modinit); 674module_init(wm8731_modinit);
740 675