diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 11:32:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 11:32:05 -0400 |
commit | 33081adf8b89d5a716d7e1c60171768d39795b39 (patch) | |
tree | 275de58bbbb5f7ddffcdc087844cfc7fbe4315be /sound/soc/codecs/twl6040.c | |
parent | c55960499f810357a29659b32d6ea594abee9237 (diff) | |
parent | 506ecbca71d07fa327dd986be1682e90885678ee (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (365 commits)
ALSA: hda - Disable sticky PCM stream assignment for AD codecs
ALSA: usb - Creative USB X-Fi volume knob support
ALSA: ca0106: Use card specific dac id for mute controls.
ALSA: ca0106: Allow different sound cards to use different SPI channel mappings.
ALSA: ca0106: Create a nice spot for mapping channels to dacs.
ALSA: ca0106: Move enabling of front dac out of hardcoded setup sequence.
ALSA: ca0106: Pull out dac powering routine into separate function.
ALSA: ca0106 - add Sound Blaster 5.1vx info.
ASoC: tlv320dac33: Use usleep_range for delays
ALSA: usb-audio: add Novation Launchpad support
ALSA: hda - Add workarounds for CT-IBG controllers
ALSA: hda - Fix wrong TLV mute bit for STAC/IDT codecs
ASoC: tpa6130a2: Error handling for broken chip
ASoC: max98088: Staticise m98088_eq_band
ASoC: soc-core: Fix codec->name memory leak
ALSA: hda - Apply ideapad quirk to Acer laptops with Cxt5066
ALSA: hda - Add some workarounds for Creative IBG
ALSA: hda - Fix wrong SPDIF NID assignment for CA0110
ALSA: hda - Fix codec rename rules for ALC662-compatible codecs
ALSA: hda - Add alc_init_jacks() call to other codecs
...
Diffstat (limited to 'sound/soc/codecs/twl6040.c')
-rw-r--r-- | sound/soc/codecs/twl6040.c | 170 |
1 files changed, 44 insertions, 126 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 64a807f1a8a1..10f6e5214511 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | /* codec private data */ | 46 | /* codec private data */ |
47 | struct twl6040_data { | 47 | struct twl6040_data { |
48 | struct snd_soc_codec codec; | ||
49 | int audpwron; | 48 | int audpwron; |
50 | int naudint; | 49 | int naudint; |
51 | int codec_powered; | 50 | int codec_powered; |
@@ -770,8 +769,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream, | |||
770 | struct snd_soc_dai *dai) | 769 | struct snd_soc_dai *dai) |
771 | { | 770 | { |
772 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 771 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
773 | struct snd_soc_device *socdev = rtd->socdev; | 772 | struct snd_soc_codec *codec = rtd->codec; |
774 | struct snd_soc_codec *codec = socdev->card->codec; | ||
775 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 773 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
776 | 774 | ||
777 | if (!priv->sysclk) { | 775 | if (!priv->sysclk) { |
@@ -803,8 +801,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, | |||
803 | struct snd_soc_dai *dai) | 801 | struct snd_soc_dai *dai) |
804 | { | 802 | { |
805 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 803 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
806 | struct snd_soc_device *socdev = rtd->socdev; | 804 | struct snd_soc_codec *codec = rtd->codec; |
807 | struct snd_soc_codec *codec = socdev->card->codec; | ||
808 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 805 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
809 | u8 lppllctl; | 806 | u8 lppllctl; |
810 | int rate; | 807 | int rate; |
@@ -839,8 +836,7 @@ static int twl6040_trigger(struct snd_pcm_substream *substream, | |||
839 | int cmd, struct snd_soc_dai *dai) | 836 | int cmd, struct snd_soc_dai *dai) |
840 | { | 837 | { |
841 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 838 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
842 | struct snd_soc_device *socdev = rtd->socdev; | 839 | struct snd_soc_codec *codec = rtd->codec; |
843 | struct snd_soc_codec *codec = socdev->card->codec; | ||
844 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 840 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
845 | 841 | ||
846 | switch (cmd) { | 842 | switch (cmd) { |
@@ -978,8 +974,8 @@ static struct snd_soc_dai_ops twl6040_dai_ops = { | |||
978 | .set_sysclk = twl6040_set_dai_sysclk, | 974 | .set_sysclk = twl6040_set_dai_sysclk, |
979 | }; | 975 | }; |
980 | 976 | ||
981 | struct snd_soc_dai twl6040_dai = { | 977 | static struct snd_soc_dai_driver twl6040_dai = { |
982 | .name = "twl6040", | 978 | .name = "twl6040-hifi", |
983 | .playback = { | 979 | .playback = { |
984 | .stream_name = "Playback", | 980 | .stream_name = "Playback", |
985 | .channels_min = 1, | 981 | .channels_min = 1, |
@@ -996,24 +992,17 @@ struct snd_soc_dai twl6040_dai = { | |||
996 | }, | 992 | }, |
997 | .ops = &twl6040_dai_ops, | 993 | .ops = &twl6040_dai_ops, |
998 | }; | 994 | }; |
999 | EXPORT_SYMBOL_GPL(twl6040_dai); | ||
1000 | 995 | ||
1001 | #ifdef CONFIG_PM | 996 | #ifdef CONFIG_PM |
1002 | static int twl6040_suspend(struct platform_device *pdev, pm_message_t state) | 997 | static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state) |
1003 | { | 998 | { |
1004 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1005 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1006 | |||
1007 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); | 999 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1008 | 1000 | ||
1009 | return 0; | 1001 | return 0; |
1010 | } | 1002 | } |
1011 | 1003 | ||
1012 | static int twl6040_resume(struct platform_device *pdev) | 1004 | static int twl6040_resume(struct snd_soc_codec *codec) |
1013 | { | 1005 | { |
1014 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1015 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1016 | |||
1017 | twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1006 | twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1018 | 1007 | ||
1019 | return 0; | 1008 | return 0; |
@@ -1023,68 +1012,9 @@ static int twl6040_resume(struct platform_device *pdev) | |||
1023 | #define twl6040_resume NULL | 1012 | #define twl6040_resume NULL |
1024 | #endif | 1013 | #endif |
1025 | 1014 | ||
1026 | static struct snd_soc_codec *twl6040_codec; | 1015 | static int twl6040_probe(struct snd_soc_codec *codec) |
1027 | |||
1028 | static int twl6040_probe(struct platform_device *pdev) | ||
1029 | { | ||
1030 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1031 | struct snd_soc_codec *codec; | ||
1032 | int ret = 0; | ||
1033 | |||
1034 | BUG_ON(!twl6040_codec); | ||
1035 | |||
1036 | codec = twl6040_codec; | ||
1037 | socdev->card->codec = codec; | ||
1038 | |||
1039 | /* register pcms */ | ||
1040 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
1041 | if (ret < 0) { | ||
1042 | dev_err(&pdev->dev, "failed to create pcms\n"); | ||
1043 | return ret; | ||
1044 | } | ||
1045 | |||
1046 | snd_soc_add_controls(codec, twl6040_snd_controls, | ||
1047 | ARRAY_SIZE(twl6040_snd_controls)); | ||
1048 | twl6040_add_widgets(codec); | ||
1049 | |||
1050 | if (ret < 0) { | ||
1051 | dev_err(&pdev->dev, "failed to register card\n"); | ||
1052 | goto card_err; | ||
1053 | } | ||
1054 | |||
1055 | return ret; | ||
1056 | |||
1057 | card_err: | ||
1058 | snd_soc_free_pcms(socdev); | ||
1059 | snd_soc_dapm_free(socdev); | ||
1060 | return ret; | ||
1061 | } | ||
1062 | |||
1063 | static int twl6040_remove(struct platform_device *pdev) | ||
1064 | { | ||
1065 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1066 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1067 | |||
1068 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1069 | snd_soc_free_pcms(socdev); | ||
1070 | snd_soc_dapm_free(socdev); | ||
1071 | kfree(codec); | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | struct snd_soc_codec_device soc_codec_dev_twl6040 = { | ||
1077 | .probe = twl6040_probe, | ||
1078 | .remove = twl6040_remove, | ||
1079 | .suspend = twl6040_suspend, | ||
1080 | .resume = twl6040_resume, | ||
1081 | }; | ||
1082 | EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040); | ||
1083 | |||
1084 | static int __devinit twl6040_codec_probe(struct platform_device *pdev) | ||
1085 | { | 1016 | { |
1086 | struct twl4030_codec_data *twl_codec = pdev->dev.platform_data; | 1017 | struct twl4030_codec_data *twl_codec = codec->dev->platform_data; |
1087 | struct snd_soc_codec *codec; | ||
1088 | struct twl6040_data *priv; | 1018 | struct twl6040_data *priv; |
1089 | int audpwron, naudint; | 1019 | int audpwron, naudint; |
1090 | int ret = 0; | 1020 | int ret = 0; |
@@ -1092,6 +1022,7 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev) | |||
1092 | priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); | 1022 | priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); |
1093 | if (priv == NULL) | 1023 | if (priv == NULL) |
1094 | return -ENOMEM; | 1024 | return -ENOMEM; |
1025 | snd_soc_codec_set_drvdata(codec, priv); | ||
1095 | 1026 | ||
1096 | if (twl_codec) { | 1027 | if (twl_codec) { |
1097 | audpwron = twl_codec->audpwron_gpio; | 1028 | audpwron = twl_codec->audpwron_gpio; |
@@ -1104,29 +1035,6 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev) | |||
1104 | priv->audpwron = audpwron; | 1035 | priv->audpwron = audpwron; |
1105 | priv->naudint = naudint; | 1036 | priv->naudint = naudint; |
1106 | 1037 | ||
1107 | codec = &priv->codec; | ||
1108 | codec->dev = &pdev->dev; | ||
1109 | twl6040_dai.dev = &pdev->dev; | ||
1110 | |||
1111 | codec->name = "twl6040"; | ||
1112 | codec->owner = THIS_MODULE; | ||
1113 | codec->read = twl6040_read_reg_cache; | ||
1114 | codec->write = twl6040_write; | ||
1115 | codec->set_bias_level = twl6040_set_bias_level; | ||
1116 | snd_soc_codec_set_drvdata(codec, priv); | ||
1117 | codec->dai = &twl6040_dai; | ||
1118 | codec->num_dai = 1; | ||
1119 | codec->reg_cache_size = ARRAY_SIZE(twl6040_reg); | ||
1120 | codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg), | ||
1121 | GFP_KERNEL); | ||
1122 | if (codec->reg_cache == NULL) { | ||
1123 | ret = -ENOMEM; | ||
1124 | goto cache_err; | ||
1125 | } | ||
1126 | |||
1127 | mutex_init(&codec->mutex); | ||
1128 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1129 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1130 | init_completion(&priv->ready); | 1038 | init_completion(&priv->ready); |
1131 | 1039 | ||
1132 | if (gpio_is_valid(audpwron)) { | 1040 | if (gpio_is_valid(audpwron)) { |
@@ -1169,23 +1077,12 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev) | |||
1169 | if (ret) | 1077 | if (ret) |
1170 | goto irq_err; | 1078 | goto irq_err; |
1171 | 1079 | ||
1172 | ret = snd_soc_register_codec(codec); | 1080 | snd_soc_add_controls(codec, twl6040_snd_controls, |
1173 | if (ret) | 1081 | ARRAY_SIZE(twl6040_snd_controls)); |
1174 | goto reg_err; | 1082 | twl6040_add_widgets(codec); |
1175 | |||
1176 | twl6040_codec = codec; | ||
1177 | |||
1178 | ret = snd_soc_register_dai(&twl6040_dai); | ||
1179 | if (ret) | ||
1180 | goto dai_err; | ||
1181 | 1083 | ||
1182 | return 0; | 1084 | return 0; |
1183 | 1085 | ||
1184 | dai_err: | ||
1185 | snd_soc_unregister_codec(codec); | ||
1186 | twl6040_codec = NULL; | ||
1187 | reg_err: | ||
1188 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1189 | irq_err: | 1086 | irq_err: |
1190 | if (naudint) | 1087 | if (naudint) |
1191 | free_irq(naudint, codec); | 1088 | free_irq(naudint, codec); |
@@ -1193,36 +1090,57 @@ gpio2_err: | |||
1193 | if (gpio_is_valid(audpwron)) | 1090 | if (gpio_is_valid(audpwron)) |
1194 | gpio_free(audpwron); | 1091 | gpio_free(audpwron); |
1195 | gpio1_err: | 1092 | gpio1_err: |
1196 | kfree(codec->reg_cache); | ||
1197 | cache_err: | ||
1198 | kfree(priv); | 1093 | kfree(priv); |
1199 | return ret; | 1094 | return ret; |
1200 | } | 1095 | } |
1201 | 1096 | ||
1202 | static int __devexit twl6040_codec_remove(struct platform_device *pdev) | 1097 | static int twl6040_remove(struct snd_soc_codec *codec) |
1203 | { | 1098 | { |
1204 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec); | 1099 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
1205 | int audpwron = priv->audpwron; | 1100 | int audpwron = priv->audpwron; |
1206 | int naudint = priv->naudint; | 1101 | int naudint = priv->naudint; |
1207 | 1102 | ||
1103 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1104 | |||
1208 | if (gpio_is_valid(audpwron)) | 1105 | if (gpio_is_valid(audpwron)) |
1209 | gpio_free(audpwron); | 1106 | gpio_free(audpwron); |
1210 | 1107 | ||
1211 | if (naudint) | 1108 | if (naudint) |
1212 | free_irq(naudint, twl6040_codec); | 1109 | free_irq(naudint, codec); |
1213 | 1110 | ||
1214 | snd_soc_unregister_dai(&twl6040_dai); | 1111 | kfree(priv); |
1215 | snd_soc_unregister_codec(twl6040_codec); | ||
1216 | 1112 | ||
1217 | kfree(twl6040_codec); | 1113 | return 0; |
1218 | twl6040_codec = NULL; | 1114 | } |
1219 | 1115 | ||
1116 | static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | ||
1117 | .probe = twl6040_probe, | ||
1118 | .remove = twl6040_remove, | ||
1119 | .suspend = twl6040_suspend, | ||
1120 | .resume = twl6040_resume, | ||
1121 | .read = twl6040_read_reg_cache, | ||
1122 | .write = twl6040_write, | ||
1123 | .set_bias_level = twl6040_set_bias_level, | ||
1124 | .reg_cache_size = ARRAY_SIZE(twl6040_reg), | ||
1125 | .reg_word_size = sizeof(u8), | ||
1126 | .reg_cache_default = twl6040_reg, | ||
1127 | }; | ||
1128 | |||
1129 | static int __devinit twl6040_codec_probe(struct platform_device *pdev) | ||
1130 | { | ||
1131 | return snd_soc_register_codec(&pdev->dev, | ||
1132 | &soc_codec_dev_twl6040, &twl6040_dai, 1); | ||
1133 | } | ||
1134 | |||
1135 | static int __devexit twl6040_codec_remove(struct platform_device *pdev) | ||
1136 | { | ||
1137 | snd_soc_unregister_codec(&pdev->dev); | ||
1220 | return 0; | 1138 | return 0; |
1221 | } | 1139 | } |
1222 | 1140 | ||
1223 | static struct platform_driver twl6040_codec_driver = { | 1141 | static struct platform_driver twl6040_codec_driver = { |
1224 | .driver = { | 1142 | .driver = { |
1225 | .name = "twl6040_codec", | 1143 | .name = "twl6040-codec", |
1226 | .owner = THIS_MODULE, | 1144 | .owner = THIS_MODULE, |
1227 | }, | 1145 | }, |
1228 | .probe = twl6040_codec_probe, | 1146 | .probe = twl6040_codec_probe, |