diff options
Diffstat (limited to 'sound/soc/codecs/ak4642.c')
-rw-r--r-- | sound/soc/codecs/ak4642.c | 175 |
1 files changed, 37 insertions, 138 deletions
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3d7dc55305e..31b35e96739 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
31 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
32 | 32 | ||
33 | #include "ak4642.h" | ||
34 | |||
35 | #define AK4642_VERSION "0.0.1" | 33 | #define AK4642_VERSION "0.0.1" |
36 | 34 | ||
37 | #define PW_MGMT1 0x00 | 35 | #define PW_MGMT1 0x00 |
@@ -102,7 +100,6 @@ | |||
102 | #define FS3 (1 << 5) | 100 | #define FS3 (1 << 5) |
103 | #define FS_MASK (FS0 | FS1 | FS2 | FS3) | 101 | #define FS_MASK (FS0 | FS1 | FS2 | FS3) |
104 | 102 | ||
105 | struct snd_soc_codec_device soc_codec_dev_ak4642; | ||
106 | 103 | ||
107 | /* | 104 | /* |
108 | * Playback Volume (table 39) | 105 | * Playback Volume (table 39) |
@@ -123,11 +120,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
123 | 120 | ||
124 | /* codec private data */ | 121 | /* codec private data */ |
125 | struct ak4642_priv { | 122 | struct ak4642_priv { |
126 | struct snd_soc_codec codec; | 123 | unsigned int sysclk; |
124 | enum snd_soc_control_type control_type; | ||
125 | void *control_data; | ||
127 | }; | 126 | }; |
128 | 127 | ||
129 | static struct snd_soc_codec *ak4642_codec; | ||
130 | |||
131 | /* | 128 | /* |
132 | * ak4642 register cache | 129 | * ak4642 register cache |
133 | */ | 130 | */ |
@@ -393,8 +390,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = { | |||
393 | .hw_params = ak4642_dai_hw_params, | 390 | .hw_params = ak4642_dai_hw_params, |
394 | }; | 391 | }; |
395 | 392 | ||
396 | struct snd_soc_dai ak4642_dai = { | 393 | static struct snd_soc_dai_driver ak4642_dai = { |
397 | .name = "AK4642", | 394 | .name = "ak4642-hifi", |
398 | .playback = { | 395 | .playback = { |
399 | .stream_name = "Playback", | 396 | .stream_name = "Playback", |
400 | .channels_min = 1, | 397 | .channels_min = 1, |
@@ -410,112 +407,63 @@ struct snd_soc_dai ak4642_dai = { | |||
410 | .ops = &ak4642_dai_ops, | 407 | .ops = &ak4642_dai_ops, |
411 | .symmetric_rates = 1, | 408 | .symmetric_rates = 1, |
412 | }; | 409 | }; |
413 | EXPORT_SYMBOL_GPL(ak4642_dai); | ||
414 | 410 | ||
415 | static int ak4642_resume(struct platform_device *pdev) | 411 | static int ak4642_resume(struct snd_soc_codec *codec) |
416 | { | 412 | { |
417 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
418 | struct snd_soc_codec *codec = socdev->card->codec; | ||
419 | |||
420 | ak4642_sync(codec); | 413 | ak4642_sync(codec); |
421 | return 0; | 414 | return 0; |
422 | } | 415 | } |
423 | 416 | ||
424 | /* | 417 | |
425 | * initialise the AK4642 driver | 418 | static int ak4642_probe(struct snd_soc_codec *codec) |
426 | * register the mixer and dsp interfaces with the kernel | ||
427 | */ | ||
428 | static int ak4642_init(struct ak4642_priv *ak4642) | ||
429 | { | 419 | { |
430 | struct snd_soc_codec *codec = &ak4642->codec; | 420 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); |
431 | int ret = 0; | ||
432 | 421 | ||
433 | if (ak4642_codec) { | 422 | dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); |
434 | dev_err(codec->dev, "Another ak4642 is registered\n"); | ||
435 | return -EINVAL; | ||
436 | } | ||
437 | 423 | ||
438 | mutex_init(&codec->mutex); | ||
439 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
440 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
441 | |||
442 | snd_soc_codec_set_drvdata(codec, ak4642); | ||
443 | codec->name = "AK4642"; | ||
444 | codec->owner = THIS_MODULE; | ||
445 | codec->read = ak4642_read_reg_cache; | ||
446 | codec->write = ak4642_write; | ||
447 | codec->dai = &ak4642_dai; | ||
448 | codec->num_dai = 1; | ||
449 | codec->hw_write = (hw_write_t)i2c_master_send; | 424 | codec->hw_write = (hw_write_t)i2c_master_send; |
450 | codec->reg_cache_size = ARRAY_SIZE(ak4642_reg); | 425 | codec->control_data = ak4642->control_data; |
451 | codec->reg_cache = kmemdup(ak4642_reg, | ||
452 | sizeof(ak4642_reg), GFP_KERNEL); | ||
453 | |||
454 | if (!codec->reg_cache) | ||
455 | return -ENOMEM; | ||
456 | |||
457 | ak4642_dai.dev = codec->dev; | ||
458 | ak4642_codec = codec; | ||
459 | |||
460 | ret = snd_soc_register_codec(codec); | ||
461 | if (ret) { | ||
462 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
463 | goto reg_cache_err; | ||
464 | } | ||
465 | 426 | ||
466 | ret = snd_soc_register_dai(&ak4642_dai); | ||
467 | if (ret) { | ||
468 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | ||
469 | snd_soc_unregister_codec(codec); | ||
470 | goto reg_cache_err; | ||
471 | } | ||
472 | |||
473 | return ret; | ||
474 | |||
475 | reg_cache_err: | ||
476 | kfree(codec->reg_cache); | ||
477 | codec->reg_cache = NULL; | ||
478 | 427 | ||
479 | return ret; | 428 | return 0; |
480 | } | 429 | } |
481 | 430 | ||
431 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | ||
432 | .probe = ak4642_probe, | ||
433 | .resume = ak4642_resume, | ||
434 | .read = ak4642_read_reg_cache, | ||
435 | .write = ak4642_write, | ||
436 | .reg_cache_size = ARRAY_SIZE(ak4642_reg), | ||
437 | .reg_word_size = sizeof(u8), | ||
438 | .reg_cache_default = ak4642_reg, | ||
439 | }; | ||
440 | |||
482 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 441 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
483 | static int ak4642_i2c_probe(struct i2c_client *i2c, | 442 | static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, |
484 | const struct i2c_device_id *id) | 443 | const struct i2c_device_id *id) |
485 | { | 444 | { |
486 | struct ak4642_priv *ak4642; | 445 | struct ak4642_priv *ak4642; |
487 | struct snd_soc_codec *codec; | ||
488 | int ret; | 446 | int ret; |
489 | 447 | ||
490 | ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL); | 448 | ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL); |
491 | if (!ak4642) | 449 | if (ak4642 == NULL) |
492 | return -ENOMEM; | 450 | return -ENOMEM; |
493 | 451 | ||
494 | codec = &ak4642->codec; | ||
495 | codec->dev = &i2c->dev; | ||
496 | |||
497 | i2c_set_clientdata(i2c, ak4642); | 452 | i2c_set_clientdata(i2c, ak4642); |
498 | codec->control_data = i2c; | 453 | ak4642->control_data = i2c; |
454 | ak4642->control_type = SND_SOC_I2C; | ||
499 | 455 | ||
500 | ret = ak4642_init(ak4642); | 456 | ret = snd_soc_register_codec(&i2c->dev, |
501 | if (ret < 0) { | 457 | &soc_codec_dev_ak4642, &ak4642_dai, 1); |
502 | printk(KERN_ERR "failed to initialise AK4642\n"); | 458 | if (ret < 0) |
503 | kfree(ak4642); | 459 | kfree(ak4642); |
504 | } | ||
505 | |||
506 | return ret; | 460 | return ret; |
507 | } | 461 | } |
508 | 462 | ||
509 | static int ak4642_i2c_remove(struct i2c_client *client) | 463 | static __devexit int ak4642_i2c_remove(struct i2c_client *client) |
510 | { | 464 | { |
511 | struct ak4642_priv *ak4642 = i2c_get_clientdata(client); | 465 | snd_soc_unregister_codec(&client->dev); |
512 | 466 | kfree(i2c_get_clientdata(client)); | |
513 | snd_soc_unregister_dai(&ak4642_dai); | ||
514 | snd_soc_unregister_codec(&ak4642->codec); | ||
515 | kfree(ak4642->codec.reg_cache); | ||
516 | kfree(ak4642); | ||
517 | ak4642_codec = NULL; | ||
518 | |||
519 | return 0; | 467 | return 0; |
520 | } | 468 | } |
521 | 469 | ||
@@ -528,64 +476,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); | |||
528 | 476 | ||
529 | static struct i2c_driver ak4642_i2c_driver = { | 477 | static struct i2c_driver ak4642_i2c_driver = { |
530 | .driver = { | 478 | .driver = { |
531 | .name = "AK4642 I2C Codec", | 479 | .name = "ak4642-codec", |
532 | .owner = THIS_MODULE, | 480 | .owner = THIS_MODULE, |
533 | }, | 481 | }, |
534 | .probe = ak4642_i2c_probe, | 482 | .probe = ak4642_i2c_probe, |
535 | .remove = ak4642_i2c_remove, | 483 | .remove = __devexit_p(ak4642_i2c_remove), |
536 | .id_table = ak4642_i2c_id, | 484 | .id_table = ak4642_i2c_id, |
537 | }; | 485 | }; |
538 | |||
539 | #endif | 486 | #endif |
540 | 487 | ||
541 | static int ak4642_probe(struct platform_device *pdev) | ||
542 | { | ||
543 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
544 | int ret; | ||
545 | |||
546 | if (!ak4642_codec) { | ||
547 | dev_err(&pdev->dev, "Codec device not registered\n"); | ||
548 | return -ENODEV; | ||
549 | } | ||
550 | |||
551 | socdev->card->codec = ak4642_codec; | ||
552 | |||
553 | /* register pcms */ | ||
554 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
555 | if (ret < 0) { | ||
556 | printk(KERN_ERR "ak4642: failed to create pcms\n"); | ||
557 | goto pcm_err; | ||
558 | } | ||
559 | |||
560 | snd_soc_add_controls(ak4642_codec, ak4642_snd_controls, | ||
561 | ARRAY_SIZE(ak4642_snd_controls)); | ||
562 | |||
563 | dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); | ||
564 | return ret; | ||
565 | |||
566 | pcm_err: | ||
567 | return ret; | ||
568 | |||
569 | } | ||
570 | |||
571 | /* power down chip */ | ||
572 | static int ak4642_remove(struct platform_device *pdev) | ||
573 | { | ||
574 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
575 | |||
576 | snd_soc_free_pcms(socdev); | ||
577 | snd_soc_dapm_free(socdev); | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | struct snd_soc_codec_device soc_codec_dev_ak4642 = { | ||
583 | .probe = ak4642_probe, | ||
584 | .remove = ak4642_remove, | ||
585 | .resume = ak4642_resume, | ||
586 | }; | ||
587 | EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642); | ||
588 | |||
589 | static int __init ak4642_modinit(void) | 488 | static int __init ak4642_modinit(void) |
590 | { | 489 | { |
591 | int ret = 0; | 490 | int ret = 0; |