aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-11-05 21:30:38 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-06 03:54:42 -0500
commitab6f6d85210c4d0265cf48e9958c04e08595055a (patch)
tree95a3371ac6700bc5b7d351b93a2190ec48e65416 /sound/soc/sh
parent80b4addc9c697c8d515afdaf671b948b3de6801c (diff)
ASoC: fsi: add master clock control functions
Current FSI driver required set_rate() platform callback function to set audio clock if it was master mode, because it seemed that CPG/FSI-DIV clocks calculation depend on platform/board/cpu. But it was calculable regardless of platform. This patch supports audio clock calculation method, but the sampling rate under 32kHz is not supported at this point. Old type set_rate() is still supported now, but it will be deleted on next version Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi.c378
1 files changed, 372 insertions, 6 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ef257bcb5341..bdaca356aaad 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h>
24#include <sound/sh_fsi.h> 25#include <sound/sh_fsi.h>
25 26
26/* PortA/PortB register */ 27/* PortA/PortB register */
@@ -188,6 +189,14 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
188 */ 189 */
189 190
190/* 191/*
192 * FSI clock
193 *
194 * FSIxCLK [CPG] (ick) -------> |
195 * |-> FSI_DIV (div)-> FSI2
196 * FSIxCK [external] (xck) ---> |
197 */
198
199/*
191 * struct 200 * struct
192 */ 201 */
193 202
@@ -227,6 +236,20 @@ struct fsi_stream {
227 dma_addr_t dma; 236 dma_addr_t dma;
228}; 237};
229 238
239struct fsi_clk {
240 /* see [FSI clock] */
241 struct clk *own;
242 struct clk *xck;
243 struct clk *ick;
244 struct clk *div;
245 int (*set_rate)(struct device *dev,
246 struct fsi_priv *fsi,
247 unsigned long rate);
248
249 unsigned long rate;
250 unsigned int count;
251};
252
230struct fsi_priv { 253struct fsi_priv {
231 void __iomem *base; 254 void __iomem *base;
232 struct fsi_master *master; 255 struct fsi_master *master;
@@ -235,6 +258,8 @@ struct fsi_priv {
235 struct fsi_stream playback; 258 struct fsi_stream playback;
236 struct fsi_stream capture; 259 struct fsi_stream capture;
237 260
261 struct fsi_clk clock;
262
238 u32 fmt; 263 u32 fmt;
239 264
240 int chan_num:16; 265 int chan_num:16;
@@ -716,14 +741,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
716/* 741/*
717 * clock function 742 * clock function
718 */ 743 */
744static int fsi_clk_init(struct device *dev,
745 struct fsi_priv *fsi,
746 int xck,
747 int ick,
748 int div,
749 int (*set_rate)(struct device *dev,
750 struct fsi_priv *fsi,
751 unsigned long rate))
752{
753 struct fsi_clk *clock = &fsi->clock;
754 int is_porta = fsi_is_port_a(fsi);
755
756 clock->xck = NULL;
757 clock->ick = NULL;
758 clock->div = NULL;
759 clock->rate = 0;
760 clock->count = 0;
761 clock->set_rate = set_rate;
762
763 clock->own = devm_clk_get(dev, NULL);
764 if (IS_ERR(clock->own))
765 return -EINVAL;
766
767 /* external clock */
768 if (xck) {
769 clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
770 if (IS_ERR(clock->xck)) {
771 dev_err(dev, "can't get xck clock\n");
772 return -EINVAL;
773 }
774 if (clock->xck == clock->own) {
775 dev_err(dev, "cpu doesn't support xck clock\n");
776 return -EINVAL;
777 }
778 }
779
780 /* FSIACLK/FSIBCLK */
781 if (ick) {
782 clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb");
783 if (IS_ERR(clock->ick)) {
784 dev_err(dev, "can't get ick clock\n");
785 return -EINVAL;
786 }
787 if (clock->ick == clock->own) {
788 dev_err(dev, "cpu doesn't support ick clock\n");
789 return -EINVAL;
790 }
791 }
792
793 /* FSI-DIV */
794 if (div) {
795 clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb");
796 if (IS_ERR(clock->div)) {
797 dev_err(dev, "can't get div clock\n");
798 return -EINVAL;
799 }
800 if (clock->div == clock->own) {
801 dev_err(dev, "cpu doens't support div clock\n");
802 return -EINVAL;
803 }
804 }
805
806 return 0;
807}
808
809#define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0)
810static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate)
811{
812 fsi->clock.rate = rate;
813}
814
815static int fsi_clk_is_valid(struct fsi_priv *fsi)
816{
817 return fsi->clock.set_rate &&
818 fsi->clock.rate;
819}
820
821static int fsi_clk_enable(struct device *dev,
822 struct fsi_priv *fsi,
823 unsigned long rate)
824{
825 struct fsi_clk *clock = &fsi->clock;
826 int ret = -EINVAL;
827
828 if (!fsi_clk_is_valid(fsi))
829 return ret;
830
831 if (0 == clock->count) {
832 ret = clock->set_rate(dev, fsi, rate);
833 if (ret < 0) {
834 fsi_clk_invalid(fsi);
835 return ret;
836 }
837
838 if (clock->xck)
839 clk_enable(clock->xck);
840 if (clock->ick)
841 clk_enable(clock->ick);
842 if (clock->div)
843 clk_enable(clock->div);
844
845 clock->count++;
846 }
847
848 return ret;
849}
850
851static int fsi_clk_disable(struct device *dev,
852 struct fsi_priv *fsi)
853{
854 struct fsi_clk *clock = &fsi->clock;
855
856 if (!fsi_clk_is_valid(fsi))
857 return -EINVAL;
858
859 if (1 == clock->count--) {
860 if (clock->xck)
861 clk_disable(clock->xck);
862 if (clock->ick)
863 clk_disable(clock->ick);
864 if (clock->div)
865 clk_disable(clock->div);
866 }
867
868 return 0;
869}
870
871static int fsi_clk_set_ackbpf(struct device *dev,
872 struct fsi_priv *fsi,
873 int ackmd, int bpfmd)
874{
875 u32 data = 0;
876
877 /* check ackmd/bpfmd relationship */
878 if (bpfmd > ackmd) {
879 dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd);
880 return -EINVAL;
881 }
882
883 /* ACKMD */
884 switch (ackmd) {
885 case 512:
886 data |= (0x0 << 12);
887 break;
888 case 256:
889 data |= (0x1 << 12);
890 break;
891 case 128:
892 data |= (0x2 << 12);
893 break;
894 case 64:
895 data |= (0x3 << 12);
896 break;
897 case 32:
898 data |= (0x4 << 12);
899 break;
900 default:
901 dev_err(dev, "unsupported ackmd (%d)\n", ackmd);
902 return -EINVAL;
903 }
904
905 /* BPFMD */
906 switch (bpfmd) {
907 case 32:
908 data |= (0x0 << 8);
909 break;
910 case 64:
911 data |= (0x1 << 8);
912 break;
913 case 128:
914 data |= (0x2 << 8);
915 break;
916 case 256:
917 data |= (0x3 << 8);
918 break;
919 case 512:
920 data |= (0x4 << 8);
921 break;
922 case 16:
923 data |= (0x7 << 8);
924 break;
925 default:
926 dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd);
927 return -EINVAL;
928 }
929
930 dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd);
931
932 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
933 udelay(10);
934
935 return 0;
936}
937
938static int fsi_clk_set_rate_external(struct device *dev,
939 struct fsi_priv *fsi,
940 unsigned long rate)
941{
942 struct clk *xck = fsi->clock.xck;
943 struct clk *ick = fsi->clock.ick;
944 unsigned long xrate;
945 int ackmd, bpfmd;
946 int ret = 0;
947
948 /* check clock rate */
949 xrate = clk_get_rate(xck);
950 if (xrate % rate) {
951 dev_err(dev, "unsupported clock rate\n");
952 return -EINVAL;
953 }
954
955 clk_set_parent(ick, xck);
956 clk_set_rate(ick, xrate);
957
958 bpfmd = fsi->chan_num * 32;
959 ackmd = xrate / rate;
960
961 dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate);
962
963 ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd);
964 if (ret < 0)
965 dev_err(dev, "%s failed", __func__);
966
967 return ret;
968}
969
970static int fsi_clk_set_rate_cpg(struct device *dev,
971 struct fsi_priv *fsi,
972 unsigned long rate)
973{
974 struct clk *ick = fsi->clock.ick;
975 struct clk *div = fsi->clock.div;
976 unsigned long target = 0; /* 12288000 or 11289600 */
977 unsigned long actual, cout;
978 unsigned long diff, min;
979 unsigned long best_cout, best_act;
980 int adj;
981 int ackmd, bpfmd;
982 int ret = -EINVAL;
983
984 if (!(12288000 % rate))
985 target = 12288000;
986 if (!(11289600 % rate))
987 target = 11289600;
988 if (!target) {
989 dev_err(dev, "unsupported rate\n");
990 return ret;
991 }
992
993 bpfmd = fsi->chan_num * 32;
994 ackmd = target / rate;
995 ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd);
996 if (ret < 0) {
997 dev_err(dev, "%s failed", __func__);
998 return ret;
999 }
1000
1001 /*
1002 * The clock flow is
1003 *
1004 * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec]
1005 *
1006 * But, it needs to find best match of CPG and FSI_DIV
1007 * combination, since it is difficult to generate correct
1008 * frequency of audio clock from ick clock only.
1009 * Because ick is created from its parent clock.
1010 *
1011 * target = rate x [512/256/128/64]fs
1012 * cout = round(target x adjustment)
1013 * actual = cout / adjustment (by FSI-DIV) ~= target
1014 * audio = actual
1015 */
1016 min = ~0;
1017 best_cout = 0;
1018 best_act = 0;
1019 for (adj = 1; adj < 0xffff; adj++) {
1020
1021 cout = target * adj;
1022 if (cout > 100000000) /* max clock = 100MHz */
1023 break;
1024
1025 /* cout/actual audio clock */
1026 cout = clk_round_rate(ick, cout);
1027 actual = cout / adj;
1028
1029 /* find best frequency */
1030 diff = abs(actual - target);
1031 if (diff < min) {
1032 min = diff;
1033 best_cout = cout;
1034 best_act = actual;
1035 }
1036 }
1037
1038 ret = clk_set_rate(ick, best_cout);
1039 if (ret < 0) {
1040 dev_err(dev, "ick clock failed\n");
1041 return -EIO;
1042 }
1043
1044 ret = clk_set_rate(div, clk_round_rate(div, best_act));
1045 if (ret < 0) {
1046 dev_err(dev, "div clock failed\n");
1047 return -EIO;
1048 }
1049
1050 dev_dbg(dev, "ick/div = %ld/%ld\n",
1051 clk_get_rate(ick), clk_get_rate(div));
1052
1053 return ret;
1054}
1055
719static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, 1056static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
720 long rate, int enable) 1057 long rate, int enable)
721{ 1058{
722 set_rate_func set_rate = fsi_get_info_set_rate(fsi); 1059 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
723 int ret; 1060 int ret;
724 1061
725 if (!set_rate) 1062 /*
726 return 0; 1063 * CAUTION
1064 *
1065 * set_rate will be deleted
1066 */
1067 if (!set_rate) {
1068 if (enable)
1069 return fsi_clk_enable(dev, fsi, rate);
1070 else
1071 return fsi_clk_disable(dev, fsi);
1072 }
727 1073
728 ret = set_rate(dev, rate, enable); 1074 ret = set_rate(dev, rate, enable);
729 if (ret < 0) /* error */ 1075 if (ret < 0) /* error */
@@ -1355,6 +1701,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
1355{ 1701{
1356 struct fsi_priv *fsi = fsi_get_priv(substream); 1702 struct fsi_priv *fsi = fsi_get_priv(substream);
1357 1703
1704 fsi_clk_invalid(fsi);
1358 fsi->rate = 0; 1705 fsi->rate = 0;
1359 1706
1360 return 0; 1707 return 0;
@@ -1365,6 +1712,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
1365{ 1712{
1366 struct fsi_priv *fsi = fsi_get_priv(substream); 1713 struct fsi_priv *fsi = fsi_get_priv(substream);
1367 1714
1715 fsi_clk_invalid(fsi);
1368 fsi->rate = 0; 1716 fsi->rate = 0;
1369} 1717}
1370 1718
@@ -1446,9 +1794,25 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1446 return -EINVAL; 1794 return -EINVAL;
1447 } 1795 }
1448 1796
1449 if (fsi_is_clk_master(fsi) && !set_rate) { 1797 if (fsi_is_clk_master(fsi)) {
1450 dev_err(dai->dev, "platform doesn't have set_rate\n"); 1798 /*
1451 return -EINVAL; 1799 * CAUTION
1800 *
1801 * set_rate will be deleted
1802 */
1803 if (set_rate)
1804 dev_warn(dai->dev, "set_rate will be removed soon\n");
1805
1806 switch (flags & SH_FSI_CLK_MASK) {
1807 case SH_FSI_CLK_EXTERNAL:
1808 fsi_clk_init(dai->dev, fsi, 1, 1, 0,
1809 fsi_clk_set_rate_external);
1810 break;
1811 case SH_FSI_CLK_CPG:
1812 fsi_clk_init(dai->dev, fsi, 0, 1, 1,
1813 fsi_clk_set_rate_cpg);
1814 break;
1815 }
1452 } 1816 }
1453 1817
1454 /* set format */ 1818 /* set format */
@@ -1472,8 +1836,10 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
1472{ 1836{
1473 struct fsi_priv *fsi = fsi_get_priv(substream); 1837 struct fsi_priv *fsi = fsi_get_priv(substream);
1474 1838
1475 if (fsi_is_clk_master(fsi)) 1839 if (fsi_is_clk_master(fsi)) {
1476 fsi->rate = params_rate(params); 1840 fsi->rate = params_rate(params);
1841 fsi_clk_valid(fsi, fsi->rate);
1842 }
1477 1843
1478 return 0; 1844 return 0;
1479} 1845}