aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/uda1380.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/codecs/uda1380.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/uda1380.c')
-rw-r--r--sound/soc/codecs/uda1380.c211
1 files changed, 57 insertions, 154 deletions
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2f925a27dcde..1a51c816e542 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -33,11 +33,9 @@
33 33
34#include "uda1380.h" 34#include "uda1380.h"
35 35
36static struct snd_soc_codec *uda1380_codec;
37
38/* codec private data */ 36/* codec private data */
39struct uda1380_priv { 37struct uda1380_priv {
40 struct snd_soc_codec codec; 38 struct snd_soc_codec *codec;
41 u16 reg_cache[UDA1380_CACHEREGNUM]; 39 u16 reg_cache[UDA1380_CACHEREGNUM];
42 unsigned int dac_clk; 40 unsigned int dac_clk;
43 struct work_struct work; 41 struct work_struct work;
@@ -135,6 +133,8 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
135 133
136static void uda1380_flush_work(struct work_struct *work) 134static void uda1380_flush_work(struct work_struct *work)
137{ 135{
136 struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
137 struct snd_soc_codec *uda1380_codec = uda1380->codec;
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
@@ -145,6 +145,7 @@ static void uda1380_flush_work(struct work_struct *work)
145 uda1380_read_reg_cache(uda1380_codec, reg)); 145 uda1380_read_reg_cache(uda1380_codec, reg));
146 clear_bit(bit, &uda1380_cache_dirty); 146 clear_bit(bit, &uda1380_cache_dirty);
147 } 147 }
148
148} 149}
149 150
150/* declarations of ALSA reg_elem_REAL controls */ 151/* declarations of ALSA reg_elem_REAL controls */
@@ -474,8 +475,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
474 struct snd_soc_dai *dai) 475 struct snd_soc_dai *dai)
475{ 476{
476 struct snd_soc_pcm_runtime *rtd = substream->private_data; 477 struct snd_soc_pcm_runtime *rtd = substream->private_data;
477 struct snd_soc_device *socdev = rtd->socdev; 478 struct snd_soc_codec *codec = rtd->codec;
478 struct snd_soc_codec *codec = socdev->card->codec;
479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); 479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
481 481
@@ -501,8 +501,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
501 struct snd_soc_dai *dai) 501 struct snd_soc_dai *dai)
502{ 502{
503 struct snd_soc_pcm_runtime *rtd = substream->private_data; 503 struct snd_soc_pcm_runtime *rtd = substream->private_data;
504 struct snd_soc_device *socdev = rtd->socdev; 504 struct snd_soc_codec *codec = rtd->codec;
505 struct snd_soc_codec *codec = socdev->card->codec;
506 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 505 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
507 506
508 /* set WSPLL power and divider if running from this clock */ 507 /* set WSPLL power and divider if running from this clock */
@@ -540,8 +539,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
540 struct snd_soc_dai *dai) 539 struct snd_soc_dai *dai)
541{ 540{
542 struct snd_soc_pcm_runtime *rtd = substream->private_data; 541 struct snd_soc_pcm_runtime *rtd = substream->private_data;
543 struct snd_soc_device *socdev = rtd->socdev; 542 struct snd_soc_codec *codec = rtd->codec;
544 struct snd_soc_codec *codec = socdev->card->codec;
545 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 543 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
546 544
547 /* shut down WSPLL power if running from this clock */ 545 /* shut down WSPLL power if running from this clock */
@@ -604,9 +602,9 @@ static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
604 .set_fmt = uda1380_set_dai_fmt_capture, 602 .set_fmt = uda1380_set_dai_fmt_capture,
605}; 603};
606 604
607struct snd_soc_dai uda1380_dai[] = { 605static struct snd_soc_dai_driver uda1380_dai[] = {
608{ 606{
609 .name = "UDA1380", 607 .name = "uda1380-hifi",
610 .playback = { 608 .playback = {
611 .stream_name = "Playback", 609 .stream_name = "Playback",
612 .channels_min = 1, 610 .channels_min = 1,
@@ -622,7 +620,7 @@ struct snd_soc_dai uda1380_dai[] = {
622 .ops = &uda1380_dai_ops, 620 .ops = &uda1380_dai_ops,
623}, 621},
624{ /* playback only - dual interface */ 622{ /* playback only - dual interface */
625 .name = "UDA1380", 623 .name = "uda1380-hifi-playback",
626 .playback = { 624 .playback = {
627 .stream_name = "Playback", 625 .stream_name = "Playback",
628 .channels_min = 1, 626 .channels_min = 1,
@@ -633,7 +631,7 @@ struct snd_soc_dai uda1380_dai[] = {
633 .ops = &uda1380_dai_ops_playback, 631 .ops = &uda1380_dai_ops_playback,
634}, 632},
635{ /* capture only - dual interface*/ 633{ /* capture only - dual interface*/
636 .name = "UDA1380", 634 .name = "uda1380-hifi-capture",
637 .capture = { 635 .capture = {
638 .stream_name = "Capture", 636 .stream_name = "Capture",
639 .channels_min = 1, 637 .channels_min = 1,
@@ -644,21 +642,15 @@ struct snd_soc_dai uda1380_dai[] = {
644 .ops = &uda1380_dai_ops_capture, 642 .ops = &uda1380_dai_ops_capture,
645}, 643},
646}; 644};
647EXPORT_SYMBOL_GPL(uda1380_dai);
648 645
649static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) 646static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
650{ 647{
651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
652 struct snd_soc_codec *codec = socdev->card->codec;
653
654 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 648 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
655 return 0; 649 return 0;
656} 650}
657 651
658static int uda1380_resume(struct platform_device *pdev) 652static int uda1380_resume(struct snd_soc_codec *codec)
659{ 653{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec = socdev->card->codec;
662 int i; 654 int i;
663 u8 data[2]; 655 u8 data[2];
664 u16 *cache = codec->reg_cache; 656 u16 *cache = codec->reg_cache;
@@ -673,91 +665,20 @@ static int uda1380_resume(struct platform_device *pdev)
673 return 0; 665 return 0;
674} 666}
675 667
676static int uda1380_probe(struct platform_device *pdev) 668static int uda1380_probe(struct snd_soc_codec *codec)
677{
678 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
679 struct snd_soc_codec *codec;
680 struct uda1380_platform_data *pdata;
681 int ret = 0;
682
683 if (uda1380_codec == NULL) {
684 dev_err(&pdev->dev, "Codec device not registered\n");
685 return -ENODEV;
686 }
687
688 socdev->card->codec = uda1380_codec;
689 codec = uda1380_codec;
690 pdata = codec->dev->platform_data;
691
692 /* register pcms */
693 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
694 if (ret < 0) {
695 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
696 goto pcm_err;
697 }
698
699 /* power on device */
700 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
701 /* set clock input */
702 switch (pdata->dac_clk) {
703 case UDA1380_DAC_CLK_SYSCLK:
704 uda1380_write(codec, UDA1380_CLK, 0);
705 break;
706 case UDA1380_DAC_CLK_WSPLL:
707 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
708 break;
709 }
710
711 snd_soc_add_controls(codec, uda1380_snd_controls,
712 ARRAY_SIZE(uda1380_snd_controls));
713 uda1380_add_widgets(codec);
714
715 return ret;
716
717pcm_err:
718 return ret;
719}
720
721/* power down chip */
722static int uda1380_remove(struct platform_device *pdev)
723{
724 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
725 struct snd_soc_codec *codec = socdev->card->codec;
726
727 if (codec->control_data)
728 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
729
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
732
733 return 0;
734}
735
736struct snd_soc_codec_device soc_codec_dev_uda1380 = {
737 .probe = uda1380_probe,
738 .remove = uda1380_remove,
739 .suspend = uda1380_suspend,
740 .resume = uda1380_resume,
741};
742EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
743
744static int uda1380_register(struct uda1380_priv *uda1380)
745{ 669{
746 int ret, i; 670 struct uda1380_platform_data *pdata =codec->dev->platform_data;
747 struct snd_soc_codec *codec = &uda1380->codec; 671 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
748 struct uda1380_platform_data *pdata = codec->dev->platform_data; 672 int ret;
749 673
750 if (uda1380_codec) { 674 codec->hw_write = (hw_write_t)i2c_master_send;
751 dev_err(codec->dev, "Another UDA1380 is registered\n");
752 return -EINVAL;
753 }
754 675
755 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset) 676 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
756 return -EINVAL; 677 return -EINVAL;
757 678
758 ret = gpio_request(pdata->gpio_power, "uda1380 power"); 679 ret = gpio_request(pdata->gpio_power, "uda1380 power");
759 if (ret) 680 if (ret)
760 goto err_out; 681 return ret;
761 ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); 682 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
762 if (ret) 683 if (ret)
763 goto err_gpio; 684 goto err_gpio;
@@ -769,25 +690,6 @@ static int uda1380_register(struct uda1380_priv *uda1380)
769 udelay(5); 690 udelay(5);
770 gpio_set_value(pdata->gpio_reset, 0); 691 gpio_set_value(pdata->gpio_reset, 0);
771 692
772 mutex_init(&codec->mutex);
773 INIT_LIST_HEAD(&codec->dapm_widgets);
774 INIT_LIST_HEAD(&codec->dapm_paths);
775
776 snd_soc_codec_set_drvdata(codec, uda1380);
777 codec->name = "UDA1380";
778 codec->owner = THIS_MODULE;
779 codec->read = uda1380_read_reg_cache;
780 codec->write = uda1380_write;
781 codec->bias_level = SND_SOC_BIAS_OFF;
782 codec->set_bias_level = uda1380_set_bias_level;
783 codec->dai = uda1380_dai;
784 codec->num_dai = ARRAY_SIZE(uda1380_dai);
785 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
786 codec->reg_cache = &uda1380->reg_cache;
787 codec->reg_cache_step = 1;
788
789 memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
790
791 ret = uda1380_reset(codec); 693 ret = uda1380_reset(codec);
792 if (ret < 0) { 694 if (ret < 0) {
793 dev_err(codec->dev, "Failed to issue reset\n"); 695 dev_err(codec->dev, "Failed to issue reset\n");
@@ -796,83 +698,84 @@ static int uda1380_register(struct uda1380_priv *uda1380)
796 698
797 INIT_WORK(&uda1380->work, uda1380_flush_work); 699 INIT_WORK(&uda1380->work, uda1380_flush_work);
798 700
799 for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++) 701 /* power on device */
800 uda1380_dai[i].dev = codec->dev; 702 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
801 703 /* set clock input */
802 uda1380_codec = codec; 704 switch (pdata->dac_clk) {
803 705 case UDA1380_DAC_CLK_SYSCLK:
804 ret = snd_soc_register_codec(codec); 706 uda1380_write(codec, UDA1380_CLK, 0);
805 if (ret != 0) { 707 break;
806 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 708 case UDA1380_DAC_CLK_WSPLL:
807 goto err_reset; 709 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
710 break;
808 } 711 }
809 712
810 ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 713 snd_soc_add_controls(codec, uda1380_snd_controls,
811 if (ret != 0) { 714 ARRAY_SIZE(uda1380_snd_controls));
812 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); 715 uda1380_add_widgets(codec);
813 goto err_dai;
814 }
815 716
816 return 0; 717 return 0;
817 718
818err_dai:
819 snd_soc_unregister_codec(codec);
820err_reset: 719err_reset:
821 gpio_set_value(pdata->gpio_power, 0); 720 gpio_set_value(pdata->gpio_power, 0);
822 gpio_free(pdata->gpio_reset); 721 gpio_free(pdata->gpio_reset);
823err_gpio: 722err_gpio:
824 gpio_free(pdata->gpio_power); 723 gpio_free(pdata->gpio_power);
825err_out:
826 return ret; 724 return ret;
827} 725}
828 726
829static void uda1380_unregister(struct uda1380_priv *uda1380) 727/* power down chip */
728static int uda1380_remove(struct snd_soc_codec *codec)
830{ 729{
831 struct snd_soc_codec *codec = &uda1380->codec; 730 struct uda1380_platform_data *pdata =codec->dev->platform_data;
832 struct uda1380_platform_data *pdata = codec->dev->platform_data;
833 731
834 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 732 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
835 snd_soc_unregister_codec(&uda1380->codec);
836 733
837 gpio_set_value(pdata->gpio_power, 0); 734 gpio_set_value(pdata->gpio_power, 0);
838 gpio_free(pdata->gpio_reset); 735 gpio_free(pdata->gpio_reset);
839 gpio_free(pdata->gpio_power); 736 gpio_free(pdata->gpio_power);
840 737
841 kfree(uda1380); 738 return 0;
842 uda1380_codec = NULL;
843} 739}
844 740
741static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
742 .probe = uda1380_probe,
743 .remove = uda1380_remove,
744 .suspend = uda1380_suspend,
745 .resume = uda1380_resume,
746 .read = uda1380_read_reg_cache,
747 .write = uda1380_write,
748 .set_bias_level = uda1380_set_bias_level,
749 .reg_cache_size = ARRAY_SIZE(uda1380_reg),
750 .reg_word_size = sizeof(u16),
751 .reg_cache_default = uda1380_reg,
752 .reg_cache_step = 1,
753};
754
845#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 755#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
846static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, 756static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
847 const struct i2c_device_id *id) 757 const struct i2c_device_id *id)
848{ 758{
849 struct uda1380_priv *uda1380; 759 struct uda1380_priv *uda1380;
850 struct snd_soc_codec *codec;
851 int ret; 760 int ret;
852 761
853 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); 762 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
854 if (uda1380 == NULL) 763 if (uda1380 == NULL)
855 return -ENOMEM; 764 return -ENOMEM;
856 765
857 codec = &uda1380->codec;
858 codec->hw_write = (hw_write_t)i2c_master_send;
859
860 i2c_set_clientdata(i2c, uda1380); 766 i2c_set_clientdata(i2c, uda1380);
861 codec->control_data = i2c;
862
863 codec->dev = &i2c->dev;
864 767
865 ret = uda1380_register(uda1380); 768 ret = snd_soc_register_codec(&i2c->dev,
866 if (ret != 0) 769 &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
770 if (ret < 0)
867 kfree(uda1380); 771 kfree(uda1380);
868
869 return ret; 772 return ret;
870} 773}
871 774
872static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) 775static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
873{ 776{
874 struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c); 777 snd_soc_unregister_codec(&i2c->dev);
875 uda1380_unregister(uda1380); 778 kfree(i2c_get_clientdata(i2c));
876 return 0; 779 return 0;
877} 780}
878 781
@@ -884,7 +787,7 @@ MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
884 787
885static struct i2c_driver uda1380_i2c_driver = { 788static struct i2c_driver uda1380_i2c_driver = {
886 .driver = { 789 .driver = {
887 .name = "UDA1380 I2C Codec", 790 .name = "uda1380-codec",
888 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
889 }, 792 },
890 .probe = uda1380_i2c_probe, 793 .probe = uda1380_i2c_probe,