diff options
-rw-r--r-- | sound/soc/codecs/wm8750.c | 105 | ||||
-rw-r--r-- | sound/soc/codecs/wm8750.h | 1 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 1 |
3 files changed, 55 insertions, 52 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index dd1f55404b29..34d846587759 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -846,83 +846,86 @@ static struct snd_soc_device *wm8750_socdev; | |||
846 | * low = 0x1a | 846 | * low = 0x1a |
847 | * high = 0x1b | 847 | * high = 0x1b |
848 | */ | 848 | */ |
849 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | ||
850 | 849 | ||
851 | /* Magic definition of all other variables and things */ | 850 | static int wm8750_i2c_probe(struct i2c_client *i2c, |
852 | I2C_CLIENT_INSMOD; | 851 | const struct i2c_device_id *id) |
853 | |||
854 | static struct i2c_driver wm8750_i2c_driver; | ||
855 | static struct i2c_client client_template; | ||
856 | |||
857 | static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) | ||
858 | { | 852 | { |
859 | struct snd_soc_device *socdev = wm8750_socdev; | 853 | struct snd_soc_device *socdev = wm8750_socdev; |
860 | struct wm8750_setup_data *setup = socdev->codec_data; | ||
861 | struct snd_soc_codec *codec = socdev->codec; | 854 | struct snd_soc_codec *codec = socdev->codec; |
862 | struct i2c_client *i2c; | ||
863 | int ret; | 855 | int ret; |
864 | 856 | ||
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); | 857 | i2c_set_clientdata(i2c, codec); |
876 | codec->control_data = i2c; | 858 | codec->control_data = i2c; |
877 | 859 | ||
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); | 860 | ret = wm8750_init(socdev); |
885 | if (ret < 0) { | 861 | if (ret < 0) |
886 | pr_err("failed to initialise WM8750\n"); | 862 | pr_err("failed to initialise WM8750\n"); |
887 | goto err; | ||
888 | } | ||
889 | return ret; | ||
890 | 863 | ||
891 | err: | ||
892 | kfree(i2c); | ||
893 | return ret; | 864 | return ret; |
894 | } | 865 | } |
895 | 866 | ||
896 | static int wm8750_i2c_detach(struct i2c_client *client) | 867 | static int wm8750_i2c_remove(struct i2c_client *client) |
897 | { | 868 | { |
898 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 869 | struct snd_soc_codec *codec = i2c_get_clientdata(client); |
899 | i2c_detach_client(client); | ||
900 | kfree(codec->reg_cache); | 870 | kfree(codec->reg_cache); |
901 | kfree(client); | ||
902 | return 0; | 871 | return 0; |
903 | } | 872 | } |
904 | 873 | ||
905 | static int wm8750_i2c_attach(struct i2c_adapter *adap) | 874 | static const struct i2c_device_id wm8750_i2c_id[] = { |
906 | { | 875 | { "wm8750", 0 }, |
907 | return i2c_probe(adap, &addr_data, wm8750_codec_probe); | 876 | { } |
908 | } | 877 | }; |
878 | MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); | ||
909 | 879 | ||
910 | /* corgi i2c codec control layer */ | ||
911 | static struct i2c_driver wm8750_i2c_driver = { | 880 | static struct i2c_driver wm8750_i2c_driver = { |
912 | .driver = { | 881 | .driver = { |
913 | .name = "WM8750 I2C Codec", | 882 | .name = "WM8750 I2C Codec", |
914 | .owner = THIS_MODULE, | 883 | .owner = THIS_MODULE, |
915 | }, | 884 | }, |
916 | .id = I2C_DRIVERID_WM8750, | 885 | .probe = wm8750_i2c_probe, |
917 | .attach_adapter = wm8750_i2c_attach, | 886 | .remove = wm8750_i2c_remove, |
918 | .detach_client = wm8750_i2c_detach, | 887 | .id_table = wm8750_i2c_id, |
919 | .command = NULL, | ||
920 | }; | 888 | }; |
921 | 889 | ||
922 | static struct i2c_client client_template = { | 890 | static int wm8750_add_i2c_device(struct platform_device *pdev, |
923 | .name = "WM8750", | 891 | const struct wm8750_setup_data *setup) |
924 | .driver = &wm8750_i2c_driver, | 892 | { |
925 | }; | 893 | struct i2c_board_info info; |
894 | struct i2c_adapter *adapter; | ||
895 | struct i2c_client *client; | ||
896 | int ret; | ||
897 | |||
898 | ret = i2c_add_driver(&wm8750_i2c_driver); | ||
899 | if (ret != 0) { | ||
900 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
901 | return ret; | ||
902 | } | ||
903 | |||
904 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
905 | info.addr = setup->i2c_address; | ||
906 | strlcpy(info.type, "wm8750", I2C_NAME_SIZE); | ||
907 | |||
908 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
909 | if (!adapter) { | ||
910 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
911 | setup->i2c_bus); | ||
912 | goto err_driver; | ||
913 | } | ||
914 | |||
915 | client = i2c_new_device(adapter, &info); | ||
916 | i2c_put_adapter(adapter); | ||
917 | if (!client) { | ||
918 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
919 | (unsigned int)info.addr); | ||
920 | goto err_driver; | ||
921 | } | ||
922 | |||
923 | return 0; | ||
924 | |||
925 | err_driver: | ||
926 | i2c_del_driver(&wm8750_i2c_driver); | ||
927 | return -ENODEV; | ||
928 | } | ||
926 | #endif | 929 | #endif |
927 | 930 | ||
928 | static int wm8750_probe(struct platform_device *pdev) | 931 | static int wm8750_probe(struct platform_device *pdev) |
@@ -954,11 +957,8 @@ static int wm8750_probe(struct platform_device *pdev) | |||
954 | 957 | ||
955 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 958 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
956 | if (setup->i2c_address) { | 959 | if (setup->i2c_address) { |
957 | normal_i2c[0] = setup->i2c_address; | ||
958 | codec->hw_write = (hw_write_t)i2c_master_send; | 960 | codec->hw_write = (hw_write_t)i2c_master_send; |
959 | ret = i2c_add_driver(&wm8750_i2c_driver); | 961 | ret = wm8750_add_i2c_device(pdev, setup); |
960 | if (ret != 0) | ||
961 | printk(KERN_ERR "can't add i2c driver"); | ||
962 | } | 962 | } |
963 | #else | 963 | #else |
964 | /* Add other interfaces here */ | 964 | /* Add other interfaces here */ |
@@ -1002,6 +1002,7 @@ static int wm8750_remove(struct platform_device *pdev) | |||
1002 | snd_soc_free_pcms(socdev); | 1002 | snd_soc_free_pcms(socdev); |
1003 | snd_soc_dapm_free(socdev); | 1003 | snd_soc_dapm_free(socdev); |
1004 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1004 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1005 | i2c_unregister_device(codec->control_data); | ||
1005 | i2c_del_driver(&wm8750_i2c_driver); | 1006 | i2c_del_driver(&wm8750_i2c_driver); |
1006 | #endif | 1007 | #endif |
1007 | kfree(codec->private_data); | 1008 | kfree(codec->private_data); |
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h index 8ef30e628b21..fe6c80f7d9e2 100644 --- a/sound/soc/codecs/wm8750.h +++ b/sound/soc/codecs/wm8750.h | |||
@@ -58,6 +58,7 @@ | |||
58 | #define WM8750_SYSCLK 0 | 58 | #define WM8750_SYSCLK 0 |
59 | 59 | ||
60 | struct wm8750_setup_data { | 60 | struct wm8750_setup_data { |
61 | int i2c_bus; | ||
61 | unsigned short i2c_address; | 62 | unsigned short i2c_address; |
62 | }; | 63 | }; |
63 | 64 | ||
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 37cb768fc933..3d4738c06e7e 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -337,6 +337,7 @@ static struct snd_soc_machine snd_soc_machine_spitz = { | |||
337 | 337 | ||
338 | /* spitz audio private data */ | 338 | /* spitz audio private data */ |
339 | static struct wm8750_setup_data spitz_wm8750_setup = { | 339 | static struct wm8750_setup_data spitz_wm8750_setup = { |
340 | .i2c_bus = 0, | ||
340 | .i2c_address = 0x1b, | 341 | .i2c_address = 0x1b, |
341 | }; | 342 | }; |
342 | 343 | ||