aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8741.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8741.c')
-rw-r--r--sound/soc/codecs/wm8741.c204
1 files changed, 57 insertions, 147 deletions
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index b9ea8904ad4b..0c6d59e4d226 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -30,9 +30,6 @@
30 30
31#include "wm8741.h" 31#include "wm8741.h"
32 32
33static struct snd_soc_codec *wm8741_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8741;
35
36#define WM8741_NUM_SUPPLIES 2 33#define WM8741_NUM_SUPPLIES 2
37static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { 34static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
38 "AVDD", 35 "AVDD",
@@ -43,7 +40,8 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
43 40
44/* codec private data */ 41/* codec private data */
45struct wm8741_priv { 42struct wm8741_priv {
46 struct snd_soc_codec codec; 43 enum snd_soc_control_type control_type;
44 void *control_data;
47 u16 reg_cache[WM8741_REGISTER_COUNT]; 45 u16 reg_cache[WM8741_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; 46 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
49 unsigned int sysclk; 47 unsigned int sysclk;
@@ -145,8 +143,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 143 struct snd_soc_dai *dai)
146{ 144{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev; 146 struct snd_soc_codec *codec = rtd->codec;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 147 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
151 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 148 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
152 int i; 149 int i;
@@ -314,7 +311,7 @@ static struct snd_soc_dai_ops wm8741_dai_ops = {
314 .set_fmt = wm8741_set_dai_fmt, 311 .set_fmt = wm8741_set_dai_fmt,
315}; 312};
316 313
317struct snd_soc_dai wm8741_dai = { 314static struct snd_soc_dai_driver wm8741_dai = {
318 .name = "WM8741", 315 .name = "WM8741",
319 .playback = { 316 .playback = {
320 .stream_name = "Playback", 317 .stream_name = "Playback",
@@ -325,13 +322,10 @@ struct snd_soc_dai wm8741_dai = {
325 }, 322 },
326 .ops = &wm8741_dai_ops, 323 .ops = &wm8741_dai_ops,
327}; 324};
328EXPORT_SYMBOL_GPL(wm8741_dai);
329 325
330#ifdef CONFIG_PM 326#ifdef CONFIG_PM
331static int wm8741_resume(struct platform_device *pdev) 327static int wm8741_resume(struct snd_soc_codec *codec)
332{ 328{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 u16 *cache = codec->reg_cache; 329 u16 *cache = codec->reg_cache;
336 int i; 330 int i;
337 331
@@ -348,189 +342,105 @@ static int wm8741_resume(struct platform_device *pdev)
348#define wm8741_resume NULL 342#define wm8741_resume NULL
349#endif 343#endif
350 344
351static int wm8741_probe(struct platform_device *pdev) 345static int wm8741_probe(struct snd_soc_codec *codec)
352{ 346{
353 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 347 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
354 struct snd_soc_codec *codec;
355 int ret = 0; 348 int ret = 0;
356 349
357 if (wm8741_codec == NULL) { 350 codec->control_data = wm8741->control_data;
358 dev_err(&pdev->dev, "Codec device not registered\n"); 351 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
359 return -ENODEV; 352 if (ret != 0) {
353 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
354 return ret;
360 } 355 }
361 356
362 socdev->card->codec = wm8741_codec; 357 ret = wm8741_reset(codec);
363 codec = wm8741_codec;
364
365 /* register pcms */
366 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
367 if (ret < 0) { 358 if (ret < 0) {
368 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 359 dev_err(codec->dev, "Failed to issue reset\n");
369 goto pcm_err; 360 return ret;
370 } 361 }
371 362
363 /* Change some default settings - latch VU */
364 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
365 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
366 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
367 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
368
372 snd_soc_add_controls(codec, wm8741_snd_controls, 369 snd_soc_add_controls(codec, wm8741_snd_controls,
373 ARRAY_SIZE(wm8741_snd_controls)); 370 ARRAY_SIZE(wm8741_snd_controls));
374 wm8741_add_widgets(codec); 371 wm8741_add_widgets(codec);
375 372
373 dev_dbg(codec->dev, "Successful registration\n");
376 return ret; 374 return ret;
377
378pcm_err:
379 return ret;
380}
381
382static int wm8741_remove(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385
386 snd_soc_free_pcms(socdev);
387 snd_soc_dapm_free(socdev);
388
389 return 0;
390} 375}
391 376
392struct snd_soc_codec_device soc_codec_dev_wm8741 = { 377static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
393 .probe = wm8741_probe, 378 .probe = wm8741_probe,
394 .remove = wm8741_remove,
395 .resume = wm8741_resume, 379 .resume = wm8741_resume,
380 .reg_cache_size = sizeof(wm8741_reg_defaults),
381 .reg_word_size = sizeof(u16),
382 .reg_cache_default = &wm8741_reg_defaults,
396}; 383};
397EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
398 384
399static int wm8741_register(struct wm8741_priv *wm8741, 385#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
400 enum snd_soc_control_type control) 386static int wm8741_i2c_probe(struct i2c_client *i2c,
387 const struct i2c_device_id *id)
401{ 388{
402 int ret; 389 struct wm8741_priv *wm8741;
403 struct snd_soc_codec *codec = &wm8741->codec; 390 int ret, i;
404 int i;
405
406 if (wm8741_codec) {
407 dev_err(codec->dev, "Another WM8741 is registered\n");
408 return -EINVAL;
409 }
410
411 mutex_init(&codec->mutex);
412 INIT_LIST_HEAD(&codec->dapm_widgets);
413 INIT_LIST_HEAD(&codec->dapm_paths);
414 391
415 snd_soc_codec_set_drvdata(codec, wm8741); 392 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
416 codec->name = "WM8741"; 393 if (wm8741 == NULL)
417 codec->owner = THIS_MODULE; 394 return -ENOMEM;
418 codec->bias_level = SND_SOC_BIAS_OFF;
419 codec->set_bias_level = NULL;
420 codec->dai = &wm8741_dai;
421 codec->num_dai = 1;
422 codec->reg_cache_size = WM8741_REGISTER_COUNT;
423 codec->reg_cache = &wm8741->reg_cache;
424 395
425 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0]; 396 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
426 wm8741->rate_constraint.count = 397 wm8741->rate_constraint.count =
427 ARRAY_SIZE(wm8741->rate_constraint_list); 398 ARRAY_SIZE(wm8741->rate_constraint_list);
428 399
429 memcpy(codec->reg_cache, wm8741_reg_defaults,
430 sizeof(wm8741->reg_cache));
431
432 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
435 goto err;
436 }
437
438 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) 400 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
439 wm8741->supplies[i].supply = wm8741_supply_names[i]; 401 wm8741->supplies[i].supply = wm8741_supply_names[i];
440 402
441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies), 403 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
442 wm8741->supplies); 404 wm8741->supplies);
443 if (ret != 0) { 405 if (ret != 0) {
444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 406 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
445 goto err; 407 goto err;
446 } 408 }
447 409
448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), 410 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
449 wm8741->supplies); 411 wm8741->supplies);
450 if (ret != 0) { 412 if (ret != 0) {
451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 413 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
452 goto err_get; 414 goto err_get;
453 } 415 }
454 416
455 ret = wm8741_reset(codec); 417 i2c_set_clientdata(i2c, wm8741);
456 if (ret < 0) { 418 wm8741->control_data = i2c;
457 dev_err(codec->dev, "Failed to issue reset\n"); 419 wm8741->control_type = SND_SOC_I2C;
458 goto err_enable;
459 }
460
461 wm8741_dai.dev = codec->dev;
462
463 /* Change some default settings - latch VU */
464 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
465 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
466 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
467 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
468
469 wm8741_codec = codec;
470
471 ret = snd_soc_register_codec(codec);
472 if (ret != 0) {
473 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
474 return ret;
475 }
476
477 ret = snd_soc_register_dai(&wm8741_dai);
478 if (ret != 0) {
479 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
480 snd_soc_unregister_codec(codec);
481 return ret;
482 }
483 420
484 dev_dbg(codec->dev, "Successful registration\n"); 421 ret = snd_soc_register_codec(&i2c->dev,
485 return 0; 422 &soc_codec_dev_wm8741, &wm8741_dai, 1);
423 if (ret < 0)
424 goto err_enable;
425 return ret;
486 426
487err_enable: 427err_enable:
488 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 428 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489 429
490err_get: 430err_get:
491 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 431 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
492
493err: 432err:
494 kfree(wm8741); 433 kfree(wm8741);
495 return ret; 434 return ret;
496} 435}
497 436
498static void wm8741_unregister(struct wm8741_priv *wm8741) 437static int wm8741_i2c_remove(struct i2c_client *client)
499{
500 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
501
502 snd_soc_unregister_dai(&wm8741_dai);
503 snd_soc_unregister_codec(&wm8741->codec);
504 kfree(wm8741);
505 wm8741_codec = NULL;
506}
507
508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
509static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
510 const struct i2c_device_id *id)
511{
512 struct wm8741_priv *wm8741;
513 struct snd_soc_codec *codec;
514
515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
516 if (wm8741 == NULL)
517 return -ENOMEM;
518
519 codec = &wm8741->codec;
520 codec->hw_write = (hw_write_t)i2c_master_send;
521
522 i2c_set_clientdata(i2c, wm8741);
523 codec->control_data = i2c;
524
525 codec->dev = &i2c->dev;
526
527 return wm8741_register(wm8741, SND_SOC_I2C);
528}
529
530static __devexit int wm8741_i2c_remove(struct i2c_client *client)
531{ 438{
532 struct wm8741_priv *wm8741 = i2c_get_clientdata(client); 439 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
533 wm8741_unregister(wm8741); 440
441 snd_soc_unregister_codec(&client->dev);
442 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
443 kfree(i2c_get_clientdata(client));
534 return 0; 444 return 0;
535} 445}
536 446
@@ -540,29 +450,29 @@ static const struct i2c_device_id wm8741_i2c_id[] = {
540}; 450};
541MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id); 451MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
542 452
543
544static struct i2c_driver wm8741_i2c_driver = { 453static struct i2c_driver wm8741_i2c_driver = {
545 .driver = { 454 .driver = {
546 .name = "WM8741", 455 .name = "wm8741-codec",
547 .owner = THIS_MODULE, 456 .owner = THIS_MODULE,
548 }, 457 },
549 .probe = wm8741_i2c_probe, 458 .probe = wm8741_i2c_probe,
550 .remove = __devexit_p(wm8741_i2c_remove), 459 .remove = wm8741_i2c_remove,
551 .id_table = wm8741_i2c_id, 460 .id_table = wm8741_i2c_id,
552}; 461};
553#endif 462#endif
554 463
555static int __init wm8741_modinit(void) 464static int __init wm8741_modinit(void)
556{ 465{
557 int ret; 466 int ret = 0;
467
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 468#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
559 ret = i2c_add_driver(&wm8741_i2c_driver); 469 ret = i2c_add_driver(&wm8741_i2c_driver);
560 if (ret != 0) { 470 if (ret != 0) {
561 printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n", 471 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
562 ret);
563 } 472 }
564#endif 473#endif
565 return 0; 474
475 return ret;
566} 476}
567module_init(wm8741_modinit); 477module_init(wm8741_modinit);
568 478