aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8580.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8580.c')
-rw-r--r--sound/soc/codecs/wm8580.c381
1 files changed, 179 insertions, 202 deletions
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index d004e5845298..442ea6f160fc 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver 2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics PLC. 4 * Copyright 2008, 2009 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -35,19 +35,6 @@
35 35
36#include "wm8580.h" 36#include "wm8580.h"
37 37
38#define WM8580_VERSION "0.1"
39
40struct pll_state {
41 unsigned int in;
42 unsigned int out;
43};
44
45/* codec private data */
46struct wm8580_priv {
47 struct pll_state a;
48 struct pll_state b;
49};
50
51/* WM8580 register space */ 38/* WM8580 register space */
52#define WM8580_PLLA1 0x00 39#define WM8580_PLLA1 0x00
53#define WM8580_PLLA2 0x01 40#define WM8580_PLLA2 0x01
@@ -102,6 +89,8 @@ struct wm8580_priv {
102#define WM8580_READBACK 0x34 89#define WM8580_READBACK 0x34
103#define WM8580_RESET 0x35 90#define WM8580_RESET 0x35
104 91
92#define WM8580_MAX_REGISTER 0x35
93
105/* PLLB4 (register 7h) */ 94/* PLLB4 (register 7h) */
106#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60 95#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
107#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20 96#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
@@ -193,6 +182,20 @@ static const u16 wm8580_reg[] = {
193 0x0000, 0x0000 /*R53*/ 182 0x0000, 0x0000 /*R53*/
194}; 183};
195 184
185struct pll_state {
186 unsigned int in;
187 unsigned int out;
188};
189
190/* codec private data */
191struct wm8580_priv {
192 struct snd_soc_codec codec;
193 u16 reg_cache[WM8580_MAX_REGISTER + 1];
194 struct pll_state a;
195 struct pll_state b;
196};
197
198
196/* 199/*
197 * read wm8580 register cache 200 * read wm8580 register cache
198 */ 201 */
@@ -200,7 +203,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
200 unsigned int reg) 203 unsigned int reg)
201{ 204{
202 u16 *cache = codec->reg_cache; 205 u16 *cache = codec->reg_cache;
203 BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); 206 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
204 return cache[reg]; 207 return cache[reg];
205} 208}
206 209
@@ -223,7 +226,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
223{ 226{
224 u8 data[2]; 227 u8 data[2];
225 228
226 BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); 229 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
227 230
228 /* Registers are 9 bits wide */ 231 /* Registers are 9 bits wide */
229 value &= 0x1ff; 232 value &= 0x1ff;
@@ -330,20 +333,6 @@ SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
330SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 333SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
331}; 334};
332 335
333/* Add non-DAPM controls */
334static int wm8580_add_controls(struct snd_soc_codec *codec)
335{
336 int err, i;
337
338 for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) {
339 err = snd_ctl_add(codec->card,
340 snd_soc_cnew(&wm8580_snd_controls[i],
341 codec, NULL));
342 if (err < 0)
343 return err;
344 }
345 return 0;
346}
347static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { 336static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
348SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), 337SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
349SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), 338SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
@@ -553,7 +542,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
553{ 542{
554 struct snd_soc_pcm_runtime *rtd = substream->private_data; 543 struct snd_soc_pcm_runtime *rtd = substream->private_data;
555 struct snd_soc_device *socdev = rtd->socdev; 544 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec; 545 struct snd_soc_codec *codec = socdev->card->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); 546 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
558 547
559 paifb &= ~WM8580_AIF_LENGTH_MASK; 548 paifb &= ~WM8580_AIF_LENGTH_MASK;
@@ -771,8 +760,22 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
771 switch (level) { 760 switch (level) {
772 case SND_SOC_BIAS_ON: 761 case SND_SOC_BIAS_ON:
773 case SND_SOC_BIAS_PREPARE: 762 case SND_SOC_BIAS_PREPARE:
763 break;
764
774 case SND_SOC_BIAS_STANDBY: 765 case SND_SOC_BIAS_STANDBY:
766 if (codec->bias_level == SND_SOC_BIAS_OFF) {
767 /* Power up and get individual control of the DACs */
768 reg = wm8580_read(codec, WM8580_PWRDN1);
769 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
770 wm8580_write(codec, WM8580_PWRDN1, reg);
771
772 /* Make VMID high impedence */
773 reg = wm8580_read(codec, WM8580_ADC_CONTROL1);
774 reg &= ~0x100;
775 wm8580_write(codec, WM8580_ADC_CONTROL1, reg);
776 }
775 break; 777 break;
778
776 case SND_SOC_BIAS_OFF: 779 case SND_SOC_BIAS_OFF:
777 reg = wm8580_read(codec, WM8580_PWRDN1); 780 reg = wm8580_read(codec, WM8580_PWRDN1);
778 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 781 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
@@ -785,6 +788,21 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
785#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 788#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
786 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 789 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
787 790
791static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
792 .hw_params = wm8580_paif_hw_params,
793 .set_fmt = wm8580_set_paif_dai_fmt,
794 .set_clkdiv = wm8580_set_dai_clkdiv,
795 .set_pll = wm8580_set_dai_pll,
796 .digital_mute = wm8580_digital_mute,
797};
798
799static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
800 .hw_params = wm8580_paif_hw_params,
801 .set_fmt = wm8580_set_paif_dai_fmt,
802 .set_clkdiv = wm8580_set_dai_clkdiv,
803 .set_pll = wm8580_set_dai_pll,
804};
805
788struct snd_soc_dai wm8580_dai[] = { 806struct snd_soc_dai wm8580_dai[] = {
789 { 807 {
790 .name = "WM8580 PAIFRX", 808 .name = "WM8580 PAIFRX",
@@ -796,13 +814,7 @@ struct snd_soc_dai wm8580_dai[] = {
796 .rates = SNDRV_PCM_RATE_8000_192000, 814 .rates = SNDRV_PCM_RATE_8000_192000,
797 .formats = WM8580_FORMATS, 815 .formats = WM8580_FORMATS,
798 }, 816 },
799 .ops = { 817 .ops = &wm8580_dai_ops_playback,
800 .hw_params = wm8580_paif_hw_params,
801 .set_fmt = wm8580_set_paif_dai_fmt,
802 .set_clkdiv = wm8580_set_dai_clkdiv,
803 .set_pll = wm8580_set_dai_pll,
804 .digital_mute = wm8580_digital_mute,
805 },
806 }, 818 },
807 { 819 {
808 .name = "WM8580 PAIFTX", 820 .name = "WM8580 PAIFTX",
@@ -814,109 +826,168 @@ struct snd_soc_dai wm8580_dai[] = {
814 .rates = SNDRV_PCM_RATE_8000_192000, 826 .rates = SNDRV_PCM_RATE_8000_192000,
815 .formats = WM8580_FORMATS, 827 .formats = WM8580_FORMATS,
816 }, 828 },
817 .ops = { 829 .ops = &wm8580_dai_ops_capture,
818 .hw_params = wm8580_paif_hw_params,
819 .set_fmt = wm8580_set_paif_dai_fmt,
820 .set_clkdiv = wm8580_set_dai_clkdiv,
821 .set_pll = wm8580_set_dai_pll,
822 },
823 }, 830 },
824}; 831};
825EXPORT_SYMBOL_GPL(wm8580_dai); 832EXPORT_SYMBOL_GPL(wm8580_dai);
826 833
827/* 834static struct snd_soc_codec *wm8580_codec;
828 * initialise the WM8580 driver 835
829 * register the mixer and dsp interfaces with the kernel 836static int wm8580_probe(struct platform_device *pdev)
830 */
831static int wm8580_init(struct snd_soc_device *socdev)
832{ 837{
833 struct snd_soc_codec *codec = socdev->codec; 838 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
839 struct snd_soc_codec *codec;
834 int ret = 0; 840 int ret = 0;
835 841
836 codec->name = "WM8580"; 842 if (wm8580_codec == NULL) {
837 codec->owner = THIS_MODULE; 843 dev_err(&pdev->dev, "Codec device not registered\n");
838 codec->read = wm8580_read_reg_cache; 844 return -ENODEV;
839 codec->write = wm8580_write; 845 }
840 codec->set_bias_level = wm8580_set_bias_level;
841 codec->dai = wm8580_dai;
842 codec->num_dai = ARRAY_SIZE(wm8580_dai);
843 codec->reg_cache_size = ARRAY_SIZE(wm8580_reg);
844 codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg),
845 GFP_KERNEL);
846
847 if (codec->reg_cache == NULL)
848 return -ENOMEM;
849
850 /* Get the codec into a known state */
851 wm8580_write(codec, WM8580_RESET, 0);
852
853 /* Power up and get individual control of the DACs */
854 wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) &
855 ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD));
856 846
857 /* Make VMID high impedence */ 847 socdev->card->codec = wm8580_codec;
858 wm8580_write(codec, WM8580_ADC_CONTROL1, 848 codec = wm8580_codec;
859 wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100);
860 849
861 /* register pcms */ 850 /* register pcms */
862 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, 851 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
863 SNDRV_DEFAULT_STR1);
864 if (ret < 0) { 852 if (ret < 0) {
865 printk(KERN_ERR "wm8580: failed to create pcms\n"); 853 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
866 goto pcm_err; 854 goto pcm_err;
867 } 855 }
868 856
869 wm8580_add_controls(codec); 857 snd_soc_add_controls(codec, wm8580_snd_controls,
858 ARRAY_SIZE(wm8580_snd_controls));
870 wm8580_add_widgets(codec); 859 wm8580_add_widgets(codec);
871
872 ret = snd_soc_init_card(socdev); 860 ret = snd_soc_init_card(socdev);
873 if (ret < 0) { 861 if (ret < 0) {
874 printk(KERN_ERR "wm8580: failed to register card\n"); 862 dev_err(codec->dev, "failed to register card: %d\n", ret);
875 goto card_err; 863 goto card_err;
876 } 864 }
865
877 return ret; 866 return ret;
878 867
879card_err: 868card_err:
880 snd_soc_free_pcms(socdev); 869 snd_soc_free_pcms(socdev);
881 snd_soc_dapm_free(socdev); 870 snd_soc_dapm_free(socdev);
882pcm_err: 871pcm_err:
883 kfree(codec->reg_cache);
884 return ret; 872 return ret;
885} 873}
886 874
887/* If the i2c layer weren't so broken, we could pass this kind of data 875/* power down chip */
888 around */ 876static int wm8580_remove(struct platform_device *pdev)
889static struct snd_soc_device *wm8580_socdev; 877{
878 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
879
880 snd_soc_free_pcms(socdev);
881 snd_soc_dapm_free(socdev);
890 882
891#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 883 return 0;
884}
892 885
893/* 886struct snd_soc_codec_device soc_codec_dev_wm8580 = {
894 * WM8580 2 wire address is determined by GPIO5 887 .probe = wm8580_probe,
895 * state during powerup. 888 .remove = wm8580_remove,
896 * low = 0x1a 889};
897 * high = 0x1b 890EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
898 */ 891
892static int wm8580_register(struct wm8580_priv *wm8580)
893{
894 int ret, i;
895 struct snd_soc_codec *codec = &wm8580->codec;
896
897 if (wm8580_codec) {
898 dev_err(codec->dev, "Another WM8580 is registered\n");
899 ret = -EINVAL;
900 goto err;
901 }
902
903 mutex_init(&codec->mutex);
904 INIT_LIST_HEAD(&codec->dapm_widgets);
905 INIT_LIST_HEAD(&codec->dapm_paths);
899 906
907 codec->private_data = wm8580;
908 codec->name = "WM8580";
909 codec->owner = THIS_MODULE;
910 codec->read = wm8580_read_reg_cache;
911 codec->write = wm8580_write;
912 codec->bias_level = SND_SOC_BIAS_OFF;
913 codec->set_bias_level = wm8580_set_bias_level;
914 codec->dai = wm8580_dai;
915 codec->num_dai = ARRAY_SIZE(wm8580_dai);
916 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
917 codec->reg_cache = &wm8580->reg_cache;
918
919 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
920
921 /* Get the codec into a known state */
922 ret = wm8580_write(codec, WM8580_RESET, 0);
923 if (ret != 0) {
924 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
925 goto err;
926 }
927
928 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
929 wm8580_dai[i].dev = codec->dev;
930
931 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
932
933 wm8580_codec = codec;
934
935 ret = snd_soc_register_codec(codec);
936 if (ret != 0) {
937 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
938 goto err;
939 }
940
941 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
942 if (ret != 0) {
943 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
944 goto err_codec;
945 }
946
947 return 0;
948
949err_codec:
950 snd_soc_unregister_codec(codec);
951err:
952 kfree(wm8580);
953 return ret;
954}
955
956static void wm8580_unregister(struct wm8580_priv *wm8580)
957{
958 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
959 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
960 snd_soc_unregister_codec(&wm8580->codec);
961 kfree(wm8580);
962 wm8580_codec = NULL;
963}
964
965#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
900static int wm8580_i2c_probe(struct i2c_client *i2c, 966static int wm8580_i2c_probe(struct i2c_client *i2c,
901 const struct i2c_device_id *id) 967 const struct i2c_device_id *id)
902{ 968{
903 struct snd_soc_device *socdev = wm8580_socdev; 969 struct wm8580_priv *wm8580;
904 struct snd_soc_codec *codec = socdev->codec; 970 struct snd_soc_codec *codec;
905 int ret;
906 971
907 i2c_set_clientdata(i2c, codec); 972 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
973 if (wm8580 == NULL)
974 return -ENOMEM;
975
976 codec = &wm8580->codec;
977 codec->hw_write = (hw_write_t)i2c_master_send;
978
979 i2c_set_clientdata(i2c, wm8580);
908 codec->control_data = i2c; 980 codec->control_data = i2c;
909 981
910 ret = wm8580_init(socdev); 982 codec->dev = &i2c->dev;
911 if (ret < 0) 983
912 dev_err(&i2c->dev, "failed to initialise WM8580\n"); 984 return wm8580_register(wm8580);
913 return ret;
914} 985}
915 986
916static int wm8580_i2c_remove(struct i2c_client *client) 987static int wm8580_i2c_remove(struct i2c_client *client)
917{ 988{
918 struct snd_soc_codec *codec = i2c_get_clientdata(client); 989 struct wm8580_priv *wm8580 = i2c_get_clientdata(client);
919 kfree(codec->reg_cache); 990 wm8580_unregister(wm8580);
920 return 0; 991 return 0;
921} 992}
922 993
@@ -928,129 +999,35 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
928 999
929static struct i2c_driver wm8580_i2c_driver = { 1000static struct i2c_driver wm8580_i2c_driver = {
930 .driver = { 1001 .driver = {
931 .name = "WM8580 I2C Codec", 1002 .name = "wm8580",
932 .owner = THIS_MODULE, 1003 .owner = THIS_MODULE,
933 }, 1004 },
934 .probe = wm8580_i2c_probe, 1005 .probe = wm8580_i2c_probe,
935 .remove = wm8580_i2c_remove, 1006 .remove = wm8580_i2c_remove,
936 .id_table = wm8580_i2c_id, 1007 .id_table = wm8580_i2c_id,
937}; 1008};
1009#endif
938 1010
939static int wm8580_add_i2c_device(struct platform_device *pdev, 1011static int __init wm8580_modinit(void)
940 const struct wm8580_setup_data *setup)
941{ 1012{
942 struct i2c_board_info info;
943 struct i2c_adapter *adapter;
944 struct i2c_client *client;
945 int ret; 1013 int ret;
946 1014
1015#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
947 ret = i2c_add_driver(&wm8580_i2c_driver); 1016 ret = i2c_add_driver(&wm8580_i2c_driver);
948 if (ret != 0) { 1017 if (ret != 0) {
949 dev_err(&pdev->dev, "can't add i2c driver\n"); 1018 pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
950 return ret;
951 }
952
953 memset(&info, 0, sizeof(struct i2c_board_info));
954 info.addr = setup->i2c_address;
955 strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
956
957 adapter = i2c_get_adapter(setup->i2c_bus);
958 if (!adapter) {
959 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
960 setup->i2c_bus);
961 goto err_driver;
962 }
963
964 client = i2c_new_device(adapter, &info);
965 i2c_put_adapter(adapter);
966 if (!client) {
967 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
968 (unsigned int)info.addr);
969 goto err_driver;
970 } 1019 }
971
972 return 0;
973
974err_driver:
975 i2c_del_driver(&wm8580_i2c_driver);
976 return -ENODEV;
977}
978#endif 1020#endif
979 1021
980static int wm8580_probe(struct platform_device *pdev)
981{
982 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
983 struct wm8580_setup_data *setup;
984 struct snd_soc_codec *codec;
985 struct wm8580_priv *wm8580;
986 int ret = 0;
987
988 pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION);
989
990 setup = socdev->codec_data;
991 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
992 if (codec == NULL)
993 return -ENOMEM;
994
995 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
996 if (wm8580 == NULL) {
997 kfree(codec);
998 return -ENOMEM;
999 }
1000
1001 codec->private_data = wm8580;
1002 socdev->codec = codec;
1003 mutex_init(&codec->mutex);
1004 INIT_LIST_HEAD(&codec->dapm_widgets);
1005 INIT_LIST_HEAD(&codec->dapm_paths);
1006 wm8580_socdev = socdev;
1007
1008#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1009 if (setup->i2c_address) {
1010 codec->hw_write = (hw_write_t)i2c_master_send;
1011 ret = wm8580_add_i2c_device(pdev, setup);
1012 }
1013#else
1014 /* Add other interfaces here */
1015#endif
1016 return ret;
1017}
1018
1019/* power down chip */
1020static int wm8580_remove(struct platform_device *pdev)
1021{
1022 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1023 struct snd_soc_codec *codec = socdev->codec;
1024
1025 if (codec->control_data)
1026 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
1027 snd_soc_free_pcms(socdev);
1028 snd_soc_dapm_free(socdev);
1029#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1030 i2c_unregister_device(codec->control_data);
1031 i2c_del_driver(&wm8580_i2c_driver);
1032#endif
1033 kfree(codec->private_data);
1034 kfree(codec);
1035
1036 return 0; 1022 return 0;
1037} 1023}
1038
1039struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1040 .probe = wm8580_probe,
1041 .remove = wm8580_remove,
1042};
1043EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1044
1045static int __init wm8580_modinit(void)
1046{
1047 return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1048}
1049module_init(wm8580_modinit); 1024module_init(wm8580_modinit);
1050 1025
1051static void __exit wm8580_exit(void) 1026static void __exit wm8580_exit(void)
1052{ 1027{
1053 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 1028#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1029 i2c_del_driver(&wm8580_i2c_driver);
1030#endif
1054} 1031}
1055module_exit(wm8580_exit); 1032module_exit(wm8580_exit);
1056 1033