aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-12-21 22:56:10 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-12-21 22:56:10 -0500
commit7ccbefe07ea0a3570e44d1ec13a307552ee4dadd (patch)
treeba0299694a9f3940f289b6a29cadab853906e3d2 /arch/arm/mach-shmobile/board-ap4evb.c
parent623eb15647fc35c5a8cd38985d5958240eb072c1 (diff)
parent90a8a73c06cc32b609a880d48449d7083327e11a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/arm/mach-shmobile/board-ap4evb.c')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c147
1 files changed, 111 insertions, 36 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 9add606021f4..a054f0d450d8 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -572,38 +572,127 @@ static struct platform_device *qhd_devices[] __initdata = {
572 572
573/* FSI */ 573/* FSI */
574#define IRQ_FSI evt2irq(0x1840) 574#define IRQ_FSI evt2irq(0x1840)
575static int __fsi_set_rate(struct clk *clk, long rate, int enable)
576{
577 int ret = 0;
578
579 if (rate <= 0)
580 return ret;
581
582 if (enable) {
583 ret = clk_set_rate(clk, rate);
584 if (0 == ret)
585 ret = clk_enable(clk);
586 } else {
587 clk_disable(clk);
588 }
589
590 return ret;
591}
592
593static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
594{
595 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
596}
575 597
576static int fsi_set_rate(int is_porta, int rate) 598static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
599{
600 struct clk *fsia_ick;
601 struct clk *fsiack;
602 int ret = -EIO;
603
604 fsia_ick = clk_get(dev, "icka");
605 if (IS_ERR(fsia_ick))
606 return PTR_ERR(fsia_ick);
607
608 /*
609 * FSIACK is connected to AK4642,
610 * and use external clock pin from it.
611 * it is parent of fsia_ick now.
612 */
613 fsiack = clk_get_parent(fsia_ick);
614 if (!fsiack)
615 goto fsia_ick_out;
616
617 /*
618 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
619 *
620 ** FIXME **
621 * Because the freq_table of external clk (fsiack) are all 0,
622 * the return value of clk_round_rate became 0.
623 * So, it use __fsi_set_rate here.
624 */
625 ret = __fsi_set_rate(fsiack, rate, enable);
626 if (ret < 0)
627 goto fsiack_out;
628
629 ret = __fsi_set_round_rate(fsia_ick, rate, enable);
630 if ((ret < 0) && enable)
631 __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
632
633fsiack_out:
634 clk_put(fsiack);
635
636fsia_ick_out:
637 clk_put(fsia_ick);
638
639 return 0;
640}
641
642static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
577{ 643{
578 struct clk *fsib_clk; 644 struct clk *fsib_clk;
579 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 645 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
646 long fsib_rate = 0;
647 long fdiv_rate = 0;
648 int ackmd_bpfmd;
580 int ret; 649 int ret;
581 650
582 /* set_rate is not needed if port A */
583 if (is_porta)
584 return 0;
585
586 fsib_clk = clk_get(NULL, "fsib_clk");
587 if (IS_ERR(fsib_clk))
588 return -EINVAL;
589
590 switch (rate) { 651 switch (rate) {
591 case 44100: 652 case 44100:
592 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); 653 fsib_rate = rate * 256;
593 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 654 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
594 break; 655 break;
595 case 48000: 656 case 48000:
596 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); 657 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
597 clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); 658 fdiv_rate = rate * 256;
598 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 659 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
599 break; 660 break;
600 default: 661 default:
601 pr_err("unsupported rate in FSI2 port B\n"); 662 pr_err("unsupported rate in FSI2 port B\n");
602 ret = -EINVAL; 663 return -EINVAL;
603 break;
604 } 664 }
605 665
666 /* FSI B setting */
667 fsib_clk = clk_get(dev, "ickb");
668 if (IS_ERR(fsib_clk))
669 return -EIO;
670
671 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
606 clk_put(fsib_clk); 672 clk_put(fsib_clk);
673 if (ret < 0)
674 return ret;
675
676 /* FSI DIV setting */
677 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
678 if (ret < 0) {
679 /* disable FSI B */
680 if (enable)
681 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
682 return ret;
683 }
684
685 return ackmd_bpfmd;
686}
687
688static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
689{
690 int ret;
691
692 if (is_porta)
693 ret = fsi_ak4642_set_rate(dev, rate, enable);
694 else
695 ret = fsi_hdmi_set_rate(dev, rate, enable);
607 696
608 return ret; 697 return ret;
609} 698}
@@ -909,6 +998,11 @@ static int __init hdmi_init_pm_clock(void)
909 goto out; 998 goto out;
910 } 999 }
911 1000
1001 ret = clk_enable(&sh7372_pllc2_clk);
1002 if (ret < 0) {
1003 pr_err("Cannot enable pllc2 clock\n");
1004 goto out;
1005 }
912 pr_debug("PLLC2 set frequency %lu\n", rate); 1006 pr_debug("PLLC2 set frequency %lu\n", rate);
913 1007
914 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 1008 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -925,23 +1019,11 @@ out:
925 1019
926device_initcall(hdmi_init_pm_clock); 1020device_initcall(hdmi_init_pm_clock);
927 1021
928#define FSIACK_DUMMY_RATE 48000
929static int __init fsi_init_pm_clock(void) 1022static int __init fsi_init_pm_clock(void)
930{ 1023{
931 struct clk *fsia_ick; 1024 struct clk *fsia_ick;
932 int ret; 1025 int ret;
933 1026
934 /*
935 * FSIACK is connected to AK4642,
936 * and the rate is depend on playing sound rate.
937 * So, set dummy rate (= 48k) here
938 */
939 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
940 if (ret < 0) {
941 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
942 return ret;
943 }
944
945 fsia_ick = clk_get(&fsi_device.dev, "icka"); 1027 fsia_ick = clk_get(&fsi_device.dev, "icka");
946 if (IS_ERR(fsia_ick)) { 1028 if (IS_ERR(fsia_ick)) {
947 ret = PTR_ERR(fsia_ick); 1029 ret = PTR_ERR(fsia_ick);
@@ -950,16 +1032,9 @@ static int __init fsi_init_pm_clock(void)
950 } 1032 }
951 1033
952 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1034 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
953 if (ret < 0) {
954 pr_err("Cannot set FSI-A parent: %d\n", ret);
955 goto out;
956 }
957
958 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
959 if (ret < 0) 1035 if (ret < 0)
960 pr_err("Cannot set FSI-A rate: %d\n", ret); 1036 pr_err("Cannot set FSI-A parent: %d\n", ret);
961 1037
962out:
963 clk_put(fsia_ick); 1038 clk_put(fsia_ick);
964 1039
965 return ret; 1040 return ret;