aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-02-16 15:49:16 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-02-18 06:55:22 -0500
commit5998102b9095fdb7c67755812038612afea315c5 (patch)
tree9b536a80336f526d7a7d206d272527f6789e449e /sound/soc/codecs
parenta8035c8f04477895207b92915b908344749be336 (diff)
ASoC: Refactor WM8731 device registration
Move the WM8731 driver to use a more standard device registration scheme where the device can be registered independantly of the ASoC probe. As a transition measure push the current manual code for registering the WM8731 into the individual machine driver probes. This allows separate patches to update the relevant architecture files with less risk of merge issues. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/wm8731.c334
-rw-r--r--sound/soc/codecs/wm8731.h6
2 files changed, 147 insertions, 193 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 3ff971aeba21..a2c478e53d54 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -29,16 +29,18 @@
29 29
30#include "wm8731.h" 30#include "wm8731.h"
31 31
32static struct snd_soc_codec *wm8731_codec;
32struct snd_soc_codec_device soc_codec_dev_wm8731; 33struct snd_soc_codec_device soc_codec_dev_wm8731;
33 34
34/* codec private data */ 35/* codec private data */
35struct wm8731_priv { 36struct wm8731_priv {
37 struct snd_soc_codec codec;
38 u16 reg_cache[WM8731_CACHEREGNUM];
36 unsigned int sysclk; 39 unsigned int sysclk;
37}; 40};
38 41
39#ifdef CONFIG_SPI_MASTER 42#ifdef CONFIG_SPI_MASTER
40static int wm8731_spi_write(struct spi_device *spi, const char *data, int len); 43static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
41static struct spi_driver wm8731_spi_driver;
42#endif 44#endif
43 45
44/* 46/*
@@ -485,55 +487,33 @@ static int wm8731_resume(struct platform_device *pdev)
485 return 0; 487 return 0;
486} 488}
487 489
488/* 490static int wm8731_probe(struct platform_device *pdev)
489 * initialise the WM8731 driver
490 * register the mixer and dsp interfaces with the kernel
491 */
492static int wm8731_init(struct snd_soc_device *socdev)
493{ 491{
494 struct snd_soc_codec *codec = socdev->card->codec; 492 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
495 int reg, ret = 0; 493 struct snd_soc_codec *codec;
494 int ret = 0;
496 495
497 codec->name = "WM8731"; 496 if (wm8731_codec == NULL) {
498 codec->owner = THIS_MODULE; 497 dev_err(&pdev->dev, "Codec device not registered\n");
499 codec->read = wm8731_read_reg_cache; 498 return -ENODEV;
500 codec->write = wm8731_write; 499 }
501 codec->set_bias_level = wm8731_set_bias_level;
502 codec->dai = &wm8731_dai;
503 codec->num_dai = 1;
504 codec->reg_cache_size = ARRAY_SIZE(wm8731_reg);
505 codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL);
506 if (codec->reg_cache == NULL)
507 return -ENOMEM;
508 500
509 wm8731_reset(codec); 501 socdev->card->codec = wm8731_codec;
502 codec = wm8731_codec;
510 503
511 /* register pcms */ 504 /* register pcms */
512 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 505 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
513 if (ret < 0) { 506 if (ret < 0) {
514 printk(KERN_ERR "wm8731: failed to create pcms\n"); 507 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
515 goto pcm_err; 508 goto pcm_err;
516 } 509 }
517 510
518 /* power on device */
519 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
520
521 /* set the update bits */
522 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
523 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
524 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
525 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
526 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
527 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
528 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
529 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
530
531 snd_soc_add_controls(codec, wm8731_snd_controls, 511 snd_soc_add_controls(codec, wm8731_snd_controls,
532 ARRAY_SIZE(wm8731_snd_controls)); 512 ARRAY_SIZE(wm8731_snd_controls));
533 wm8731_add_widgets(codec); 513 wm8731_add_widgets(codec);
534 ret = snd_soc_init_card(socdev); 514 ret = snd_soc_init_card(socdev);
535 if (ret < 0) { 515 if (ret < 0) {
536 printk(KERN_ERR "wm8731: failed to register card\n"); 516 dev_err(codec->dev, "failed to register card: %d\n", ret);
537 goto card_err; 517 goto card_err;
538 } 518 }
539 519
@@ -543,104 +523,6 @@ card_err:
543 snd_soc_free_pcms(socdev); 523 snd_soc_free_pcms(socdev);
544 snd_soc_dapm_free(socdev); 524 snd_soc_dapm_free(socdev);
545pcm_err: 525pcm_err:
546 kfree(codec->reg_cache);
547 return ret;
548}
549
550static struct snd_soc_device *wm8731_socdev;
551
552
553#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
554static struct i2c_driver wm8731_i2c_driver;
555
556static int wm8731_add_i2c_device(struct platform_device *pdev,
557 const struct wm8731_setup_data *setup)
558{
559 struct i2c_board_info info;
560 struct i2c_adapter *adapter;
561 struct i2c_client *client;
562 int ret;
563
564 ret = i2c_add_driver(&wm8731_i2c_driver);
565 if (ret != 0) {
566 dev_err(&pdev->dev, "can't add i2c driver\n");
567 return ret;
568 }
569
570 memset(&info, 0, sizeof(struct i2c_board_info));
571 info.addr = setup->i2c_address;
572 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
573
574 adapter = i2c_get_adapter(setup->i2c_bus);
575 if (!adapter) {
576 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
577 setup->i2c_bus);
578 goto err_driver;
579 }
580
581 client = i2c_new_device(adapter, &info);
582 i2c_put_adapter(adapter);
583 if (!client) {
584 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
585 (unsigned int)info.addr);
586 goto err_driver;
587 }
588
589 return 0;
590
591err_driver:
592 i2c_del_driver(&wm8731_i2c_driver);
593 return -ENODEV;
594}
595#endif
596
597static int wm8731_probe(struct platform_device *pdev)
598{
599 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
600 struct wm8731_setup_data *setup;
601 struct snd_soc_codec *codec;
602 struct wm8731_priv *wm8731;
603 int ret = 0;
604
605 setup = socdev->codec_data;
606 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
607 if (codec == NULL)
608 return -ENOMEM;
609
610 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
611 if (wm8731 == NULL) {
612 kfree(codec);
613 return -ENOMEM;
614 }
615
616 codec->private_data = wm8731;
617 socdev->card->codec = codec;
618 mutex_init(&codec->mutex);
619 INIT_LIST_HEAD(&codec->dapm_widgets);
620 INIT_LIST_HEAD(&codec->dapm_paths);
621
622 wm8731_socdev = socdev;
623 ret = -ENODEV;
624
625#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
626 if (setup->i2c_address) {
627 codec->hw_write = (hw_write_t)i2c_master_send;
628 ret = wm8731_add_i2c_device(pdev, setup);
629 }
630#endif
631#if defined(CONFIG_SPI_MASTER)
632 if (setup->spi) {
633 codec->hw_write = (hw_write_t)wm8731_spi_write;
634 ret = spi_register_driver(&wm8731_spi_driver);
635 if (ret != 0)
636 printk(KERN_ERR "can't add spi driver");
637 }
638#endif
639
640 if (ret != 0) {
641 kfree(codec->private_data);
642 kfree(codec);
643 }
644 return ret; 526 return ret;
645} 527}
646 528
@@ -648,22 +530,9 @@ static int wm8731_probe(struct platform_device *pdev)
648static int wm8731_remove(struct platform_device *pdev) 530static int wm8731_remove(struct platform_device *pdev)
649{ 531{
650 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 532 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
651 struct snd_soc_codec *codec = socdev->card->codec;
652
653 if (codec->control_data)
654 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
655 533
656 snd_soc_free_pcms(socdev); 534 snd_soc_free_pcms(socdev);
657 snd_soc_dapm_free(socdev); 535 snd_soc_dapm_free(socdev);
658#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
659 i2c_unregister_device(codec->control_data);
660 i2c_del_driver(&wm8731_i2c_driver);
661#endif
662#if defined(CONFIG_SPI_MASTER)
663 spi_unregister_driver(&wm8731_spi_driver);
664#endif
665 kfree(codec->private_data);
666 kfree(codec);
667 536
668 return 0; 537 return 0;
669} 538}
@@ -676,37 +545,78 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
676}; 545};
677EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 546EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
678 547
679#if defined(CONFIG_SPI_MASTER) 548static int wm8731_register(struct wm8731_priv *wm8731)
680static int __devinit wm8731_spi_probe(struct spi_device *spi)
681{ 549{
682 struct snd_soc_device *socdev = wm8731_socdev;
683 struct snd_soc_codec *codec = socdev->card->codec;
684 int ret; 550 int ret;
551 struct snd_soc_codec *codec = &wm8731->codec;
552 u16 reg;
685 553
686 codec->control_data = spi; 554 if (wm8731_codec) {
555 dev_err(codec->dev, "Another WM8731 is registered\n");
556 return -EINVAL;
557 }
687 558
688 ret = wm8731_init(socdev); 559 mutex_init(&codec->mutex);
689 if (ret < 0) 560 INIT_LIST_HEAD(&codec->dapm_widgets);
690 dev_err(&spi->dev, "failed to initialise WM8731\n"); 561 INIT_LIST_HEAD(&codec->dapm_paths);
691 562
692 return ret; 563 codec->private_data = wm8731;
693} 564 codec->name = "WM8731";
565 codec->owner = THIS_MODULE;
566 codec->read = wm8731_read_reg_cache;
567 codec->write = wm8731_write;
568 codec->bias_level = SND_SOC_BIAS_OFF;
569 codec->set_bias_level = wm8731_set_bias_level;
570 codec->dai = &wm8731_dai;
571 codec->num_dai = 1;
572 codec->reg_cache_size = WM8731_CACHEREGNUM;
573 codec->reg_cache = &wm8731->reg_cache;
574
575 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
576
577 wm8731_dai.dev = codec->dev;
578
579 wm8731_reset(codec);
580 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
581
582 /* Latch the update bits */
583 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
584 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
585 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
586 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
587 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
588 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
589 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
590 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
591
592 wm8731_codec = codec;
593
594 ret = snd_soc_register_codec(codec);
595 if (ret != 0) {
596 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
597 return ret;
598 }
599
600 ret = snd_soc_register_dai(&wm8731_dai);
601 if (ret != 0) {
602 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
603 snd_soc_unregister_codec(codec);
604 return ret;
605 }
694 606
695static int __devexit wm8731_spi_remove(struct spi_device *spi)
696{
697 return 0; 607 return 0;
698} 608}
699 609
700static struct spi_driver wm8731_spi_driver = { 610static void wm8731_unregister(struct wm8731_priv *wm8731)
701 .driver = { 611{
702 .name = "wm8731", 612 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
703 .bus = &spi_bus_type, 613 snd_soc_unregister_dai(&wm8731_dai);
704 .owner = THIS_MODULE, 614 snd_soc_unregister_codec(&wm8731->codec);
705 }, 615 kfree(wm8731);
706 .probe = wm8731_spi_probe, 616 wm8731_codec = NULL;
707 .remove = __devexit_p(wm8731_spi_remove), 617}
708};
709 618
619#if defined(CONFIG_SPI_MASTER)
710static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) 620static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
711{ 621{
712 struct spi_transfer t; 622 struct spi_transfer t;
@@ -730,37 +640,67 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
730 640
731 return len; 641 return len;
732} 642}
643
644static int __devinit wm8731_spi_probe(struct spi_device *spi)
645{
646 struct snd_soc_codec *codec;
647 struct wm8731_priv *wm8731;
648
649 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
650 if (wm8731 == NULL)
651 return -ENOMEM;
652
653 codec = &wm8731->codec;
654 codec->control_data = spi;
655 codec->hw_write = (hw_write_t)wm8731_spi_write;
656 codec->dev = &spi->dev;
657
658 return wm8731_register(wm8731);
659}
660
661static int __devexit wm8731_spi_remove(struct spi_device *spi)
662{
663 /* FIXME: This isn't actually implemented... */
664 return 0;
665}
666
667static struct spi_driver wm8731_spi_driver = {
668 .driver = {
669 .name = "wm8731",
670 .bus = &spi_bus_type,
671 .owner = THIS_MODULE,
672 },
673 .probe = wm8731_spi_probe,
674 .remove = __devexit_p(wm8731_spi_remove),
675};
733#endif /* CONFIG_SPI_MASTER */ 676#endif /* CONFIG_SPI_MASTER */
734 677
735#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 678#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
736/*
737 * WM8731 2 wire address is determined by GPIO5
738 * state during powerup.
739 * low = 0x1a
740 * high = 0x1b
741 */
742
743static int wm8731_i2c_probe(struct i2c_client *i2c, 679static int wm8731_i2c_probe(struct i2c_client *i2c,
744 const struct i2c_device_id *id) 680 const struct i2c_device_id *id)
745{ 681{
746 struct snd_soc_device *socdev = wm8731_socdev; 682 struct wm8731_priv *wm8731;
747 struct snd_soc_codec *codec = socdev->card->codec; 683 struct snd_soc_codec *codec;
748 int ret;
749 684
750 i2c_set_clientdata(i2c, codec); 685 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
686 if (wm8731 == NULL)
687 return -ENOMEM;
688
689 codec = &wm8731->codec;
690 codec->hw_write = (hw_write_t)i2c_master_send;
691
692 i2c_set_clientdata(i2c, wm8731);
751 codec->control_data = i2c; 693 codec->control_data = i2c;
752 694
753 ret = wm8731_init(socdev); 695 codec->dev = &i2c->dev;
754 if (ret < 0)
755 pr_err("failed to initialise WM8731\n");
756 696
757 return ret; 697 return wm8731_register(wm8731);
758} 698}
759 699
760static int wm8731_i2c_remove(struct i2c_client *client) 700static int wm8731_i2c_remove(struct i2c_client *client)
761{ 701{
762 struct snd_soc_codec *codec = i2c_get_clientdata(client); 702 struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
763 kfree(codec->reg_cache); 703 wm8731_unregister(wm8731);
764 return 0; 704 return 0;
765} 705}
766 706
@@ -783,13 +723,33 @@ static struct i2c_driver wm8731_i2c_driver = {
783 723
784static int __init wm8731_modinit(void) 724static int __init wm8731_modinit(void)
785{ 725{
786 return snd_soc_register_dai(&wm8731_dai); 726 int ret;
727#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
728 ret = i2c_add_driver(&wm8731_i2c_driver);
729 if (ret != 0) {
730 printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n",
731 ret);
732 }
733#endif
734#if defined(CONFIG_SPI_MASTER)
735 ret = spi_register_driver(&wm8731_spi_driver);
736 if (ret != 0) {
737 printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n",
738 ret);
739 }
740#endif
741 return 0;
787} 742}
788module_init(wm8731_modinit); 743module_init(wm8731_modinit);
789 744
790static void __exit wm8731_exit(void) 745static void __exit wm8731_exit(void)
791{ 746{
792 snd_soc_unregister_dai(&wm8731_dai); 747#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
748 i2c_del_driver(&wm8731_i2c_driver);
749#endif
750#if defined(CONFIG_SPI_MASTER)
751 spi_unregister_driver(&wm8731_spi_driver);
752#endif
793} 753}
794module_exit(wm8731_exit); 754module_exit(wm8731_exit);
795 755
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 95190e9c0c14..cd7b806e8ad0 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -34,12 +34,6 @@
34#define WM8731_SYSCLK 0 34#define WM8731_SYSCLK 0
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data {
38 int spi;
39 int i2c_bus;
40 unsigned short i2c_address;
41};
42
43extern struct snd_soc_dai wm8731_dai; 37extern struct snd_soc_dai wm8731_dai;
44extern struct snd_soc_codec_device soc_codec_dev_wm8731; 38extern struct snd_soc_codec_device soc_codec_dev_wm8731;
45 39