aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorCliff Cai <cliff.cai@analog.com>2008-09-01 13:47:03 -0400
committerJaroslav Kysela <perex@perex.cz>2008-09-04 04:34:27 -0400
commitd2a403553ba7659d85dae2a05b1f3767d2fefcfe (patch)
treee902a5a87e8aa5359d2c7e7331ca22babf1694d6 /sound
parente5d3fd38f93755c5ab1e04b8e40196135f576355 (diff)
ALSA: ASoC: Add SPI support for WM8731
[Modified to allow runtime selection between I2C and SPI and to select SPI_MASTER for all codecs build so this is included. -- broonie] Signed-off-by: Cliff Cai <cliff.cai@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/Kconfig1
-rw-r--r--sound/soc/codecs/wm8731.c71
-rw-r--r--sound/soc/codecs/wm8731.h1
3 files changed, 71 insertions, 2 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 13ae4fd2d179..cceac73aff0a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -2,6 +2,7 @@ config SND_SOC_ALL_CODECS
2 tristate "Build all ASoC CODEC drivers" 2 tristate "Build all ASoC CODEC drivers"
3 depends on I2C 3 depends on I2C
4 select SPI 4 select SPI
5 select SPI_MASTER
5 select SND_SOC_AK4535 6 select SND_SOC_AK4535
6 select SND_SOC_UDA1380 7 select SND_SOC_UDA1380
7 select SND_SOC_WM8510 8 select SND_SOC_WM8510
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 5814f9bdf0c0..975befdfd885 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>
@@ -652,6 +653,61 @@ err_driver:
652} 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 u16 msg[2];
692
693 if (len <= 0)
694 return 0;
695
696 msg[0] = (data[0] << 8) + data[1];
697
698 spi_message_init(&m);
699 memset(&t, 0, (sizeof t));
700
701 t.tx_buf = &msg[0];
702 t.len = len;
703
704 spi_message_add_tail(&t, &m);
705 spi_sync(spi, &m);
706
707 return len;
708}
709#endif /* CONFIG_SPI_MASTER */
710
655static int wm8731_probe(struct platform_device *pdev) 711static int wm8731_probe(struct platform_device *pdev)
656{ 712{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 713 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -680,13 +736,21 @@ static int wm8731_probe(struct platform_device *pdev)
680 INIT_LIST_HEAD(&codec->dapm_paths); 736 INIT_LIST_HEAD(&codec->dapm_paths);
681 737
682 wm8731_socdev = socdev; 738 wm8731_socdev = socdev;
739 ret = -ENODEV;
740
683#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 741#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
684 if (setup->i2c_address) { 742 if (setup->i2c_address) {
685 codec->hw_write = (hw_write_t)i2c_master_send; 743 codec->hw_write = (hw_write_t)i2c_master_send;
686 ret = wm8731_add_i2c_device(pdev, setup); 744 ret = wm8731_add_i2c_device(pdev, setup);
687 } 745 }
688#else 746#endif
689 /* Add other interfaces here */ 747#if defined(CONFIG_SPI_MASTER)
748 if (setup->spi) {
749 codec->hw_write = (hw_write_t)wm8731_spi_write;
750 ret = spi_register_driver(&wm8731_spi_driver);
751 if (ret != 0)
752 printk(KERN_ERR "can't add spi driver");
753 }
690#endif 754#endif
691 755
692 if (ret != 0) { 756 if (ret != 0) {
@@ -711,6 +775,9 @@ static int wm8731_remove(struct platform_device *pdev)
711 i2c_unregister_device(codec->control_data); 775 i2c_unregister_device(codec->control_data);
712 i2c_del_driver(&wm8731_i2c_driver); 776 i2c_del_driver(&wm8731_i2c_driver);
713#endif 777#endif
778#if defined(CONFIG_SPI_MASTER)
779 spi_unregister_driver(&wm8731_spi_driver);
780#endif
714 kfree(codec->private_data); 781 kfree(codec->private_data);
715 kfree(codec); 782 kfree(codec);
716 783
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 0f8123909ab0..95190e9c0c14 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -35,6 +35,7 @@
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data { 37struct wm8731_setup_data {
38 int spi;
38 int i2c_bus; 39 int i2c_bus;
39 unsigned short i2c_address; 40 unsigned short i2c_address;
40}; 41};