diff options
Diffstat (limited to 'sound/soc/codecs/wm9705.c')
-rw-r--r-- | sound/soc/codecs/wm9705.c | 116 |
1 files changed, 50 insertions, 66 deletions
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 8793341849d1..a144acda751c 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -248,8 +248,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, | |||
248 | { | 248 | { |
249 | struct snd_pcm_runtime *runtime = substream->runtime; | 249 | struct snd_pcm_runtime *runtime = substream->runtime; |
250 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 250 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
251 | struct snd_soc_device *socdev = rtd->socdev; | 251 | struct snd_soc_codec *codec = rtd->codec; |
252 | struct snd_soc_codec *codec = socdev->card->codec; | ||
253 | int reg; | 252 | int reg; |
254 | u16 vra; | 253 | u16 vra; |
255 | 254 | ||
@@ -273,9 +272,9 @@ static struct snd_soc_dai_ops wm9705_dai_ops = { | |||
273 | .prepare = ac97_prepare, | 272 | .prepare = ac97_prepare, |
274 | }; | 273 | }; |
275 | 274 | ||
276 | struct snd_soc_dai wm9705_dai[] = { | 275 | static struct snd_soc_dai_driver wm9705_dai[] = { |
277 | { | 276 | { |
278 | .name = "AC97 HiFi", | 277 | .name = "wm9705-hifi", |
279 | .ac97_control = 1, | 278 | .ac97_control = 1, |
280 | .playback = { | 279 | .playback = { |
281 | .stream_name = "HiFi Playback", | 280 | .stream_name = "HiFi Playback", |
@@ -294,7 +293,7 @@ struct snd_soc_dai wm9705_dai[] = { | |||
294 | .ops = &wm9705_dai_ops, | 293 | .ops = &wm9705_dai_ops, |
295 | }, | 294 | }, |
296 | { | 295 | { |
297 | .name = "AC97 Aux", | 296 | .name = "wm9705-aux", |
298 | .playback = { | 297 | .playback = { |
299 | .stream_name = "Aux Playback", | 298 | .stream_name = "Aux Playback", |
300 | .channels_min = 1, | 299 | .channels_min = 1, |
@@ -304,7 +303,6 @@ struct snd_soc_dai wm9705_dai[] = { | |||
304 | }, | 303 | }, |
305 | } | 304 | } |
306 | }; | 305 | }; |
307 | EXPORT_SYMBOL_GPL(wm9705_dai); | ||
308 | 306 | ||
309 | static int wm9705_reset(struct snd_soc_codec *codec) | 307 | static int wm9705_reset(struct snd_soc_codec *codec) |
310 | { | 308 | { |
@@ -318,20 +316,15 @@ static int wm9705_reset(struct snd_soc_codec *codec) | |||
318 | } | 316 | } |
319 | 317 | ||
320 | #ifdef CONFIG_PM | 318 | #ifdef CONFIG_PM |
321 | static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg) | 319 | static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg) |
322 | { | 320 | { |
323 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
324 | struct snd_soc_codec *codec = socdev->card->codec; | ||
325 | |||
326 | soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); | 321 | soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); |
327 | 322 | ||
328 | return 0; | 323 | return 0; |
329 | } | 324 | } |
330 | 325 | ||
331 | static int wm9705_soc_resume(struct platform_device *pdev) | 326 | static int wm9705_soc_resume(struct snd_soc_codec *codec) |
332 | { | 327 | { |
333 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
334 | struct snd_soc_codec *codec = socdev->card->codec; | ||
335 | int i, ret; | 328 | int i, ret; |
336 | u16 *cache = codec->reg_cache; | 329 | u16 *cache = codec->reg_cache; |
337 | 330 | ||
@@ -352,49 +345,18 @@ static int wm9705_soc_resume(struct platform_device *pdev) | |||
352 | #define wm9705_soc_resume NULL | 345 | #define wm9705_soc_resume NULL |
353 | #endif | 346 | #endif |
354 | 347 | ||
355 | static int wm9705_soc_probe(struct platform_device *pdev) | 348 | static int wm9705_soc_probe(struct snd_soc_codec *codec) |
356 | { | 349 | { |
357 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
358 | struct snd_soc_codec *codec; | ||
359 | int ret = 0; | 350 | int ret = 0; |
360 | 351 | ||
361 | printk(KERN_INFO "WM9705 SoC Audio Codec\n"); | 352 | printk(KERN_INFO "WM9705 SoC Audio Codec\n"); |
362 | 353 | ||
363 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), | ||
364 | GFP_KERNEL); | ||
365 | if (socdev->card->codec == NULL) | ||
366 | return -ENOMEM; | ||
367 | codec = socdev->card->codec; | ||
368 | mutex_init(&codec->mutex); | ||
369 | |||
370 | codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL); | ||
371 | if (codec->reg_cache == NULL) { | ||
372 | ret = -ENOMEM; | ||
373 | goto cache_err; | ||
374 | } | ||
375 | codec->reg_cache_size = sizeof(wm9705_reg); | ||
376 | codec->reg_cache_step = 2; | ||
377 | |||
378 | codec->name = "WM9705"; | ||
379 | codec->owner = THIS_MODULE; | ||
380 | codec->dai = wm9705_dai; | ||
381 | codec->num_dai = ARRAY_SIZE(wm9705_dai); | ||
382 | codec->write = ac97_write; | ||
383 | codec->read = ac97_read; | ||
384 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
385 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
386 | |||
387 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 354 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
388 | if (ret < 0) { | 355 | if (ret < 0) { |
389 | printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); | 356 | printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); |
390 | goto codec_err; | 357 | return ret; |
391 | } | 358 | } |
392 | 359 | ||
393 | /* register pcms */ | ||
394 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
395 | if (ret < 0) | ||
396 | goto pcm_err; | ||
397 | |||
398 | ret = wm9705_reset(codec); | 360 | ret = wm9705_reset(codec); |
399 | if (ret) | 361 | if (ret) |
400 | goto reset_err; | 362 | goto reset_err; |
@@ -406,40 +368,62 @@ static int wm9705_soc_probe(struct platform_device *pdev) | |||
406 | return 0; | 368 | return 0; |
407 | 369 | ||
408 | reset_err: | 370 | reset_err: |
409 | snd_soc_free_pcms(socdev); | ||
410 | pcm_err: | ||
411 | snd_soc_free_ac97_codec(codec); | 371 | snd_soc_free_ac97_codec(codec); |
412 | codec_err: | ||
413 | kfree(codec->reg_cache); | ||
414 | cache_err: | ||
415 | kfree(socdev->card->codec); | ||
416 | socdev->card->codec = NULL; | ||
417 | return ret; | 372 | return ret; |
418 | } | 373 | } |
419 | 374 | ||
420 | static int wm9705_soc_remove(struct platform_device *pdev) | 375 | static int wm9705_soc_remove(struct snd_soc_codec *codec) |
421 | { | 376 | { |
422 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
423 | struct snd_soc_codec *codec = socdev->card->codec; | ||
424 | |||
425 | if (codec == NULL) | ||
426 | return 0; | ||
427 | |||
428 | snd_soc_dapm_free(socdev); | ||
429 | snd_soc_free_pcms(socdev); | ||
430 | snd_soc_free_ac97_codec(codec); | 377 | snd_soc_free_ac97_codec(codec); |
431 | kfree(codec->reg_cache); | ||
432 | kfree(codec); | ||
433 | return 0; | 378 | return 0; |
434 | } | 379 | } |
435 | 380 | ||
436 | struct snd_soc_codec_device soc_codec_dev_wm9705 = { | 381 | static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { |
437 | .probe = wm9705_soc_probe, | 382 | .probe = wm9705_soc_probe, |
438 | .remove = wm9705_soc_remove, | 383 | .remove = wm9705_soc_remove, |
439 | .suspend = wm9705_soc_suspend, | 384 | .suspend = wm9705_soc_suspend, |
440 | .resume = wm9705_soc_resume, | 385 | .resume = wm9705_soc_resume, |
386 | .read = ac97_read, | ||
387 | .write = ac97_write, | ||
388 | .reg_cache_size = ARRAY_SIZE(wm9705_reg), | ||
389 | .reg_word_size = sizeof(u16), | ||
390 | .reg_cache_step = 2, | ||
391 | .reg_cache_default = wm9705_reg, | ||
392 | }; | ||
393 | |||
394 | static __devinit int wm9705_probe(struct platform_device *pdev) | ||
395 | { | ||
396 | return snd_soc_register_codec(&pdev->dev, | ||
397 | &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai)); | ||
398 | } | ||
399 | |||
400 | static int __devexit wm9705_remove(struct platform_device *pdev) | ||
401 | { | ||
402 | snd_soc_unregister_codec(&pdev->dev); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct platform_driver wm9705_codec_driver = { | ||
407 | .driver = { | ||
408 | .name = "wm9705-codec", | ||
409 | .owner = THIS_MODULE, | ||
410 | }, | ||
411 | |||
412 | .probe = wm9705_probe, | ||
413 | .remove = __devexit_p(wm9705_remove), | ||
441 | }; | 414 | }; |
442 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); | 415 | |
416 | static int __init wm9705_init(void) | ||
417 | { | ||
418 | return platform_driver_register(&wm9705_codec_driver); | ||
419 | } | ||
420 | module_init(wm9705_init); | ||
421 | |||
422 | static void __exit wm9705_exit(void) | ||
423 | { | ||
424 | platform_driver_unregister(&wm9705_codec_driver); | ||
425 | } | ||
426 | module_exit(wm9705_exit); | ||
443 | 427 | ||
444 | MODULE_DESCRIPTION("ASoC WM9705 driver"); | 428 | MODULE_DESCRIPTION("ASoC WM9705 driver"); |
445 | MODULE_AUTHOR("Ian Molton"); | 429 | MODULE_AUTHOR("Ian Molton"); |