aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/siu_dai.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/siu_dai.c')
-rw-r--r--sound/soc/sh/siu_dai.c97
1 files changed, 58 insertions, 39 deletions
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index eeed5edd722b..af53b64d8af2 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -71,6 +71,8 @@ struct port_flag {
71 struct format_flag capture; 71 struct format_flag capture;
72}; 72};
73 73
74struct siu_info *siu_i2s_data;
75
74static struct port_flag siu_flags[SIU_PORT_NUM] = { 76static struct port_flag siu_flags[SIU_PORT_NUM] = {
75 [SIU_PORT_A] = { 77 [SIU_PORT_A] = {
76 .playback = { 78 .playback = {
@@ -104,13 +106,13 @@ static struct port_flag siu_flags[SIU_PORT_NUM] = {
104 106
105static void siu_dai_start(struct siu_port *port_info) 107static void siu_dai_start(struct siu_port *port_info)
106{ 108{
107 struct siu_info *info = siu_i2s_dai.private_data; 109 struct siu_info *info = siu_i2s_data;
108 u32 __iomem *base = info->reg; 110 u32 __iomem *base = info->reg;
109 111
110 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); 112 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
111 113
112 /* Turn on SIU clock */ 114 /* Turn on SIU clock */
113 pm_runtime_get_sync(siu_i2s_dai.dev); 115 pm_runtime_get_sync(info->dev);
114 116
115 /* Issue software reset to siu */ 117 /* Issue software reset to siu */
116 siu_write32(base + SIU_SRCTL, 0); 118 siu_write32(base + SIU_SRCTL, 0);
@@ -148,21 +150,21 @@ static void siu_dai_start(struct siu_port *port_info)
148 siu_write32(base + SIU_SBDVCB, port_info->capture.volume); 150 siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
149} 151}
150 152
151static void siu_dai_stop(void) 153static void siu_dai_stop(struct siu_port *port_info)
152{ 154{
153 struct siu_info *info = siu_i2s_dai.private_data; 155 struct siu_info *info = siu_i2s_data;
154 u32 __iomem *base = info->reg; 156 u32 __iomem *base = info->reg;
155 157
156 /* SIU software reset */ 158 /* SIU software reset */
157 siu_write32(base + SIU_SRCTL, 0); 159 siu_write32(base + SIU_SRCTL, 0);
158 160
159 /* Turn off SIU clock */ 161 /* Turn off SIU clock */
160 pm_runtime_put_sync(siu_i2s_dai.dev); 162 pm_runtime_put_sync(info->dev);
161} 163}
162 164
163static void siu_dai_spbAselect(struct siu_port *port_info) 165static void siu_dai_spbAselect(struct siu_port *port_info)
164{ 166{
165 struct siu_info *info = siu_i2s_dai.private_data; 167 struct siu_info *info = siu_i2s_data;
166 struct siu_firmware *fw = &info->fw; 168 struct siu_firmware *fw = &info->fw;
167 u32 *ydef = fw->yram0; 169 u32 *ydef = fw->yram0;
168 u32 idx; 170 u32 idx;
@@ -187,7 +189,7 @@ static void siu_dai_spbAselect(struct siu_port *port_info)
187 189
188static void siu_dai_spbBselect(struct siu_port *port_info) 190static void siu_dai_spbBselect(struct siu_port *port_info)
189{ 191{
190 struct siu_info *info = siu_i2s_dai.private_data; 192 struct siu_info *info = siu_i2s_data;
191 struct siu_firmware *fw = &info->fw; 193 struct siu_firmware *fw = &info->fw;
192 u32 *ydef = fw->yram0; 194 u32 *ydef = fw->yram0;
193 u32 idx; 195 u32 idx;
@@ -207,7 +209,7 @@ static void siu_dai_spbBselect(struct siu_port *port_info)
207 209
208static void siu_dai_open(struct siu_stream *siu_stream) 210static void siu_dai_open(struct siu_stream *siu_stream)
209{ 211{
210 struct siu_info *info = siu_i2s_dai.private_data; 212 struct siu_info *info = siu_i2s_data;
211 u32 __iomem *base = info->reg; 213 u32 __iomem *base = info->reg;
212 u32 srctl, ifctl; 214 u32 srctl, ifctl;
213 215
@@ -238,7 +240,7 @@ static void siu_dai_open(struct siu_stream *siu_stream)
238 */ 240 */
239static void siu_dai_pcmdatapack(struct siu_stream *siu_stream) 241static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
240{ 242{
241 struct siu_info *info = siu_i2s_dai.private_data; 243 struct siu_info *info = siu_i2s_data;
242 u32 __iomem *base = info->reg; 244 u32 __iomem *base = info->reg;
243 u32 dpak; 245 u32 dpak;
244 246
@@ -258,7 +260,7 @@ static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
258 260
259static int siu_dai_spbstart(struct siu_port *port_info) 261static int siu_dai_spbstart(struct siu_port *port_info)
260{ 262{
261 struct siu_info *info = siu_i2s_dai.private_data; 263 struct siu_info *info = siu_i2s_data;
262 u32 __iomem *base = info->reg; 264 u32 __iomem *base = info->reg;
263 struct siu_firmware *fw = &info->fw; 265 struct siu_firmware *fw = &info->fw;
264 u32 *ydef = fw->yram0; 266 u32 *ydef = fw->yram0;
@@ -323,7 +325,7 @@ static int siu_dai_spbstart(struct siu_port *port_info)
323 325
324static void siu_dai_spbstop(struct siu_port *port_info) 326static void siu_dai_spbstop(struct siu_port *port_info)
325{ 327{
326 struct siu_info *info = siu_i2s_dai.private_data; 328 struct siu_info *info = siu_i2s_data;
327 u32 __iomem *base = info->reg; 329 u32 __iomem *base = info->reg;
328 330
329 siu_write32(base + SIU_SBACTIV, 0); 331 siu_write32(base + SIU_SBACTIV, 0);
@@ -402,7 +404,7 @@ static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
402{ 404{
403 struct siu_port *port_info = snd_kcontrol_chip(kctrl); 405 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
404 struct device *dev = port_info->pcm->card->dev; 406 struct device *dev = port_info->pcm->card->dev;
405 struct siu_info *info = siu_i2s_dai.private_data; 407 struct siu_info *info = siu_i2s_data;
406 u32 __iomem *base = info->reg; 408 u32 __iomem *base = info->reg;
407 u32 new_vol; 409 u32 new_vol;
408 u32 cur_vol; 410 u32 cur_vol;
@@ -510,7 +512,7 @@ void siu_free_port(struct siu_port *port_info)
510static int siu_dai_startup(struct snd_pcm_substream *substream, 512static int siu_dai_startup(struct snd_pcm_substream *substream,
511 struct snd_soc_dai *dai) 513 struct snd_soc_dai *dai)
512{ 514{
513 struct siu_info *info = siu_i2s_dai.private_data; 515 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
514 struct snd_pcm_runtime *rt = substream->runtime; 516 struct snd_pcm_runtime *rt = substream->runtime;
515 struct siu_port *port_info = siu_port_info(substream); 517 struct siu_port *port_info = siu_port_info(substream);
516 int ret; 518 int ret;
@@ -532,7 +534,7 @@ static int siu_dai_startup(struct snd_pcm_substream *substream,
532static void siu_dai_shutdown(struct snd_pcm_substream *substream, 534static void siu_dai_shutdown(struct snd_pcm_substream *substream,
533 struct snd_soc_dai *dai) 535 struct snd_soc_dai *dai)
534{ 536{
535 struct siu_info *info = siu_i2s_dai.private_data; 537 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
536 struct siu_port *port_info = siu_port_info(substream); 538 struct siu_port *port_info = siu_port_info(substream);
537 539
538 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, 540 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
@@ -548,7 +550,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
548 /* during stmread or stmwrite ? */ 550 /* during stmread or stmwrite ? */
549 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg); 551 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
550 siu_dai_spbstop(port_info); 552 siu_dai_spbstop(port_info);
551 siu_dai_stop(); 553 siu_dai_stop(port_info);
552 } 554 }
553} 555}
554 556
@@ -556,7 +558,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
556static int siu_dai_prepare(struct snd_pcm_substream *substream, 558static int siu_dai_prepare(struct snd_pcm_substream *substream,
557 struct snd_soc_dai *dai) 559 struct snd_soc_dai *dai)
558{ 560{
559 struct siu_info *info = siu_i2s_dai.private_data; 561 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
560 struct snd_pcm_runtime *rt = substream->runtime; 562 struct snd_pcm_runtime *rt = substream->runtime;
561 struct siu_port *port_info = siu_port_info(substream); 563 struct siu_port *port_info = siu_port_info(substream);
562 struct siu_stream *siu_stream; 564 struct siu_stream *siu_stream;
@@ -605,7 +607,7 @@ fail:
605static int siu_dai_set_fmt(struct snd_soc_dai *dai, 607static int siu_dai_set_fmt(struct snd_soc_dai *dai,
606 unsigned int fmt) 608 unsigned int fmt)
607{ 609{
608 struct siu_info *info = siu_i2s_dai.private_data; 610 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
609 u32 __iomem *base = info->reg; 611 u32 __iomem *base = info->reg;
610 u32 ifctl; 612 u32 ifctl;
611 613
@@ -671,21 +673,37 @@ static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
671 return -EINVAL; 673 return -EINVAL;
672 } 674 }
673 675
674 siu_clk = clk_get(siu_i2s_dai.dev, siu_name); 676 siu_clk = clk_get(dai->dev, siu_name);
675 if (IS_ERR(siu_clk)) 677 if (IS_ERR(siu_clk)) {
678 dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
679 PTR_ERR(siu_clk));
676 return PTR_ERR(siu_clk); 680 return PTR_ERR(siu_clk);
681 }
682
683 parent_clk = clk_get(dai->dev, parent_name);
684 if (IS_ERR(parent_clk)) {
685 ret = PTR_ERR(parent_clk);
686 dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
687 goto epclkget;
688 }
677 689
678 parent_clk = clk_get(siu_i2s_dai.dev, parent_name); 690 ret = clk_set_parent(siu_clk, parent_clk);
679 if (!IS_ERR(parent_clk)) { 691 if (ret < 0) {
680 ret = clk_set_parent(siu_clk, parent_clk); 692 dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
681 if (!ret) 693 goto eclksetp;
682 clk_set_rate(siu_clk, freq);
683 clk_put(parent_clk);
684 } 694 }
685 695
696 ret = clk_set_rate(siu_clk, freq);
697 if (ret < 0)
698 dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);
699
700 /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
701eclksetp:
702 clk_put(parent_clk);
703epclkget:
686 clk_put(siu_clk); 704 clk_put(siu_clk);
687 705
688 return 0; 706 return ret;
689} 707}
690 708
691static struct snd_soc_dai_ops siu_dai_ops = { 709static struct snd_soc_dai_ops siu_dai_ops = {
@@ -696,9 +714,8 @@ static struct snd_soc_dai_ops siu_dai_ops = {
696 .set_fmt = siu_dai_set_fmt, 714 .set_fmt = siu_dai_set_fmt,
697}; 715};
698 716
699struct snd_soc_dai siu_i2s_dai = { 717static struct snd_soc_dai_driver siu_i2s_dai = {
700 .name = "sh-siu", 718 .name = "siu-i2s-dai",
701 .id = 0,
702 .playback = { 719 .playback = {
703 .channels_min = 2, 720 .channels_min = 2,
704 .channels_max = 2, 721 .channels_max = 2,
@@ -713,7 +730,6 @@ struct snd_soc_dai siu_i2s_dai = {
713 }, 730 },
714 .ops = &siu_dai_ops, 731 .ops = &siu_dai_ops,
715}; 732};
716EXPORT_SYMBOL_GPL(siu_i2s_dai);
717 733
718static int __devinit siu_probe(struct platform_device *pdev) 734static int __devinit siu_probe(struct platform_device *pdev)
719{ 735{
@@ -725,6 +741,8 @@ static int __devinit siu_probe(struct platform_device *pdev)
725 info = kmalloc(sizeof(*info), GFP_KERNEL); 741 info = kmalloc(sizeof(*info), GFP_KERNEL);
726 if (!info) 742 if (!info)
727 return -ENOMEM; 743 return -ENOMEM;
744 siu_i2s_data = info;
745 info->dev = &pdev->dev;
728 746
729 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); 747 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
730 if (ret) 748 if (ret)
@@ -767,14 +785,14 @@ static int __devinit siu_probe(struct platform_device *pdev)
767 if (!info->reg) 785 if (!info->reg)
768 goto emapreg; 786 goto emapreg;
769 787
770 siu_i2s_dai.dev = &pdev->dev; 788 dev_set_drvdata(&pdev->dev, info);
771 siu_i2s_dai.private_data = info;
772 789
773 ret = snd_soc_register_dais(&siu_i2s_dai, 1); 790 /* register using ARRAY version so we can keep dai name */
791 ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1);
774 if (ret < 0) 792 if (ret < 0)
775 goto edaiinit; 793 goto edaiinit;
776 794
777 ret = snd_soc_register_platform(&siu_platform); 795 ret = snd_soc_register_platform(&pdev->dev, &siu_platform);
778 if (ret < 0) 796 if (ret < 0)
779 goto esocregp; 797 goto esocregp;
780 798
@@ -783,7 +801,7 @@ static int __devinit siu_probe(struct platform_device *pdev)
783 return ret; 801 return ret;
784 802
785esocregp: 803esocregp:
786 snd_soc_unregister_dais(&siu_i2s_dai, 1); 804 snd_soc_unregister_dai(&pdev->dev);
787edaiinit: 805edaiinit:
788 iounmap(info->reg); 806 iounmap(info->reg);
789emapreg: 807emapreg:
@@ -804,13 +822,13 @@ ereqfw:
804 822
805static int __devexit siu_remove(struct platform_device *pdev) 823static int __devexit siu_remove(struct platform_device *pdev)
806{ 824{
807 struct siu_info *info = siu_i2s_dai.private_data; 825 struct siu_info *info = dev_get_drvdata(&pdev->dev);
808 struct resource *res; 826 struct resource *res;
809 827
810 pm_runtime_disable(&pdev->dev); 828 pm_runtime_disable(&pdev->dev);
811 829
812 snd_soc_unregister_platform(&siu_platform); 830 snd_soc_unregister_platform(&pdev->dev);
813 snd_soc_unregister_dais(&siu_i2s_dai, 1); 831 snd_soc_unregister_dai(&pdev->dev);
814 832
815 iounmap(info->reg); 833 iounmap(info->reg);
816 iounmap(info->yram); 834 iounmap(info->yram);
@@ -826,7 +844,8 @@ static int __devexit siu_remove(struct platform_device *pdev)
826 844
827static struct platform_driver siu_driver = { 845static struct platform_driver siu_driver = {
828 .driver = { 846 .driver = {
829 .name = "sh_siu", 847 .owner = THIS_MODULE,
848 .name = "siu-pcm-audio",
830 }, 849 },
831 .probe = siu_probe, 850 .probe = siu_probe,
832 .remove = __devexit_p(siu_remove), 851 .remove = __devexit_p(siu_remove),