aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9705.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9705.c')
-rw-r--r--sound/soc/codecs/wm9705.c116
1 files changed, 50 insertions, 66 deletions
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 8793341849d1..e4d8f5339c51 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
276struct snd_soc_dai wm9705_dai[] = { 275static 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};
307EXPORT_SYMBOL_GPL(wm9705_dai);
308 306
309static int wm9705_reset(struct snd_soc_codec *codec) 307static 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
321static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg) 319static 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
331static int wm9705_soc_resume(struct platform_device *pdev) 326static 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
355static int wm9705_soc_probe(struct platform_device *pdev) 348static 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
408reset_err: 370reset_err:
409 snd_soc_free_pcms(socdev);
410pcm_err:
411 snd_soc_free_ac97_codec(codec); 371 snd_soc_free_ac97_codec(codec);
412codec_err:
413 kfree(codec->reg_cache);
414cache_err:
415 kfree(socdev->card->codec);
416 socdev->card->codec = NULL;
417 return ret; 372 return ret;
418} 373}
419 374
420static int wm9705_soc_remove(struct platform_device *pdev) 375static 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
436struct snd_soc_codec_device soc_codec_dev_wm9705 = { 381static 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 = sizeof(wm9705_reg),
389 .reg_word_size = sizeof(u16),
390 .reg_cache_step = 2,
391 .reg_cache_default = wm9705_reg,
392};
393
394static __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
400static int __devexit wm9705_remove(struct platform_device *pdev)
401{
402 snd_soc_unregister_codec(&pdev->dev);
403 return 0;
404}
405
406static 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};
442EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); 415
416static int __init wm9705_init(void)
417{
418 return platform_driver_register(&wm9705_codec_driver);
419}
420module_init(wm9705_init);
421
422static void __exit wm9705_exit(void)
423{
424 platform_driver_unregister(&wm9705_codec_driver);
425}
426module_exit(wm9705_exit);
443 427
444MODULE_DESCRIPTION("ASoC WM9705 driver"); 428MODULE_DESCRIPTION("ASoC WM9705 driver");
445MODULE_AUTHOR("Ian Molton"); 429MODULE_AUTHOR("Ian Molton");