aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-12-13 03:28:43 -0500
committerTakashi Iwai <tiwai@suse.de>2010-12-13 03:28:43 -0500
commit20aeeb356ba2e8daa99b5942c528ae2b3ea28433 (patch)
treed2cebc7039954851998d592123899f5627def7a9 /arch/arm/mach-shmobile/board-ap4evb.c
parent07a9e2b2fbdda631eeff54e4b8ebcaaea71be538 (diff)
parent5b84ba26a9672e615897234fa5efd3eea2d6b295 (diff)
Merge branch 'topic/workq-update' into topic/asoc
Conflicts: sound/soc/codecs/wm8350.c sound/soc/codecs/wm8753.c sound/soc/sh/fsi.c sound/soc/soc-core.c
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 82c3204af899..e6bf1e114b10 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -567,38 +567,127 @@ 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;
576
577 if (enable) {
578 ret = clk_set_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_round_rate(struct clk *clk, long rate, int enable)
589{
590 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
591}
570 592
571static int fsi_set_rate(int is_porta, int rate) 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)
572{ 638{
573 struct clk *fsib_clk; 639 struct clk *fsib_clk;
574 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 640 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
641 long fsib_rate = 0;
642 long fdiv_rate = 0;
643 int ackmd_bpfmd;
575 int ret; 644 int ret;
576 645
577 /* set_rate is not needed if port A */
578 if (is_porta)
579 return 0;
580
581 fsib_clk = clk_get(NULL, "fsib_clk");
582 if (IS_ERR(fsib_clk))
583 return -EINVAL;
584
585 switch (rate) { 646 switch (rate) {
586 case 44100: 647 case 44100:
587 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); 648 fsib_rate = rate * 256;
588 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 649 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
589 break; 650 break;
590 case 48000: 651 case 48000:
591 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); 652 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
592 clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); 653 fdiv_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 default: 656 default:
596 pr_err("unsupported rate in FSI2 port B\n"); 657 pr_err("unsupported rate in FSI2 port B\n");
597 ret = -EINVAL; 658 return -EINVAL;
598 break;
599 } 659 }
600 660
661 /* FSI B setting */
662 fsib_clk = clk_get(dev, "ickb");
663 if (IS_ERR(fsib_clk))
664 return -EIO;
665
666 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
601 clk_put(fsib_clk); 667 clk_put(fsib_clk);
668 if (ret < 0)
669 return ret;
670
671 /* FSI DIV setting */
672 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
673 if (ret < 0) {
674 /* disable FSI B */
675 if (enable)
676 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
677 return ret;
678 }
679
680 return ackmd_bpfmd;
681}
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);
602 691
603 return ret; 692 return ret;
604} 693}
@@ -885,6 +974,11 @@ static int __init hdmi_init_pm_clock(void)
885 goto out; 974 goto out;
886 } 975 }
887 976
977 ret = clk_enable(&sh7372_pllc2_clk);
978 if (ret < 0) {
979 pr_err("Cannot enable pllc2 clock\n");
980 goto out;
981 }
888 pr_debug("PLLC2 set frequency %lu\n", rate); 982 pr_debug("PLLC2 set frequency %lu\n", rate);
889 983
890 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 984 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -901,23 +995,11 @@ out:
901 995
902device_initcall(hdmi_init_pm_clock); 996device_initcall(hdmi_init_pm_clock);
903 997
904#define FSIACK_DUMMY_RATE 48000
905static int __init fsi_init_pm_clock(void) 998static int __init fsi_init_pm_clock(void)
906{ 999{
907 struct clk *fsia_ick; 1000 struct clk *fsia_ick;
908 int ret; 1001 int ret;
909 1002
910 /*
911 * FSIACK is connected to AK4642,
912 * and the rate is depend on playing sound rate.
913 * So, set dummy rate (= 48k) here
914 */
915 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
916 if (ret < 0) {
917 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
918 return ret;
919 }
920
921 fsia_ick = clk_get(&fsi_device.dev, "icka"); 1003 fsia_ick = clk_get(&fsi_device.dev, "icka");
922 if (IS_ERR(fsia_ick)) { 1004 if (IS_ERR(fsia_ick)) {
923 ret = PTR_ERR(fsia_ick); 1005 ret = PTR_ERR(fsia_ick);
@@ -926,16 +1008,9 @@ static int __init fsi_init_pm_clock(void)
926 } 1008 }
927 1009
928 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1010 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
929 if (ret < 0) {
930 pr_err("Cannot set FSI-A parent: %d\n", ret);
931 goto out;
932 }
933
934 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
935 if (ret < 0) 1011 if (ret < 0)
936 pr_err("Cannot set FSI-A rate: %d\n", ret); 1012 pr_err("Cannot set FSI-A parent: %d\n", ret);
937 1013
938out:
939 clk_put(fsia_ick); 1014 clk_put(fsia_ick);
940 1015
941 return ret; 1016 return ret;