aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-11-19 02:23:17 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-11-24 01:31:00 -0500
commit22de4e1fe446794acaebdf19dcaff4256d659972 (patch)
treedaafc6b0c41ef1c0ad6f4cab642994523096e743
parentd4bc99b977e3a1dd10a84a01ebe59ac2ccebf0cd (diff)
ARM: mach-shmobile: ap4evb: FSI clock use proper process for ak4642
Current AP4 FSI didn't use set_rate for ak4642, and used dummy rate when init. And FSI driver was modified to always call set_rate. The user which are using FSI set_rate is only AP4 now. 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.c96
-rw-r--r--sound/soc/sh/fsi.c8
2 files changed, 68 insertions, 36 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 61c1068198ec..e084b423146e 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -575,7 +575,7 @@ static int __fsi_set_rate(struct clk *clk, long rate, int enable)
575 return ret; 575 return ret;
576 576
577 if (enable) { 577 if (enable) {
578 ret = clk_set_rate(clk, clk_round_rate(clk, rate)); 578 ret = clk_set_rate(clk, rate);
579 if (0 == ret) 579 if (0 == ret)
580 ret = clk_enable(clk); 580 ret = clk_enable(clk);
581 } else { 581 } else {
@@ -585,7 +585,56 @@ static int __fsi_set_rate(struct clk *clk, long rate, int enable)
585 return ret; 585 return ret;
586} 586}
587 587
588static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) 588static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
589{
590 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
591}
592
593static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
594{
595 struct clk *fsia_ick;
596 struct clk *fsiack;
597 int ret = -EIO;
598
599 fsia_ick = clk_get(dev, "icka");
600 if (IS_ERR(fsia_ick))
601 return PTR_ERR(fsia_ick);
602
603 /*
604 * FSIACK is connected to AK4642,
605 * and use external clock pin from it.
606 * it is parent of fsia_ick now.
607 */
608 fsiack = clk_get_parent(fsia_ick);
609 if (!fsiack)
610 goto fsia_ick_out;
611
612 /*
613 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
614 *
615 ** FIXME **
616 * Because the freq_table of external clk (fsiack) are all 0,
617 * the return value of clk_round_rate became 0.
618 * So, it use __fsi_set_rate here.
619 */
620 ret = __fsi_set_rate(fsiack, rate, enable);
621 if (ret < 0)
622 goto fsiack_out;
623
624 ret = __fsi_set_round_rate(fsia_ick, rate, enable);
625 if ((ret < 0) && enable)
626 __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
627
628fsiack_out:
629 clk_put(fsiack);
630
631fsia_ick_out:
632 clk_put(fsia_ick);
633
634 return 0;
635}
636
637static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
589{ 638{
590 struct clk *fsib_clk; 639 struct clk *fsib_clk;
591 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 640 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
@@ -594,10 +643,6 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
594 int ackmd_bpfmd; 643 int ackmd_bpfmd;
595 int ret; 644 int ret;
596 645
597 /* set_rate is not needed if port A */
598 if (is_porta)
599 return 0;
600
601 switch (rate) { 646 switch (rate) {
602 case 44100: 647 case 44100:
603 fsib_rate = rate * 256; 648 fsib_rate = rate * 256;
@@ -618,23 +663,35 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
618 if (IS_ERR(fsib_clk)) 663 if (IS_ERR(fsib_clk))
619 return -EIO; 664 return -EIO;
620 665
621 ret = __fsi_set_rate(fsib_clk, fsib_rate, enable); 666 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
622 clk_put(fsib_clk); 667 clk_put(fsib_clk);
623 if (ret < 0) 668 if (ret < 0)
624 return ret; 669 return ret;
625 670
626 /* FSI DIV setting */ 671 /* FSI DIV setting */
627 ret = __fsi_set_rate(fdiv_clk, fdiv_rate, enable); 672 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
628 if (ret < 0) { 673 if (ret < 0) {
629 /* disable FSI B */ 674 /* disable FSI B */
630 if (enable) 675 if (enable)
631 __fsi_set_rate(fsib_clk, fsib_rate, 0); 676 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
632 return ret; 677 return ret;
633 } 678 }
634 679
635 return ackmd_bpfmd; 680 return ackmd_bpfmd;
636} 681}
637 682
683static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
684{
685 int ret;
686
687 if (is_porta)
688 ret = fsi_ak4642_set_rate(dev, rate, enable);
689 else
690 ret = fsi_hdmi_set_rate(dev, rate, enable);
691
692 return ret;
693}
694
638static struct sh_fsi_platform_info fsi_info = { 695static struct sh_fsi_platform_info fsi_info = {
639 .porta_flags = SH_FSI_BRS_INV | 696 .porta_flags = SH_FSI_BRS_INV |
640 SH_FSI_OUT_SLAVE_MODE | 697 SH_FSI_OUT_SLAVE_MODE |
@@ -928,23 +985,11 @@ out:
928 985
929device_initcall(hdmi_init_pm_clock); 986device_initcall(hdmi_init_pm_clock);
930 987
931#define FSIACK_DUMMY_RATE 48000
932static int __init fsi_init_pm_clock(void) 988static int __init fsi_init_pm_clock(void)
933{ 989{
934 struct clk *fsia_ick; 990 struct clk *fsia_ick;
935 int ret; 991 int ret;
936 992
937 /*
938 * FSIACK is connected to AK4642,
939 * and the rate is depend on playing sound rate.
940 * So, set dummy rate (= 48k) here
941 */
942 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
943 if (ret < 0) {
944 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
945 return ret;
946 }
947
948 fsia_ick = clk_get(&fsi_device.dev, "icka"); 993 fsia_ick = clk_get(&fsi_device.dev, "icka");
949 if (IS_ERR(fsia_ick)) { 994 if (IS_ERR(fsia_ick)) {
950 ret = PTR_ERR(fsia_ick); 995 ret = PTR_ERR(fsia_ick);
@@ -953,16 +998,9 @@ static int __init fsi_init_pm_clock(void)
953 } 998 }
954 999
955 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1000 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
956 if (ret < 0) {
957 pr_err("Cannot set FSI-A parent: %d\n", ret);
958 goto out;
959 }
960
961 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
962 if (ret < 0) 1001 if (ret < 0)
963 pr_err("Cannot set FSI-A rate: %d\n", ret); 1002 pr_err("Cannot set FSI-A parent: %d\n", ret);
964 1003
965out:
966 clk_put(fsia_ick); 1004 clk_put(fsia_ick);
967 1005
968 return ret; 1006 return ret;
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 136414f163e9..4c2404b1b862 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -902,18 +902,12 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
902 struct fsi_master *master = fsi_get_master(fsi); 902 struct fsi_master *master = fsi_get_master(fsi);
903 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 903 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
904 int fsi_ver = master->core->ver; 904 int fsi_ver = master->core->ver;
905 int is_play = fsi_is_play(substream);
906 long rate = params_rate(params); 905 long rate = params_rate(params);
907 int ret; 906 int ret;
908 907
909 /* if slave mode, set_rate is not needed */
910 if (!fsi_is_master_mode(fsi, is_play))
911 return 0;
912
913 /* it is error if no set_rate */
914 set_rate = master->info->set_rate; 908 set_rate = master->info->set_rate;
915 if (!set_rate) 909 if (!set_rate)
916 return -EIO; 910 return 0;
917 911
918 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1); 912 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
919 if (ret < 0) /* error */ 913 if (ret < 0) /* error */