diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2010-11-19 02:23:17 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-11-24 01:31:00 -0500 |
commit | 22de4e1fe446794acaebdf19dcaff4256d659972 (patch) | |
tree | daafc6b0c41ef1c0ad6f4cab642994523096e743 | |
parent | d4bc99b977e3a1dd10a84a01ebe59ac2ccebf0cd (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.c | 96 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 8 |
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 | ||
588 | static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) | 588 | static 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 | |||
593 | static 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 | |||
628 | fsiack_out: | ||
629 | clk_put(fsiack); | ||
630 | |||
631 | fsia_ick_out: | ||
632 | clk_put(fsia_ick); | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static 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 | ||
683 | static 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 | |||
638 | static struct sh_fsi_platform_info fsi_info = { | 695 | static 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 | ||
929 | device_initcall(hdmi_init_pm_clock); | 986 | device_initcall(hdmi_init_pm_clock); |
930 | 987 | ||
931 | #define FSIACK_DUMMY_RATE 48000 | ||
932 | static int __init fsi_init_pm_clock(void) | 988 | static 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 | ||
965 | out: | ||
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 */ |