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.c178
1 files changed, 122 insertions, 56 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9402fcaf04f..7b64d9a7ff7 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -570,88 +571,144 @@ static struct snd_soc_device *wm8731_socdev;
570 * low = 0x1a 571 * low = 0x1a
571 * high = 0x1b 572 * high = 0x1b
572 */ 573 */
573static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
574 574
575/* Magic definition of all other variables and things */ 575static int wm8731_i2c_probe(struct i2c_client *i2c,
576I2C_CLIENT_INSMOD; 576 const struct i2c_device_id *id)
577
578static struct i2c_driver wm8731_i2c_driver;
579static struct i2c_client client_template;
580
581/* If the i2c layer weren't so broken, we could pass this kind of data
582 around */
583
584static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
585{ 577{
586 struct snd_soc_device *socdev = wm8731_socdev; 578 struct snd_soc_device *socdev = wm8731_socdev;
587 struct wm8731_setup_data *setup = socdev->codec_data;
588 struct snd_soc_codec *codec = socdev->codec; 579 struct snd_soc_codec *codec = socdev->codec;
589 struct i2c_client *i2c;
590 int ret; 580 int ret;
591 581
592 if (addr != setup->i2c_address)
593 return -ENODEV;
594
595 client_template.adapter = adap;
596 client_template.addr = addr;
597
598 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
599 if (i2c == NULL)
600 return -ENOMEM;
601
602 i2c_set_clientdata(i2c, codec); 582 i2c_set_clientdata(i2c, codec);
603 codec->control_data = i2c; 583 codec->control_data = i2c;
604 584
605 ret = i2c_attach_client(i2c);
606 if (ret < 0) {
607 pr_err("failed to attach codec at addr %x\n", addr);
608 goto err;
609 }
610
611 ret = wm8731_init(socdev); 585 ret = wm8731_init(socdev);
612 if (ret < 0) { 586 if (ret < 0)
613 pr_err("failed to initialise WM8731\n"); 587 pr_err("failed to initialise WM8731\n");
614 goto err;
615 }
616 return ret;
617 588
618err:
619 kfree(i2c);
620 return ret; 589 return ret;
621} 590}
622 591
623static int wm8731_i2c_detach(struct i2c_client *client) 592static int wm8731_i2c_remove(struct i2c_client *client)
624{ 593{
625 struct snd_soc_codec *codec = i2c_get_clientdata(client); 594 struct snd_soc_codec *codec = i2c_get_clientdata(client);
626 i2c_detach_client(client);
627 kfree(codec->reg_cache); 595 kfree(codec->reg_cache);
628 kfree(client);
629 return 0; 596 return 0;
630} 597}
631 598
632static int wm8731_i2c_attach(struct i2c_adapter *adap) 599static const struct i2c_device_id wm8731_i2c_id[] = {
633{ 600 { "wm8731", 0 },
634 return i2c_probe(adap, &addr_data, wm8731_codec_probe); 601 { }
635} 602};
603MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
636 604
637/* corgi i2c codec control layer */
638static struct i2c_driver wm8731_i2c_driver = { 605static struct i2c_driver wm8731_i2c_driver = {
639 .driver = { 606 .driver = {
640 .name = "WM8731 I2C Codec", 607 .name = "WM8731 I2C Codec",
641 .owner = THIS_MODULE, 608 .owner = THIS_MODULE,
642 }, 609 },
643 .id = I2C_DRIVERID_WM8731, 610 .probe = wm8731_i2c_probe,
644 .attach_adapter = wm8731_i2c_attach, 611 .remove = wm8731_i2c_remove,
645 .detach_client = wm8731_i2c_detach, 612 .id_table = wm8731_i2c_id,
646 .command = NULL,
647}; 613};
648 614
649static struct i2c_client client_template = { 615static int wm8731_add_i2c_device(struct platform_device *pdev,
650 .name = "WM8731", 616 const struct wm8731_setup_data *setup)
651 .driver = &wm8731_i2c_driver, 617{
652}; 618 struct i2c_board_info info;
619 struct i2c_adapter *adapter;
620 struct i2c_client *client;
621 int ret;
622
623 ret = i2c_add_driver(&wm8731_i2c_driver);
624 if (ret != 0) {
625 dev_err(&pdev->dev, "can't add i2c driver\n");
626 return ret;
627 }
628
629 memset(&info, 0, sizeof(struct i2c_board_info));
630 info.addr = setup->i2c_address;
631 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
632
633 adapter = i2c_get_adapter(setup->i2c_bus);
634 if (!adapter) {
635 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
636 setup->i2c_bus);
637 goto err_driver;
638 }
639
640 client = i2c_new_device(adapter, &info);
641 i2c_put_adapter(adapter);
642 if (!client) {
643 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
644 (unsigned int)info.addr);
645 goto err_driver;
646 }
647
648 return 0;
649
650err_driver:
651 i2c_del_driver(&wm8731_i2c_driver);
652 return -ENODEV;
653}
653#endif 654#endif
654 655
656#if defined(CONFIG_SPI_MASTER)
657static int __devinit wm8731_spi_probe(struct spi_device *spi)
658{
659 struct snd_soc_device *socdev = wm8731_socdev;
660 struct snd_soc_codec *codec = socdev->codec;
661 int ret;
662
663 codec->control_data = spi;
664
665 ret = wm8731_init(socdev);
666 if (ret < 0)
667 dev_err(&spi->dev, "failed to initialise WM8731\n");
668
669 return ret;
670}
671
672static int __devexit wm8731_spi_remove(struct spi_device *spi)
673{
674 return 0;
675}
676
677static struct spi_driver wm8731_spi_driver = {
678 .driver = {
679 .name = "wm8731",
680 .bus = &spi_bus_type,
681 .owner = THIS_MODULE,
682 },
683 .probe = wm8731_spi_probe,
684 .remove = __devexit_p(wm8731_spi_remove),
685};
686
687static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
688{
689 struct spi_transfer t;
690 struct spi_message m;
691 u8 msg[2];
692
693 if (len <= 0)
694 return 0;
695
696 msg[0] = data[0];
697 msg[1] = data[1];
698
699 spi_message_init(&m);
700 memset(&t, 0, (sizeof t));
701
702 t.tx_buf = &msg[0];
703 t.len = len;
704
705 spi_message_add_tail(&t, &m);
706 spi_sync(spi, &m);
707
708 return len;
709}
710#endif /* CONFIG_SPI_MASTER */
711
655static int wm8731_probe(struct platform_device *pdev) 712static int wm8731_probe(struct platform_device *pdev)
656{ 713{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 714 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -680,16 +737,21 @@ static int wm8731_probe(struct platform_device *pdev)
680 INIT_LIST_HEAD(&codec->dapm_paths); 737 INIT_LIST_HEAD(&codec->dapm_paths);
681 738
682 wm8731_socdev = socdev; 739 wm8731_socdev = socdev;
740 ret = -ENODEV;
741
683#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 742#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
684 if (setup->i2c_address) { 743 if (setup->i2c_address) {
685 normal_i2c[0] = setup->i2c_address;
686 codec->hw_write = (hw_write_t)i2c_master_send; 744 codec->hw_write = (hw_write_t)i2c_master_send;
687 ret = i2c_add_driver(&wm8731_i2c_driver); 745 ret = wm8731_add_i2c_device(pdev, setup);
746 }
747#endif
748#if defined(CONFIG_SPI_MASTER)
749 if (setup->spi) {
750 codec->hw_write = (hw_write_t)wm8731_spi_write;
751 ret = spi_register_driver(&wm8731_spi_driver);
688 if (ret != 0) 752 if (ret != 0)
689 printk(KERN_ERR "can't add i2c driver"); 753 printk(KERN_ERR "can't add spi driver");
690 } 754 }
691#else
692 /* Add other interfaces here */
693#endif 755#endif
694 756
695 if (ret != 0) { 757 if (ret != 0) {
@@ -711,8 +773,12 @@ static int wm8731_remove(struct platform_device *pdev)
711 snd_soc_free_pcms(socdev); 773 snd_soc_free_pcms(socdev);
712 snd_soc_dapm_free(socdev); 774 snd_soc_dapm_free(socdev);
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 775#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
776 i2c_unregister_device(codec->control_data);
714 i2c_del_driver(&wm8731_i2c_driver); 777 i2c_del_driver(&wm8731_i2c_driver);
715#endif 778#endif
779#if defined(CONFIG_SPI_MASTER)
780 spi_unregister_driver(&wm8731_spi_driver);
781#endif
716 kfree(codec->private_data); 782 kfree(codec->private_data);
717 kfree(codec); 783 kfree(codec);
718 784