diff options
Diffstat (limited to 'sound/soc/codecs/ak4671.c')
-rw-r--r-- | sound/soc/codecs/ak4671.c | 141 |
1 files changed, 30 insertions, 111 deletions
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 87566932a3b1..239f0562003c 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -23,11 +23,11 @@ | |||
23 | 23 | ||
24 | #include "ak4671.h" | 24 | #include "ak4671.h" |
25 | 25 | ||
26 | static struct snd_soc_codec *ak4671_codec; | ||
27 | 26 | ||
28 | /* codec private data */ | 27 | /* codec private data */ |
29 | struct ak4671_priv { | 28 | struct ak4671_priv { |
30 | struct snd_soc_codec codec; | 29 | enum snd_soc_control_type control_type; |
30 | void *control_data; | ||
31 | u8 reg_cache[AK4671_CACHEREGNUM]; | 31 | u8 reg_cache[AK4671_CACHEREGNUM]; |
32 | }; | 32 | }; |
33 | 33 | ||
@@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = { | |||
619 | .set_fmt = ak4671_set_dai_fmt, | 619 | .set_fmt = ak4671_set_dai_fmt, |
620 | }; | 620 | }; |
621 | 621 | ||
622 | struct snd_soc_dai ak4671_dai = { | 622 | static struct snd_soc_dai_driver ak4671_dai = { |
623 | .name = "AK4671", | 623 | .name = "ak4671-hifi", |
624 | .playback = { | 624 | .playback = { |
625 | .stream_name = "Playback", | 625 | .stream_name = "Playback", |
626 | .channels_min = 1, | 626 | .channels_min = 1, |
@@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = { | |||
635 | .formats = AK4671_FORMATS,}, | 635 | .formats = AK4671_FORMATS,}, |
636 | .ops = &ak4671_dai_ops, | 636 | .ops = &ak4671_dai_ops, |
637 | }; | 637 | }; |
638 | EXPORT_SYMBOL_GPL(ak4671_dai); | ||
639 | 638 | ||
640 | static int ak4671_probe(struct platform_device *pdev) | 639 | static int ak4671_probe(struct snd_soc_codec *codec) |
641 | { | 640 | { |
642 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 641 | struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); |
643 | struct snd_soc_codec *codec; | 642 | int ret; |
644 | int ret = 0; | ||
645 | |||
646 | if (ak4671_codec == NULL) { | ||
647 | dev_err(&pdev->dev, "Codec device not registered\n"); | ||
648 | return -ENODEV; | ||
649 | } | ||
650 | 643 | ||
651 | socdev->card->codec = ak4671_codec; | 644 | codec->hw_write = (hw_write_t)i2c_master_send; |
652 | codec = ak4671_codec; | 645 | codec->bias_level = SND_SOC_BIAS_OFF; |
653 | 646 | ||
654 | /* register pcms */ | 647 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); |
655 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
656 | if (ret < 0) { | 648 | if (ret < 0) { |
657 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); | 649 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
658 | goto pcm_err; | 650 | return ret; |
659 | } | 651 | } |
660 | 652 | ||
661 | snd_soc_add_controls(codec, ak4671_snd_controls, | 653 | snd_soc_add_controls(codec, ak4671_snd_controls, |
@@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev) | |||
665 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 657 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
666 | 658 | ||
667 | return ret; | 659 | return ret; |
668 | |||
669 | pcm_err: | ||
670 | return ret; | ||
671 | } | 660 | } |
672 | 661 | ||
673 | static int ak4671_remove(struct platform_device *pdev) | 662 | static int ak4671_remove(struct snd_soc_codec *codec) |
674 | { | 663 | { |
675 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 664 | ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF); |
676 | |||
677 | snd_soc_free_pcms(socdev); | ||
678 | snd_soc_dapm_free(socdev); | ||
679 | |||
680 | return 0; | 665 | return 0; |
681 | } | 666 | } |
682 | 667 | ||
683 | struct snd_soc_codec_device soc_codec_dev_ak4671 = { | 668 | static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { |
684 | .probe = ak4671_probe, | 669 | .probe = ak4671_probe, |
685 | .remove = ak4671_remove, | 670 | .remove = ak4671_remove, |
671 | .set_bias_level = ak4671_set_bias_level, | ||
672 | .reg_cache_size = AK4671_CACHEREGNUM, | ||
673 | .reg_word_size = sizeof(u8), | ||
674 | .reg_cache_default = ak4671_reg, | ||
686 | }; | 675 | }; |
687 | EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671); | ||
688 | |||
689 | static int ak4671_register(struct ak4671_priv *ak4671, | ||
690 | enum snd_soc_control_type control) | ||
691 | { | ||
692 | int ret; | ||
693 | struct snd_soc_codec *codec = &ak4671->codec; | ||
694 | |||
695 | if (ak4671_codec) { | ||
696 | dev_err(codec->dev, "Another AK4671 is registered\n"); | ||
697 | ret = -EINVAL; | ||
698 | goto err; | ||
699 | } | ||
700 | |||
701 | mutex_init(&codec->mutex); | ||
702 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
703 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
704 | |||
705 | snd_soc_codec_set_drvdata(codec, ak4671); | ||
706 | codec->name = "AK4671"; | ||
707 | codec->owner = THIS_MODULE; | ||
708 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
709 | codec->set_bias_level = ak4671_set_bias_level; | ||
710 | codec->dai = &ak4671_dai; | ||
711 | codec->num_dai = 1; | ||
712 | codec->reg_cache_size = AK4671_CACHEREGNUM; | ||
713 | codec->reg_cache = &ak4671->reg_cache; | ||
714 | |||
715 | memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg)); | ||
716 | |||
717 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, control); | ||
718 | if (ret < 0) { | ||
719 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
720 | goto err; | ||
721 | } | ||
722 | |||
723 | ak4671_dai.dev = codec->dev; | ||
724 | ak4671_codec = codec; | ||
725 | |||
726 | ret = snd_soc_register_codec(codec); | ||
727 | if (ret != 0) { | ||
728 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
729 | goto err; | ||
730 | } | ||
731 | |||
732 | ret = snd_soc_register_dai(&ak4671_dai); | ||
733 | if (ret != 0) { | ||
734 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | ||
735 | goto err_codec; | ||
736 | } | ||
737 | |||
738 | return 0; | ||
739 | |||
740 | err_codec: | ||
741 | snd_soc_unregister_codec(codec); | ||
742 | err: | ||
743 | kfree(ak4671); | ||
744 | return ret; | ||
745 | } | ||
746 | |||
747 | static void ak4671_unregister(struct ak4671_priv *ak4671) | ||
748 | { | ||
749 | ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF); | ||
750 | snd_soc_unregister_dai(&ak4671_dai); | ||
751 | snd_soc_unregister_codec(&ak4671->codec); | ||
752 | kfree(ak4671); | ||
753 | ak4671_codec = NULL; | ||
754 | } | ||
755 | 676 | ||
756 | static int __devinit ak4671_i2c_probe(struct i2c_client *client, | 677 | static int __devinit ak4671_i2c_probe(struct i2c_client *client, |
757 | const struct i2c_device_id *id) | 678 | const struct i2c_device_id *id) |
758 | { | 679 | { |
759 | struct ak4671_priv *ak4671; | 680 | struct ak4671_priv *ak4671; |
760 | struct snd_soc_codec *codec; | 681 | int ret; |
761 | 682 | ||
762 | ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); | 683 | ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); |
763 | if (ak4671 == NULL) | 684 | if (ak4671 == NULL) |
764 | return -ENOMEM; | 685 | return -ENOMEM; |
765 | 686 | ||
766 | codec = &ak4671->codec; | ||
767 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
768 | |||
769 | i2c_set_clientdata(client, ak4671); | 687 | i2c_set_clientdata(client, ak4671); |
770 | codec->control_data = client; | 688 | ak4671->control_data = client; |
771 | 689 | ak4671->control_type = SND_SOC_I2C; | |
772 | codec->dev = &client->dev; | ||
773 | 690 | ||
774 | return ak4671_register(ak4671, SND_SOC_I2C); | 691 | ret = snd_soc_register_codec(&client->dev, |
692 | &soc_codec_dev_ak4671, &ak4671_dai, 1); | ||
693 | if (ret < 0) | ||
694 | kfree(ak4671); | ||
695 | return ret; | ||
775 | } | 696 | } |
776 | 697 | ||
777 | static __devexit int ak4671_i2c_remove(struct i2c_client *client) | 698 | static __devexit int ak4671_i2c_remove(struct i2c_client *client) |
778 | { | 699 | { |
779 | struct ak4671_priv *ak4671 = i2c_get_clientdata(client); | 700 | snd_soc_unregister_codec(&client->dev); |
780 | 701 | kfree(i2c_get_clientdata(client)); | |
781 | ak4671_unregister(ak4671); | ||
782 | |||
783 | return 0; | 702 | return 0; |
784 | } | 703 | } |
785 | 704 | ||
@@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id); | |||
791 | 710 | ||
792 | static struct i2c_driver ak4671_i2c_driver = { | 711 | static struct i2c_driver ak4671_i2c_driver = { |
793 | .driver = { | 712 | .driver = { |
794 | .name = "ak4671", | 713 | .name = "ak4671-codec", |
795 | .owner = THIS_MODULE, | 714 | .owner = THIS_MODULE, |
796 | }, | 715 | }, |
797 | .probe = ak4671_i2c_probe, | 716 | .probe = ak4671_i2c_probe, |