aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8750.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r--sound/soc/codecs/wm8750.c177
1 files changed, 123 insertions, 54 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index dd1f55404b29..4892e398a598 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.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>
@@ -841,88 +842,147 @@ static struct snd_soc_device *wm8750_socdev;
841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 842#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
842 843
843/* 844/*
844 * WM8731 2 wire address is determined by GPIO5 845 * WM8750 2 wire address is determined by GPIO5
845 * state during powerup. 846 * state during powerup.
846 * low = 0x1a 847 * low = 0x1a
847 * high = 0x1b 848 * high = 0x1b
848 */ 849 */
849static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
850 850
851/* Magic definition of all other variables and things */ 851static int wm8750_i2c_probe(struct i2c_client *i2c,
852I2C_CLIENT_INSMOD; 852 const struct i2c_device_id *id)
853
854static struct i2c_driver wm8750_i2c_driver;
855static struct i2c_client client_template;
856
857static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
858{ 853{
859 struct snd_soc_device *socdev = wm8750_socdev; 854 struct snd_soc_device *socdev = wm8750_socdev;
860 struct wm8750_setup_data *setup = socdev->codec_data;
861 struct snd_soc_codec *codec = socdev->codec; 855 struct snd_soc_codec *codec = socdev->codec;
862 struct i2c_client *i2c;
863 int ret; 856 int ret;
864 857
865 if (addr != setup->i2c_address)
866 return -ENODEV;
867
868 client_template.adapter = adap;
869 client_template.addr = addr;
870
871 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
872 if (i2c == NULL)
873 return -ENOMEM;
874
875 i2c_set_clientdata(i2c, codec); 858 i2c_set_clientdata(i2c, codec);
876 codec->control_data = i2c; 859 codec->control_data = i2c;
877 860
878 ret = i2c_attach_client(i2c);
879 if (ret < 0) {
880 pr_err("failed to attach codec at addr %x\n", addr);
881 goto err;
882 }
883
884 ret = wm8750_init(socdev); 861 ret = wm8750_init(socdev);
885 if (ret < 0) { 862 if (ret < 0)
886 pr_err("failed to initialise WM8750\n"); 863 pr_err("failed to initialise WM8750\n");
887 goto err;
888 }
889 return ret;
890 864
891err:
892 kfree(i2c);
893 return ret; 865 return ret;
894} 866}
895 867
896static int wm8750_i2c_detach(struct i2c_client *client) 868static int wm8750_i2c_remove(struct i2c_client *client)
897{ 869{
898 struct snd_soc_codec *codec = i2c_get_clientdata(client); 870 struct snd_soc_codec *codec = i2c_get_clientdata(client);
899 i2c_detach_client(client);
900 kfree(codec->reg_cache); 871 kfree(codec->reg_cache);
901 kfree(client);
902 return 0; 872 return 0;
903} 873}
904 874
905static int wm8750_i2c_attach(struct i2c_adapter *adap) 875static const struct i2c_device_id wm8750_i2c_id[] = {
906{ 876 { "wm8750", 0 },
907 return i2c_probe(adap, &addr_data, wm8750_codec_probe); 877 { }
908} 878};
879MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
909 880
910/* corgi i2c codec control layer */
911static struct i2c_driver wm8750_i2c_driver = { 881static struct i2c_driver wm8750_i2c_driver = {
912 .driver = { 882 .driver = {
913 .name = "WM8750 I2C Codec", 883 .name = "WM8750 I2C Codec",
914 .owner = THIS_MODULE, 884 .owner = THIS_MODULE,
915 }, 885 },
916 .id = I2C_DRIVERID_WM8750, 886 .probe = wm8750_i2c_probe,
917 .attach_adapter = wm8750_i2c_attach, 887 .remove = wm8750_i2c_remove,
918 .detach_client = wm8750_i2c_detach, 888 .id_table = wm8750_i2c_id,
919 .command = NULL,
920}; 889};
921 890
922static struct i2c_client client_template = { 891static int wm8750_add_i2c_device(struct platform_device *pdev,
923 .name = "WM8750", 892 const struct wm8750_setup_data *setup)
924 .driver = &wm8750_i2c_driver, 893{
894 struct i2c_board_info info;
895 struct i2c_adapter *adapter;
896 struct i2c_client *client;
897 int ret;
898
899 ret = i2c_add_driver(&wm8750_i2c_driver);
900 if (ret != 0) {
901 dev_err(&pdev->dev, "can't add i2c driver\n");
902 return ret;
903 }
904
905 memset(&info, 0, sizeof(struct i2c_board_info));
906 info.addr = setup->i2c_address;
907 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
908
909 adapter = i2c_get_adapter(setup->i2c_bus);
910 if (!adapter) {
911 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
912 setup->i2c_bus);
913 goto err_driver;
914 }
915
916 client = i2c_new_device(adapter, &info);
917 i2c_put_adapter(adapter);
918 if (!client) {
919 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
920 (unsigned int)info.addr);
921 goto err_driver;
922 }
923
924 return 0;
925
926err_driver:
927 i2c_del_driver(&wm8750_i2c_driver);
928 return -ENODEV;
929}
930#endif
931
932#if defined(CONFIG_SPI_MASTER)
933static int __devinit wm8750_spi_probe(struct spi_device *spi)
934{
935 struct snd_soc_device *socdev = wm8750_socdev;
936 struct snd_soc_codec *codec = socdev->codec;
937 int ret;
938
939 codec->control_data = spi;
940
941 ret = wm8750_init(socdev);
942 if (ret < 0)
943 dev_err(&spi->dev, "failed to initialise WM8750\n");
944
945 return ret;
946}
947
948static int __devexit wm8750_spi_remove(struct spi_device *spi)
949{
950 return 0;
951}
952
953static struct spi_driver wm8750_spi_driver = {
954 .driver = {
955 .name = "wm8750",
956 .bus = &spi_bus_type,
957 .owner = THIS_MODULE,
958 },
959 .probe = wm8750_spi_probe,
960 .remove = __devexit_p(wm8750_spi_remove),
925}; 961};
962
963static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
964{
965 struct spi_transfer t;
966 struct spi_message m;
967 u8 msg[2];
968
969 if (len <= 0)
970 return 0;
971
972 msg[0] = data[0];
973 msg[1] = data[1];
974
975 spi_message_init(&m);
976 memset(&t, 0, (sizeof t));
977
978 t.tx_buf = &msg[0];
979 t.len = len;
980
981 spi_message_add_tail(&t, &m);
982 spi_sync(spi, &m);
983
984 return len;
985}
926#endif 986#endif
927 987
928static int wm8750_probe(struct platform_device *pdev) 988static int wm8750_probe(struct platform_device *pdev)
@@ -931,7 +991,7 @@ static int wm8750_probe(struct platform_device *pdev)
931 struct wm8750_setup_data *setup = socdev->codec_data; 991 struct wm8750_setup_data *setup = socdev->codec_data;
932 struct snd_soc_codec *codec; 992 struct snd_soc_codec *codec;
933 struct wm8750_priv *wm8750; 993 struct wm8750_priv *wm8750;
934 int ret = 0; 994 int ret;
935 995
936 pr_info("WM8750 Audio Codec %s", WM8750_VERSION); 996 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
937 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 997 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -952,16 +1012,21 @@ static int wm8750_probe(struct platform_device *pdev)
952 wm8750_socdev = socdev; 1012 wm8750_socdev = socdev;
953 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work); 1013 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
954 1014
1015 ret = -ENODEV;
1016
955#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1017#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
956 if (setup->i2c_address) { 1018 if (setup->i2c_address) {
957 normal_i2c[0] = setup->i2c_address;
958 codec->hw_write = (hw_write_t)i2c_master_send; 1019 codec->hw_write = (hw_write_t)i2c_master_send;
959 ret = i2c_add_driver(&wm8750_i2c_driver); 1020 ret = wm8750_add_i2c_device(pdev, setup);
1021 }
1022#endif
1023#if defined(CONFIG_SPI_MASTER)
1024 if (setup->spi) {
1025 codec->hw_write = (hw_write_t)wm8750_spi_write;
1026 ret = spi_register_driver(&wm8750_spi_driver);
960 if (ret != 0) 1027 if (ret != 0)
961 printk(KERN_ERR "can't add i2c driver"); 1028 printk(KERN_ERR "can't add spi driver");
962 } 1029 }
963#else
964 /* Add other interfaces here */
965#endif 1030#endif
966 1031
967 if (ret != 0) { 1032 if (ret != 0) {
@@ -1002,8 +1067,12 @@ static int wm8750_remove(struct platform_device *pdev)
1002 snd_soc_free_pcms(socdev); 1067 snd_soc_free_pcms(socdev);
1003 snd_soc_dapm_free(socdev); 1068 snd_soc_dapm_free(socdev);
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1070 i2c_unregister_device(codec->control_data);
1005 i2c_del_driver(&wm8750_i2c_driver); 1071 i2c_del_driver(&wm8750_i2c_driver);
1006#endif 1072#endif
1073#if defined(CONFIG_SPI_MASTER)
1074 spi_unregister_driver(&wm8750_spi_driver);
1075#endif
1007 kfree(codec->private_data); 1076 kfree(codec->private_data);
1008 kfree(codec); 1077 kfree(codec);
1009 1078