diff options
Diffstat (limited to 'sound/soc/codecs/ad1980.c')
-rw-r--r-- | sound/soc/codecs/ad1980.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 042072738cdc..1371afac657b 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | struct snd_soc_dai ad1980_dai = { | 133 | struct snd_soc_dai_driver ad1980_dai = { |
134 | .name = "AC97", | 134 | .name = "ad1980-hifi", |
135 | .ac97_control = 1, | 135 | .ac97_control = 1, |
136 | .playback = { | 136 | .playback = { |
137 | .stream_name = "Playback", | 137 | .stream_name = "Playback", |
@@ -177,53 +177,20 @@ err: | |||
177 | return -EIO; | 177 | return -EIO; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int ad1980_soc_probe(struct platform_device *pdev) | 180 | static int ad1980_soc_probe(struct snd_soc_codec *codec) |
181 | { | 181 | { |
182 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 182 | int ret; |
183 | struct snd_soc_codec *codec; | ||
184 | int ret = 0; | ||
185 | u16 vendor_id2; | 183 | u16 vendor_id2; |
186 | u16 ext_status; | 184 | u16 ext_status; |
187 | 185 | ||
188 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); | 186 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); |
189 | 187 | ||
190 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
191 | if (socdev->card->codec == NULL) | ||
192 | return -ENOMEM; | ||
193 | codec = socdev->card->codec; | ||
194 | mutex_init(&codec->mutex); | ||
195 | |||
196 | codec->reg_cache = | ||
197 | kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL); | ||
198 | if (codec->reg_cache == NULL) { | ||
199 | ret = -ENOMEM; | ||
200 | goto cache_err; | ||
201 | } | ||
202 | memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \ | ||
203 | ARRAY_SIZE(ad1980_reg)); | ||
204 | codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg); | ||
205 | codec->reg_cache_step = 2; | ||
206 | codec->name = "AD1980"; | ||
207 | codec->owner = THIS_MODULE; | ||
208 | codec->dai = &ad1980_dai; | ||
209 | codec->num_dai = 1; | ||
210 | codec->write = ac97_write; | ||
211 | codec->read = ac97_read; | ||
212 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
213 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
214 | |||
215 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 188 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
216 | if (ret < 0) { | 189 | if (ret < 0) { |
217 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); | 190 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); |
218 | goto codec_err; | 191 | return ret; |
219 | } | 192 | } |
220 | 193 | ||
221 | /* register pcms */ | ||
222 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
223 | if (ret < 0) | ||
224 | goto pcm_err; | ||
225 | |||
226 | |||
227 | ret = ad1980_reset(codec, 0); | 194 | ret = ad1980_reset(codec, 0); |
228 | if (ret < 0) { | 195 | if (ret < 0) { |
229 | printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); | 196 | printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); |
@@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev) | |||
262 | return 0; | 229 | return 0; |
263 | 230 | ||
264 | reset_err: | 231 | reset_err: |
265 | snd_soc_free_pcms(socdev); | ||
266 | |||
267 | pcm_err: | ||
268 | snd_soc_free_ac97_codec(codec); | 232 | snd_soc_free_ac97_codec(codec); |
269 | |||
270 | codec_err: | ||
271 | kfree(codec->reg_cache); | ||
272 | |||
273 | cache_err: | ||
274 | kfree(socdev->card->codec); | ||
275 | socdev->card->codec = NULL; | ||
276 | return ret; | 233 | return ret; |
277 | } | 234 | } |
278 | 235 | ||
279 | static int ad1980_soc_remove(struct platform_device *pdev) | 236 | static int ad1980_soc_remove(struct snd_soc_codec *codec) |
280 | { | 237 | { |
281 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
282 | struct snd_soc_codec *codec = socdev->card->codec; | ||
283 | |||
284 | if (codec == NULL) | ||
285 | return 0; | ||
286 | |||
287 | snd_soc_dapm_free(socdev); | ||
288 | snd_soc_free_pcms(socdev); | ||
289 | snd_soc_free_ac97_codec(codec); | 238 | snd_soc_free_ac97_codec(codec); |
290 | kfree(codec->reg_cache); | ||
291 | kfree(codec); | ||
292 | return 0; | 239 | return 0; |
293 | } | 240 | } |
294 | 241 | ||
295 | struct snd_soc_codec_device soc_codec_dev_ad1980 = { | 242 | static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { |
296 | .probe = ad1980_soc_probe, | 243 | .probe = ad1980_soc_probe, |
297 | .remove = ad1980_soc_remove, | 244 | .remove = ad1980_soc_remove, |
245 | .reg_cache_size = ARRAY_SIZE(ad1980_reg), | ||
246 | .reg_word_size = sizeof(u16), | ||
247 | .reg_cache_step = 2, | ||
248 | .write = ac97_write, | ||
249 | .read = ac97_read, | ||
298 | }; | 250 | }; |
299 | EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); | 251 | |
252 | static __devinit int ad1980_probe(struct platform_device *pdev) | ||
253 | { | ||
254 | return snd_soc_register_codec(&pdev->dev, | ||
255 | &soc_codec_dev_ad1980, &ad1980_dai, 1); | ||
256 | } | ||
257 | |||
258 | static int __devexit ad1980_remove(struct platform_device *pdev) | ||
259 | { | ||
260 | snd_soc_unregister_codec(&pdev->dev); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static struct platform_driver ad1980_codec_driver = { | ||
265 | .driver = { | ||
266 | .name = "ad1980-codec", | ||
267 | .owner = THIS_MODULE, | ||
268 | }, | ||
269 | |||
270 | .probe = ad1980_probe, | ||
271 | .remove = __devexit_p(ad1980_remove), | ||
272 | }; | ||
273 | |||
274 | static int __init ad1980_init(void) | ||
275 | { | ||
276 | return platform_driver_register(&ad1980_codec_driver); | ||
277 | } | ||
278 | module_init(ad1980_init); | ||
279 | |||
280 | static void __exit ad1980_exit(void) | ||
281 | { | ||
282 | platform_driver_unregister(&ad1980_codec_driver); | ||
283 | } | ||
284 | module_exit(ad1980_exit); | ||
300 | 285 | ||
301 | MODULE_DESCRIPTION("ASoC ad1980 driver"); | 286 | MODULE_DESCRIPTION("ASoC ad1980 driver"); |
302 | MODULE_AUTHOR("Roy Huang, Cliff Cai"); | 287 | MODULE_AUTHOR("Roy Huang, Cliff Cai"); |