aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-11-23 21:44:06 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-11-24 01:29:56 -0500
commitd4bc99b977e3a1dd10a84a01ebe59ac2ccebf0cd (patch)
tree441a72709a1dd40ac84b89cec8b036f00960a96b
parente8ee13a818db4954517cea7da6e7c15b9656eb00 (diff)
ARM: mach-shmobile: ap4evb: FSI clock use proper process for HDMI
Current AP4 FSI set_rate function used bogus clock process which didn't care enable/disable and clk->usecound. To solve this issue, this patch also modify FSI driver to call set_rate with enough options. This patch modify it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c58
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c2
-rw-r--r--include/sound/sh_fsi.h6
-rw-r--r--sound/soc/sh/fsi.c19
4 files changed, 67 insertions, 18 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d3260542b943..61c1068198ec 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -567,40 +567,72 @@ static struct platform_device *qhd_devices[] __initdata = {
567 567
568/* FSI */ 568/* FSI */
569#define IRQ_FSI evt2irq(0x1840) 569#define IRQ_FSI evt2irq(0x1840)
570static int __fsi_set_rate(struct clk *clk, long rate, int enable)
571{
572 int ret = 0;
573
574 if (rate <= 0)
575 return ret;
570 576
571static int fsi_set_rate(int is_porta, int rate) 577 if (enable) {
578 ret = clk_set_rate(clk, clk_round_rate(clk, rate));
579 if (0 == ret)
580 ret = clk_enable(clk);
581 } else {
582 clk_disable(clk);
583 }
584
585 return ret;
586}
587
588static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
572{ 589{
573 struct clk *fsib_clk; 590 struct clk *fsib_clk;
574 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 591 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
592 long fsib_rate = 0;
593 long fdiv_rate = 0;
594 int ackmd_bpfmd;
575 int ret; 595 int ret;
576 596
577 /* set_rate is not needed if port A */ 597 /* set_rate is not needed if port A */
578 if (is_porta) 598 if (is_porta)
579 return 0; 599 return 0;
580 600
581 fsib_clk = clk_get(NULL, "fsib_clk");
582 if (IS_ERR(fsib_clk))
583 return -EINVAL;
584
585 switch (rate) { 601 switch (rate) {
586 case 44100: 602 case 44100:
587 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); 603 fsib_rate = rate * 256;
588 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 604 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
589 break; 605 break;
590 case 48000: 606 case 48000:
591 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); 607 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
592 clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); 608 fdiv_rate = rate * 256;
593 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 609 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
594 break; 610 break;
595 default: 611 default:
596 pr_err("unsupported rate in FSI2 port B\n"); 612 pr_err("unsupported rate in FSI2 port B\n");
597 ret = -EINVAL; 613 return -EINVAL;
598 break;
599 } 614 }
600 615
616 /* FSI B setting */
617 fsib_clk = clk_get(dev, "ickb");
618 if (IS_ERR(fsib_clk))
619 return -EIO;
620
621 ret = __fsi_set_rate(fsib_clk, fsib_rate, enable);
601 clk_put(fsib_clk); 622 clk_put(fsib_clk);
623 if (ret < 0)
624 return ret;
602 625
603 return ret; 626 /* FSI DIV setting */
627 ret = __fsi_set_rate(fdiv_clk, fdiv_rate, enable);
628 if (ret < 0) {
629 /* disable FSI B */
630 if (enable)
631 __fsi_set_rate(fsib_clk, fsib_rate, 0);
632 return ret;
633 }
634
635 return ackmd_bpfmd;
604} 636}
605 637
606static struct sh_fsi_platform_info fsi_info = { 638static struct sh_fsi_platform_info fsi_info = {
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 13226323e4e0..4191e2921127 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -471,7 +471,7 @@ static int fsidiv_set_rate(struct clk *clk,
471 return -ENOENT; 471 return -ENOENT;
472 472
473 __raw_writel(idx << 16, clk->mapping->base); 473 __raw_writel(idx << 16, clk->mapping->base);
474 return fsidiv_enable(clk); 474 return 0;
475} 475}
476 476
477static struct clk_ops fsidiv_clk_ops = { 477static struct clk_ops fsidiv_clk_ops = {
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index fa60cbda90a4..d79894192ae3 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -85,7 +85,9 @@
85 * ACK_MD (FSI2) 85 * ACK_MD (FSI2)
86 * CKG1 (FSI) 86 * CKG1 (FSI)
87 * 87 *
88 * err: return value < 0 88 * err : return value < 0
89 * no change : return value == 0
90 * change xMD : return value > 0
89 * 91 *
90 * 0x-00000AB 92 * 0x-00000AB
91 * 93 *
@@ -111,7 +113,7 @@
111struct sh_fsi_platform_info { 113struct sh_fsi_platform_info {
112 unsigned long porta_flags; 114 unsigned long porta_flags;
113 unsigned long portb_flags; 115 unsigned long portb_flags;
114 int (*set_rate)(int is_porta, int rate); /* for master mode */ 116 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
115}; 117};
116 118
117#endif /* __SOUND_FSI_H */ 119#endif /* __SOUND_FSI_H */
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 507e709f2807..136414f163e9 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -132,6 +132,8 @@ struct fsi_priv {
132 struct fsi_stream playback; 132 struct fsi_stream playback;
133 struct fsi_stream capture; 133 struct fsi_stream capture;
134 134
135 long rate;
136
135 u32 mst_ctrl; 137 u32 mst_ctrl;
136}; 138};
137 139
@@ -854,10 +856,17 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
854{ 856{
855 struct fsi_priv *fsi = fsi_get_priv(substream); 857 struct fsi_priv *fsi = fsi_get_priv(substream);
856 int is_play = fsi_is_play(substream); 858 int is_play = fsi_is_play(substream);
859 struct fsi_master *master = fsi_get_master(fsi);
860 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
857 861
858 fsi_irq_disable(fsi, is_play); 862 fsi_irq_disable(fsi, is_play);
859 fsi_clk_ctrl(fsi, 0); 863 fsi_clk_ctrl(fsi, 0);
860 864
865 set_rate = master->info->set_rate;
866 if (set_rate && fsi->rate)
867 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
868 fsi->rate = 0;
869
861 pm_runtime_put_sync(dai->dev); 870 pm_runtime_put_sync(dai->dev);
862} 871}
863 872
@@ -891,9 +900,10 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
891{ 900{
892 struct fsi_priv *fsi = fsi_get_priv(substream); 901 struct fsi_priv *fsi = fsi_get_priv(substream);
893 struct fsi_master *master = fsi_get_master(fsi); 902 struct fsi_master *master = fsi_get_master(fsi);
894 int (*set_rate)(int is_porta, int rate) = master->info->set_rate; 903 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
895 int fsi_ver = master->core->ver; 904 int fsi_ver = master->core->ver;
896 int is_play = fsi_is_play(substream); 905 int is_play = fsi_is_play(substream);
906 long rate = params_rate(params);
897 int ret; 907 int ret;
898 908
899 /* if slave mode, set_rate is not needed */ 909 /* if slave mode, set_rate is not needed */
@@ -901,10 +911,15 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
901 return 0; 911 return 0;
902 912
903 /* it is error if no set_rate */ 913 /* it is error if no set_rate */
914 set_rate = master->info->set_rate;
904 if (!set_rate) 915 if (!set_rate)
905 return -EIO; 916 return -EIO;
906 917
907 ret = set_rate(fsi_is_port_a(fsi), params_rate(params)); 918 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
919 if (ret < 0) /* error */
920 return ret;
921
922 fsi->rate = rate;
908 if (ret > 0) { 923 if (ret > 0) {
909 u32 data = 0; 924 u32 data = 0;
910 925