diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-09 10:22:08 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-09 10:22:08 -0500 |
commit | 954f497f7167de273b6e062de84689ccd8bf999d (patch) | |
tree | 73dd01cf9526c79956d58a30a7da3441e457fe23 | |
parent | 1870975f5db15fc30c8c025665fbc86ecb1fffd9 (diff) | |
parent | 3449f5fab8c51e37a8a48bc2516588c615373191 (diff) |
Merge remote-tracking branch 'asoc/topic/fsi' into asoc-next
-rw-r--r-- | include/sound/sh_fsi.h | 6 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 550 |
2 files changed, 487 insertions, 69 deletions
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 906010344dd7..cc1c919c6436 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * A: inversion | 26 | * A: inversion |
27 | * B: format mode | 27 | * B: format mode |
28 | * C: chip specific | 28 | * C: chip specific |
29 | * D: clock selecter if master mode | ||
29 | */ | 30 | */ |
30 | 31 | ||
31 | /* A: clock inversion */ | 32 | /* A: clock inversion */ |
@@ -44,6 +45,11 @@ | |||
44 | #define SH_FSI_OPTION_MASK 0x00000F00 | 45 | #define SH_FSI_OPTION_MASK 0x00000F00 |
45 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ | 46 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ |
46 | 47 | ||
48 | /* D: clock selecter if master mode */ | ||
49 | #define SH_FSI_CLK_MASK 0x0000F000 | ||
50 | #define SH_FSI_CLK_EXTERNAL (0 << 12) | ||
51 | #define SH_FSI_CLK_CPG (1 << 12) /* FSIxCK + FSI-DIV */ | ||
52 | |||
47 | /* | 53 | /* |
48 | * set_rate return value | 54 | * set_rate return value |
49 | * | 55 | * |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9d7f30774a44..a606d0f93d1c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/pcm_params.h> | ||
25 | #include <sound/sh_fsi.h> | 26 | #include <sound/sh_fsi.h> |
26 | 27 | ||
27 | /* PortA/PortB register */ | 28 | /* PortA/PortB register */ |
@@ -189,6 +190,14 @@ typedef int (*set_rate_func)(struct device *dev, int rate, int enable); | |||
189 | */ | 190 | */ |
190 | 191 | ||
191 | /* | 192 | /* |
193 | * FSI clock | ||
194 | * | ||
195 | * FSIxCLK [CPG] (ick) -------> | | ||
196 | * |-> FSI_DIV (div)-> FSI2 | ||
197 | * FSIxCK [external] (xck) ---> | | ||
198 | */ | ||
199 | |||
200 | /* | ||
192 | * struct | 201 | * struct |
193 | */ | 202 | */ |
194 | 203 | ||
@@ -228,6 +237,20 @@ struct fsi_stream { | |||
228 | dma_addr_t dma; | 237 | dma_addr_t dma; |
229 | }; | 238 | }; |
230 | 239 | ||
240 | struct fsi_clk { | ||
241 | /* see [FSI clock] */ | ||
242 | struct clk *own; | ||
243 | struct clk *xck; | ||
244 | struct clk *ick; | ||
245 | struct clk *div; | ||
246 | int (*set_rate)(struct device *dev, | ||
247 | struct fsi_priv *fsi, | ||
248 | unsigned long rate); | ||
249 | |||
250 | unsigned long rate; | ||
251 | unsigned int count; | ||
252 | }; | ||
253 | |||
231 | struct fsi_priv { | 254 | struct fsi_priv { |
232 | void __iomem *base; | 255 | void __iomem *base; |
233 | struct fsi_master *master; | 256 | struct fsi_master *master; |
@@ -236,11 +259,17 @@ struct fsi_priv { | |||
236 | struct fsi_stream playback; | 259 | struct fsi_stream playback; |
237 | struct fsi_stream capture; | 260 | struct fsi_stream capture; |
238 | 261 | ||
262 | struct fsi_clk clock; | ||
263 | |||
239 | u32 fmt; | 264 | u32 fmt; |
240 | 265 | ||
241 | int chan_num:16; | 266 | int chan_num:16; |
242 | int clk_master:1; | 267 | int clk_master:1; |
268 | int clk_cpg:1; | ||
243 | int spdif:1; | 269 | int spdif:1; |
270 | int enable_stream:1; | ||
271 | int bit_clk_inv:1; | ||
272 | int lr_clk_inv:1; | ||
244 | 273 | ||
245 | long rate; | 274 | long rate; |
246 | }; | 275 | }; |
@@ -370,6 +399,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) | |||
370 | return fsi->spdif; | 399 | return fsi->spdif; |
371 | } | 400 | } |
372 | 401 | ||
402 | static int fsi_is_enable_stream(struct fsi_priv *fsi) | ||
403 | { | ||
404 | return fsi->enable_stream; | ||
405 | } | ||
406 | |||
373 | static int fsi_is_play(struct snd_pcm_substream *substream) | 407 | static int fsi_is_play(struct snd_pcm_substream *substream) |
374 | { | 408 | { |
375 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 409 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
@@ -717,14 +751,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
717 | /* | 751 | /* |
718 | * clock function | 752 | * clock function |
719 | */ | 753 | */ |
754 | static int fsi_clk_init(struct device *dev, | ||
755 | struct fsi_priv *fsi, | ||
756 | int xck, | ||
757 | int ick, | ||
758 | int div, | ||
759 | int (*set_rate)(struct device *dev, | ||
760 | struct fsi_priv *fsi, | ||
761 | unsigned long rate)) | ||
762 | { | ||
763 | struct fsi_clk *clock = &fsi->clock; | ||
764 | int is_porta = fsi_is_port_a(fsi); | ||
765 | |||
766 | clock->xck = NULL; | ||
767 | clock->ick = NULL; | ||
768 | clock->div = NULL; | ||
769 | clock->rate = 0; | ||
770 | clock->count = 0; | ||
771 | clock->set_rate = set_rate; | ||
772 | |||
773 | clock->own = devm_clk_get(dev, NULL); | ||
774 | if (IS_ERR(clock->own)) | ||
775 | return -EINVAL; | ||
776 | |||
777 | /* external clock */ | ||
778 | if (xck) { | ||
779 | clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb"); | ||
780 | if (IS_ERR(clock->xck)) { | ||
781 | dev_err(dev, "can't get xck clock\n"); | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | if (clock->xck == clock->own) { | ||
785 | dev_err(dev, "cpu doesn't support xck clock\n"); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | } | ||
789 | |||
790 | /* FSIACLK/FSIBCLK */ | ||
791 | if (ick) { | ||
792 | clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb"); | ||
793 | if (IS_ERR(clock->ick)) { | ||
794 | dev_err(dev, "can't get ick clock\n"); | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | if (clock->ick == clock->own) { | ||
798 | dev_err(dev, "cpu doesn't support ick clock\n"); | ||
799 | return -EINVAL; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | /* FSI-DIV */ | ||
804 | if (div) { | ||
805 | clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb"); | ||
806 | if (IS_ERR(clock->div)) { | ||
807 | dev_err(dev, "can't get div clock\n"); | ||
808 | return -EINVAL; | ||
809 | } | ||
810 | if (clock->div == clock->own) { | ||
811 | dev_err(dev, "cpu doens't support div clock\n"); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | #define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0) | ||
820 | static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate) | ||
821 | { | ||
822 | fsi->clock.rate = rate; | ||
823 | } | ||
824 | |||
825 | static int fsi_clk_is_valid(struct fsi_priv *fsi) | ||
826 | { | ||
827 | return fsi->clock.set_rate && | ||
828 | fsi->clock.rate; | ||
829 | } | ||
830 | |||
831 | static int fsi_clk_enable(struct device *dev, | ||
832 | struct fsi_priv *fsi, | ||
833 | unsigned long rate) | ||
834 | { | ||
835 | struct fsi_clk *clock = &fsi->clock; | ||
836 | int ret = -EINVAL; | ||
837 | |||
838 | if (!fsi_clk_is_valid(fsi)) | ||
839 | return ret; | ||
840 | |||
841 | if (0 == clock->count) { | ||
842 | ret = clock->set_rate(dev, fsi, rate); | ||
843 | if (ret < 0) { | ||
844 | fsi_clk_invalid(fsi); | ||
845 | return ret; | ||
846 | } | ||
847 | |||
848 | if (clock->xck) | ||
849 | clk_enable(clock->xck); | ||
850 | if (clock->ick) | ||
851 | clk_enable(clock->ick); | ||
852 | if (clock->div) | ||
853 | clk_enable(clock->div); | ||
854 | |||
855 | clock->count++; | ||
856 | } | ||
857 | |||
858 | return ret; | ||
859 | } | ||
860 | |||
861 | static int fsi_clk_disable(struct device *dev, | ||
862 | struct fsi_priv *fsi) | ||
863 | { | ||
864 | struct fsi_clk *clock = &fsi->clock; | ||
865 | |||
866 | if (!fsi_clk_is_valid(fsi)) | ||
867 | return -EINVAL; | ||
868 | |||
869 | if (1 == clock->count--) { | ||
870 | if (clock->xck) | ||
871 | clk_disable(clock->xck); | ||
872 | if (clock->ick) | ||
873 | clk_disable(clock->ick); | ||
874 | if (clock->div) | ||
875 | clk_disable(clock->div); | ||
876 | } | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static int fsi_clk_set_ackbpf(struct device *dev, | ||
882 | struct fsi_priv *fsi, | ||
883 | int ackmd, int bpfmd) | ||
884 | { | ||
885 | u32 data = 0; | ||
886 | |||
887 | /* check ackmd/bpfmd relationship */ | ||
888 | if (bpfmd > ackmd) { | ||
889 | dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd); | ||
890 | return -EINVAL; | ||
891 | } | ||
892 | |||
893 | /* ACKMD */ | ||
894 | switch (ackmd) { | ||
895 | case 512: | ||
896 | data |= (0x0 << 12); | ||
897 | break; | ||
898 | case 256: | ||
899 | data |= (0x1 << 12); | ||
900 | break; | ||
901 | case 128: | ||
902 | data |= (0x2 << 12); | ||
903 | break; | ||
904 | case 64: | ||
905 | data |= (0x3 << 12); | ||
906 | break; | ||
907 | case 32: | ||
908 | data |= (0x4 << 12); | ||
909 | break; | ||
910 | default: | ||
911 | dev_err(dev, "unsupported ackmd (%d)\n", ackmd); | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
915 | /* BPFMD */ | ||
916 | switch (bpfmd) { | ||
917 | case 32: | ||
918 | data |= (0x0 << 8); | ||
919 | break; | ||
920 | case 64: | ||
921 | data |= (0x1 << 8); | ||
922 | break; | ||
923 | case 128: | ||
924 | data |= (0x2 << 8); | ||
925 | break; | ||
926 | case 256: | ||
927 | data |= (0x3 << 8); | ||
928 | break; | ||
929 | case 512: | ||
930 | data |= (0x4 << 8); | ||
931 | break; | ||
932 | case 16: | ||
933 | data |= (0x7 << 8); | ||
934 | break; | ||
935 | default: | ||
936 | dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | |||
940 | dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd); | ||
941 | |||
942 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
943 | udelay(10); | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
948 | static int fsi_clk_set_rate_external(struct device *dev, | ||
949 | struct fsi_priv *fsi, | ||
950 | unsigned long rate) | ||
951 | { | ||
952 | struct clk *xck = fsi->clock.xck; | ||
953 | struct clk *ick = fsi->clock.ick; | ||
954 | unsigned long xrate; | ||
955 | int ackmd, bpfmd; | ||
956 | int ret = 0; | ||
957 | |||
958 | /* check clock rate */ | ||
959 | xrate = clk_get_rate(xck); | ||
960 | if (xrate % rate) { | ||
961 | dev_err(dev, "unsupported clock rate\n"); | ||
962 | return -EINVAL; | ||
963 | } | ||
964 | |||
965 | clk_set_parent(ick, xck); | ||
966 | clk_set_rate(ick, xrate); | ||
967 | |||
968 | bpfmd = fsi->chan_num * 32; | ||
969 | ackmd = xrate / rate; | ||
970 | |||
971 | dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate); | ||
972 | |||
973 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
974 | if (ret < 0) | ||
975 | dev_err(dev, "%s failed", __func__); | ||
976 | |||
977 | return ret; | ||
978 | } | ||
979 | |||
980 | static int fsi_clk_set_rate_cpg(struct device *dev, | ||
981 | struct fsi_priv *fsi, | ||
982 | unsigned long rate) | ||
983 | { | ||
984 | struct clk *ick = fsi->clock.ick; | ||
985 | struct clk *div = fsi->clock.div; | ||
986 | unsigned long target = 0; /* 12288000 or 11289600 */ | ||
987 | unsigned long actual, cout; | ||
988 | unsigned long diff, min; | ||
989 | unsigned long best_cout, best_act; | ||
990 | int adj; | ||
991 | int ackmd, bpfmd; | ||
992 | int ret = -EINVAL; | ||
993 | |||
994 | if (!(12288000 % rate)) | ||
995 | target = 12288000; | ||
996 | if (!(11289600 % rate)) | ||
997 | target = 11289600; | ||
998 | if (!target) { | ||
999 | dev_err(dev, "unsupported rate\n"); | ||
1000 | return ret; | ||
1001 | } | ||
1002 | |||
1003 | bpfmd = fsi->chan_num * 32; | ||
1004 | ackmd = target / rate; | ||
1005 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
1006 | if (ret < 0) { | ||
1007 | dev_err(dev, "%s failed", __func__); | ||
1008 | return ret; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * The clock flow is | ||
1013 | * | ||
1014 | * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec] | ||
1015 | * | ||
1016 | * But, it needs to find best match of CPG and FSI_DIV | ||
1017 | * combination, since it is difficult to generate correct | ||
1018 | * frequency of audio clock from ick clock only. | ||
1019 | * Because ick is created from its parent clock. | ||
1020 | * | ||
1021 | * target = rate x [512/256/128/64]fs | ||
1022 | * cout = round(target x adjustment) | ||
1023 | * actual = cout / adjustment (by FSI-DIV) ~= target | ||
1024 | * audio = actual | ||
1025 | */ | ||
1026 | min = ~0; | ||
1027 | best_cout = 0; | ||
1028 | best_act = 0; | ||
1029 | for (adj = 1; adj < 0xffff; adj++) { | ||
1030 | |||
1031 | cout = target * adj; | ||
1032 | if (cout > 100000000) /* max clock = 100MHz */ | ||
1033 | break; | ||
1034 | |||
1035 | /* cout/actual audio clock */ | ||
1036 | cout = clk_round_rate(ick, cout); | ||
1037 | actual = cout / adj; | ||
1038 | |||
1039 | /* find best frequency */ | ||
1040 | diff = abs(actual - target); | ||
1041 | if (diff < min) { | ||
1042 | min = diff; | ||
1043 | best_cout = cout; | ||
1044 | best_act = actual; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | ret = clk_set_rate(ick, best_cout); | ||
1049 | if (ret < 0) { | ||
1050 | dev_err(dev, "ick clock failed\n"); | ||
1051 | return -EIO; | ||
1052 | } | ||
1053 | |||
1054 | ret = clk_set_rate(div, clk_round_rate(div, best_act)); | ||
1055 | if (ret < 0) { | ||
1056 | dev_err(dev, "div clock failed\n"); | ||
1057 | return -EIO; | ||
1058 | } | ||
1059 | |||
1060 | dev_dbg(dev, "ick/div = %ld/%ld\n", | ||
1061 | clk_get_rate(ick), clk_get_rate(div)); | ||
1062 | |||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
720 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | 1066 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, |
721 | long rate, int enable) | 1067 | long rate, int enable) |
722 | { | 1068 | { |
723 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1069 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
724 | int ret; | 1070 | int ret; |
725 | 1071 | ||
726 | if (!set_rate) | 1072 | /* |
727 | return 0; | 1073 | * CAUTION |
1074 | * | ||
1075 | * set_rate will be deleted | ||
1076 | */ | ||
1077 | if (!set_rate) { | ||
1078 | if (enable) | ||
1079 | return fsi_clk_enable(dev, fsi, rate); | ||
1080 | else | ||
1081 | return fsi_clk_disable(dev, fsi); | ||
1082 | } | ||
728 | 1083 | ||
729 | ret = set_rate(dev, rate, enable); | 1084 | ret = set_rate(dev, rate, enable); |
730 | if (ret < 0) /* error */ | 1085 | if (ret < 0) /* error */ |
@@ -792,10 +1147,9 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
792 | */ | 1147 | */ |
793 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) | 1148 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) |
794 | { | 1149 | { |
795 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
796 | int i; | 1150 | int i; |
797 | 1151 | ||
798 | if (enable_stream) { | 1152 | if (fsi_is_enable_stream(fsi)) { |
799 | /* | 1153 | /* |
800 | * stream mode | 1154 | * stream mode |
801 | * see | 1155 | * see |
@@ -953,8 +1307,6 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | |||
953 | 1307 | ||
954 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | 1308 | static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) |
955 | { | 1309 | { |
956 | u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; | ||
957 | |||
958 | /* | 1310 | /* |
959 | * we can use 16bit stream mode | 1311 | * we can use 16bit stream mode |
960 | * when "playback" and "16bit data" | 1312 | * when "playback" and "16bit data" |
@@ -962,7 +1314,7 @@ static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) | |||
962 | * see | 1314 | * see |
963 | * fsi_pio_push16() | 1315 | * fsi_pio_push16() |
964 | */ | 1316 | */ |
965 | if (enable_stream) | 1317 | if (fsi_is_enable_stream(fsi)) |
966 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | | 1318 | io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | |
967 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); | 1319 | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); |
968 | else | 1320 | else |
@@ -1296,6 +1648,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1296 | 1648 | ||
1297 | /* clock inversion (CKG2) */ | 1649 | /* clock inversion (CKG2) */ |
1298 | data = 0; | 1650 | data = 0; |
1651 | if (fsi->bit_clk_inv) | ||
1652 | data |= (1 << 0); | ||
1653 | if (fsi->lr_clk_inv) | ||
1654 | data |= (1 << 4); | ||
1655 | if (fsi_is_clk_master(fsi)) | ||
1656 | data <<= 8; | ||
1657 | /* FIXME | ||
1658 | * | ||
1659 | * SH_FSI_xxx_INV style will be removed | ||
1660 | */ | ||
1299 | if (SH_FSI_LRM_INV & flags) | 1661 | if (SH_FSI_LRM_INV & flags) |
1300 | data |= 1 << 12; | 1662 | data |= 1 << 12; |
1301 | if (SH_FSI_BRM_INV & flags) | 1663 | if (SH_FSI_BRM_INV & flags) |
@@ -1334,14 +1696,21 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1334 | /* fifo init */ | 1696 | /* fifo init */ |
1335 | fsi_fifo_init(fsi, io, dev); | 1697 | fsi_fifo_init(fsi, io, dev); |
1336 | 1698 | ||
1699 | /* start master clock */ | ||
1700 | if (fsi_is_clk_master(fsi)) | ||
1701 | return fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1702 | |||
1337 | return 0; | 1703 | return 0; |
1338 | } | 1704 | } |
1339 | 1705 | ||
1340 | static void fsi_hw_shutdown(struct fsi_priv *fsi, | 1706 | static int fsi_hw_shutdown(struct fsi_priv *fsi, |
1341 | struct device *dev) | 1707 | struct device *dev) |
1342 | { | 1708 | { |
1709 | /* stop master clock */ | ||
1343 | if (fsi_is_clk_master(fsi)) | 1710 | if (fsi_is_clk_master(fsi)) |
1344 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1711 | return fsi_set_master_clk(dev, fsi, fsi->rate, 0); |
1712 | |||
1713 | return 0; | ||
1345 | } | 1714 | } |
1346 | 1715 | ||
1347 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | 1716 | static int fsi_dai_startup(struct snd_pcm_substream *substream, |
@@ -1349,6 +1718,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1349 | { | 1718 | { |
1350 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1719 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1351 | 1720 | ||
1721 | fsi_clk_invalid(fsi); | ||
1352 | fsi->rate = 0; | 1722 | fsi->rate = 0; |
1353 | 1723 | ||
1354 | return 0; | 1724 | return 0; |
@@ -1359,6 +1729,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | |||
1359 | { | 1729 | { |
1360 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1730 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1361 | 1731 | ||
1732 | fsi_clk_invalid(fsi); | ||
1362 | fsi->rate = 0; | 1733 | fsi->rate = 0; |
1363 | } | 1734 | } |
1364 | 1735 | ||
@@ -1372,13 +1743,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1372 | switch (cmd) { | 1743 | switch (cmd) { |
1373 | case SNDRV_PCM_TRIGGER_START: | 1744 | case SNDRV_PCM_TRIGGER_START: |
1374 | fsi_stream_init(fsi, io, substream); | 1745 | fsi_stream_init(fsi, io, substream); |
1375 | fsi_hw_startup(fsi, io, dai->dev); | 1746 | if (!ret) |
1376 | ret = fsi_stream_transfer(io); | 1747 | ret = fsi_hw_startup(fsi, io, dai->dev); |
1377 | if (0 == ret) | 1748 | if (!ret) |
1749 | ret = fsi_stream_transfer(io); | ||
1750 | if (!ret) | ||
1378 | fsi_stream_start(fsi, io); | 1751 | fsi_stream_start(fsi, io); |
1379 | break; | 1752 | break; |
1380 | case SNDRV_PCM_TRIGGER_STOP: | 1753 | case SNDRV_PCM_TRIGGER_STOP: |
1381 | fsi_hw_shutdown(fsi, dai->dev); | 1754 | if (!ret) |
1755 | ret = fsi_hw_shutdown(fsi, dai->dev); | ||
1382 | fsi_stream_stop(fsi, io); | 1756 | fsi_stream_stop(fsi, io); |
1383 | fsi_stream_quit(fsi, io); | 1757 | fsi_stream_quit(fsi, io); |
1384 | break; | 1758 | break; |
@@ -1414,7 +1788,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
1414 | 1788 | ||
1415 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; | 1789 | fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; |
1416 | fsi->chan_num = 2; | 1790 | fsi->chan_num = 2; |
1417 | fsi->spdif = 1; | ||
1418 | 1791 | ||
1419 | return 0; | 1792 | return 0; |
1420 | } | 1793 | } |
@@ -1423,7 +1796,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1423 | { | 1796 | { |
1424 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 1797 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
1425 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1798 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
1426 | u32 flags = fsi_get_info_flags(fsi); | ||
1427 | int ret; | 1799 | int ret; |
1428 | 1800 | ||
1429 | /* set master/slave audio interface */ | 1801 | /* set master/slave audio interface */ |
@@ -1437,23 +1809,50 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1437 | return -EINVAL; | 1809 | return -EINVAL; |
1438 | } | 1810 | } |
1439 | 1811 | ||
1440 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1812 | /* set clock inversion */ |
1441 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1813 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
1442 | return -EINVAL; | 1814 | case SND_SOC_DAIFMT_NB_IF: |
1443 | } | 1815 | fsi->bit_clk_inv = 0; |
1444 | 1816 | fsi->lr_clk_inv = 1; | |
1445 | /* set format */ | ||
1446 | switch (flags & SH_FSI_FMT_MASK) { | ||
1447 | case SH_FSI_FMT_DAI: | ||
1448 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1449 | break; | 1817 | break; |
1450 | case SH_FSI_FMT_SPDIF: | 1818 | case SND_SOC_DAIFMT_IB_NF: |
1451 | ret = fsi_set_fmt_spdif(fsi); | 1819 | fsi->bit_clk_inv = 1; |
1820 | fsi->lr_clk_inv = 0; | ||
1452 | break; | 1821 | break; |
1822 | case SND_SOC_DAIFMT_IB_IF: | ||
1823 | fsi->bit_clk_inv = 1; | ||
1824 | fsi->lr_clk_inv = 1; | ||
1825 | break; | ||
1826 | case SND_SOC_DAIFMT_NB_NF: | ||
1453 | default: | 1827 | default: |
1454 | ret = -EINVAL; | 1828 | fsi->bit_clk_inv = 0; |
1829 | fsi->lr_clk_inv = 0; | ||
1830 | break; | ||
1831 | } | ||
1832 | |||
1833 | if (fsi_is_clk_master(fsi)) { | ||
1834 | /* | ||
1835 | * CAUTION | ||
1836 | * | ||
1837 | * set_rate will be deleted | ||
1838 | */ | ||
1839 | if (set_rate) | ||
1840 | dev_warn(dai->dev, "set_rate will be removed soon\n"); | ||
1841 | |||
1842 | if (fsi->clk_cpg) | ||
1843 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, | ||
1844 | fsi_clk_set_rate_cpg); | ||
1845 | else | ||
1846 | fsi_clk_init(dai->dev, fsi, 1, 1, 0, | ||
1847 | fsi_clk_set_rate_external); | ||
1455 | } | 1848 | } |
1456 | 1849 | ||
1850 | /* set format */ | ||
1851 | if (fsi_is_spdif(fsi)) | ||
1852 | ret = fsi_set_fmt_spdif(fsi); | ||
1853 | else | ||
1854 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1855 | |||
1457 | return ret; | 1856 | return ret; |
1458 | } | 1857 | } |
1459 | 1858 | ||
@@ -1462,19 +1861,13 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
1462 | struct snd_soc_dai *dai) | 1861 | struct snd_soc_dai *dai) |
1463 | { | 1862 | { |
1464 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1863 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1465 | long rate = params_rate(params); | ||
1466 | int ret; | ||
1467 | 1864 | ||
1468 | if (!fsi_is_clk_master(fsi)) | 1865 | if (fsi_is_clk_master(fsi)) { |
1469 | return 0; | 1866 | fsi->rate = params_rate(params); |
1470 | 1867 | fsi_clk_valid(fsi, fsi->rate); | |
1471 | ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); | 1868 | } |
1472 | if (ret < 0) | ||
1473 | return ret; | ||
1474 | |||
1475 | fsi->rate = rate; | ||
1476 | 1869 | ||
1477 | return ret; | 1870 | return 0; |
1478 | } | 1871 | } |
1479 | 1872 | ||
1480 | static const struct snd_soc_dai_ops fsi_dai_ops = { | 1873 | static const struct snd_soc_dai_ops fsi_dai_ops = { |
@@ -1498,7 +1891,7 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { | |||
1498 | .rates = FSI_RATES, | 1891 | .rates = FSI_RATES, |
1499 | .rate_min = 8000, | 1892 | .rate_min = 8000, |
1500 | .rate_max = 192000, | 1893 | .rate_max = 192000, |
1501 | .channels_min = 1, | 1894 | .channels_min = 2, |
1502 | .channels_max = 2, | 1895 | .channels_max = 2, |
1503 | .buffer_bytes_max = 64 * 1024, | 1896 | .buffer_bytes_max = 64 * 1024, |
1504 | .period_bytes_min = 32, | 1897 | .period_bytes_min = 32, |
@@ -1586,14 +1979,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1586 | .playback = { | 1979 | .playback = { |
1587 | .rates = FSI_RATES, | 1980 | .rates = FSI_RATES, |
1588 | .formats = FSI_FMTS, | 1981 | .formats = FSI_FMTS, |
1589 | .channels_min = 1, | 1982 | .channels_min = 2, |
1590 | .channels_max = 8, | 1983 | .channels_max = 2, |
1591 | }, | 1984 | }, |
1592 | .capture = { | 1985 | .capture = { |
1593 | .rates = FSI_RATES, | 1986 | .rates = FSI_RATES, |
1594 | .formats = FSI_FMTS, | 1987 | .formats = FSI_FMTS, |
1595 | .channels_min = 1, | 1988 | .channels_min = 2, |
1596 | .channels_max = 8, | 1989 | .channels_max = 2, |
1597 | }, | 1990 | }, |
1598 | .ops = &fsi_dai_ops, | 1991 | .ops = &fsi_dai_ops, |
1599 | }, | 1992 | }, |
@@ -1602,14 +1995,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1602 | .playback = { | 1995 | .playback = { |
1603 | .rates = FSI_RATES, | 1996 | .rates = FSI_RATES, |
1604 | .formats = FSI_FMTS, | 1997 | .formats = FSI_FMTS, |
1605 | .channels_min = 1, | 1998 | .channels_min = 2, |
1606 | .channels_max = 8, | 1999 | .channels_max = 2, |
1607 | }, | 2000 | }, |
1608 | .capture = { | 2001 | .capture = { |
1609 | .rates = FSI_RATES, | 2002 | .rates = FSI_RATES, |
1610 | .formats = FSI_FMTS, | 2003 | .formats = FSI_FMTS, |
1611 | .channels_min = 1, | 2004 | .channels_min = 2, |
1612 | .channels_max = 8, | 2005 | .channels_max = 2, |
1613 | }, | 2006 | }, |
1614 | .ops = &fsi_dai_ops, | 2007 | .ops = &fsi_dai_ops, |
1615 | }, | 2008 | }, |
@@ -1624,15 +2017,29 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
1624 | /* | 2017 | /* |
1625 | * platform function | 2018 | * platform function |
1626 | */ | 2019 | */ |
1627 | static void fsi_handler_init(struct fsi_priv *fsi) | 2020 | static void fsi_port_info_init(struct fsi_priv *fsi, |
2021 | struct sh_fsi_port_info *info) | ||
2022 | { | ||
2023 | if (info->flags & SH_FSI_FMT_SPDIF) | ||
2024 | fsi->spdif = 1; | ||
2025 | |||
2026 | if (info->flags & SH_FSI_CLK_CPG) | ||
2027 | fsi->clk_cpg = 1; | ||
2028 | |||
2029 | if (info->flags & SH_FSI_ENABLE_STREAM_MODE) | ||
2030 | fsi->enable_stream = 1; | ||
2031 | } | ||
2032 | |||
2033 | static void fsi_handler_init(struct fsi_priv *fsi, | ||
2034 | struct sh_fsi_port_info *info) | ||
1628 | { | 2035 | { |
1629 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ | 2036 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ |
1630 | fsi->playback.priv = fsi; | 2037 | fsi->playback.priv = fsi; |
1631 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ | 2038 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ |
1632 | fsi->capture.priv = fsi; | 2039 | fsi->capture.priv = fsi; |
1633 | 2040 | ||
1634 | if (fsi->info->tx_id) { | 2041 | if (info->tx_id) { |
1635 | fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id; | 2042 | fsi->playback.slave.shdma_slave.slave_id = info->tx_id; |
1636 | fsi->playback.handler = &fsi_dma_push_handler; | 2043 | fsi->playback.handler = &fsi_dma_push_handler; |
1637 | } | 2044 | } |
1638 | } | 2045 | } |
@@ -1642,10 +2049,16 @@ static int fsi_probe(struct platform_device *pdev) | |||
1642 | struct fsi_master *master; | 2049 | struct fsi_master *master; |
1643 | const struct platform_device_id *id_entry; | 2050 | const struct platform_device_id *id_entry; |
1644 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; | 2051 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; |
2052 | struct sh_fsi_port_info nul_info, *pinfo; | ||
2053 | struct fsi_priv *fsi; | ||
1645 | struct resource *res; | 2054 | struct resource *res; |
1646 | unsigned int irq; | 2055 | unsigned int irq; |
1647 | int ret; | 2056 | int ret; |
1648 | 2057 | ||
2058 | nul_info.flags = 0; | ||
2059 | nul_info.tx_id = 0; | ||
2060 | nul_info.rx_id = 0; | ||
2061 | |||
1649 | id_entry = pdev->id_entry; | 2062 | id_entry = pdev->id_entry; |
1650 | if (!id_entry) { | 2063 | if (!id_entry) { |
1651 | dev_err(&pdev->dev, "unknown fsi device\n"); | 2064 | dev_err(&pdev->dev, "unknown fsi device\n"); |
@@ -1678,22 +2091,28 @@ static int fsi_probe(struct platform_device *pdev) | |||
1678 | spin_lock_init(&master->lock); | 2091 | spin_lock_init(&master->lock); |
1679 | 2092 | ||
1680 | /* FSI A setting */ | 2093 | /* FSI A setting */ |
1681 | master->fsia.base = master->base; | 2094 | pinfo = (info) ? &info->port_a : &nul_info; |
1682 | master->fsia.master = master; | 2095 | fsi = &master->fsia; |
1683 | master->fsia.info = &info->port_a; | 2096 | fsi->base = master->base; |
1684 | fsi_handler_init(&master->fsia); | 2097 | fsi->master = master; |
1685 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); | 2098 | fsi->info = pinfo; |
2099 | fsi_port_info_init(fsi, pinfo); | ||
2100 | fsi_handler_init(fsi, pinfo); | ||
2101 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1686 | if (ret < 0) { | 2102 | if (ret < 0) { |
1687 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 2103 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1688 | return ret; | 2104 | return ret; |
1689 | } | 2105 | } |
1690 | 2106 | ||
1691 | /* FSI B setting */ | 2107 | /* FSI B setting */ |
1692 | master->fsib.base = master->base + 0x40; | 2108 | pinfo = (info) ? &info->port_b : &nul_info; |
1693 | master->fsib.master = master; | 2109 | fsi = &master->fsib; |
1694 | master->fsib.info = &info->port_b; | 2110 | fsi->base = master->base + 0x40; |
1695 | fsi_handler_init(&master->fsib); | 2111 | fsi->master = master; |
1696 | ret = fsi_stream_probe(&master->fsib, &pdev->dev); | 2112 | fsi->info = pinfo; |
2113 | fsi_port_info_init(fsi, pinfo); | ||
2114 | fsi_handler_init(fsi, pinfo); | ||
2115 | ret = fsi_stream_probe(fsi, &pdev->dev); | ||
1697 | if (ret < 0) { | 2116 | if (ret < 0) { |
1698 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 2117 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
1699 | goto exit_fsia; | 2118 | goto exit_fsia; |
@@ -1702,7 +2121,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1702 | pm_runtime_enable(&pdev->dev); | 2121 | pm_runtime_enable(&pdev->dev); |
1703 | dev_set_drvdata(&pdev->dev, master); | 2122 | dev_set_drvdata(&pdev->dev, master); |
1704 | 2123 | ||
1705 | ret = request_irq(irq, &fsi_interrupt, 0, | 2124 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, |
1706 | id_entry->name, master); | 2125 | id_entry->name, master); |
1707 | if (ret) { | 2126 | if (ret) { |
1708 | dev_err(&pdev->dev, "irq request err\n"); | 2127 | dev_err(&pdev->dev, "irq request err\n"); |
@@ -1712,7 +2131,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1712 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); | 2131 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); |
1713 | if (ret < 0) { | 2132 | if (ret < 0) { |
1714 | dev_err(&pdev->dev, "cannot snd soc register\n"); | 2133 | dev_err(&pdev->dev, "cannot snd soc register\n"); |
1715 | goto exit_free_irq; | 2134 | goto exit_fsib; |
1716 | } | 2135 | } |
1717 | 2136 | ||
1718 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, | 2137 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, |
@@ -1726,8 +2145,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
1726 | 2145 | ||
1727 | exit_snd_soc: | 2146 | exit_snd_soc: |
1728 | snd_soc_unregister_platform(&pdev->dev); | 2147 | snd_soc_unregister_platform(&pdev->dev); |
1729 | exit_free_irq: | ||
1730 | free_irq(irq, master); | ||
1731 | exit_fsib: | 2148 | exit_fsib: |
1732 | pm_runtime_disable(&pdev->dev); | 2149 | pm_runtime_disable(&pdev->dev); |
1733 | fsi_stream_remove(&master->fsib); | 2150 | fsi_stream_remove(&master->fsib); |
@@ -1743,7 +2160,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1743 | 2160 | ||
1744 | master = dev_get_drvdata(&pdev->dev); | 2161 | master = dev_get_drvdata(&pdev->dev); |
1745 | 2162 | ||
1746 | free_irq(master->irq, master); | ||
1747 | pm_runtime_disable(&pdev->dev); | 2163 | pm_runtime_disable(&pdev->dev); |
1748 | 2164 | ||
1749 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 2165 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); |
@@ -1774,10 +2190,6 @@ static void __fsi_resume(struct fsi_priv *fsi, | |||
1774 | return; | 2190 | return; |
1775 | 2191 | ||
1776 | fsi_hw_startup(fsi, io, dev); | 2192 | fsi_hw_startup(fsi, io, dev); |
1777 | |||
1778 | if (fsi_is_clk_master(fsi) && fsi->rate) | ||
1779 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1780 | |||
1781 | fsi_stream_start(fsi, io); | 2193 | fsi_stream_start(fsi, io); |
1782 | } | 2194 | } |
1783 | 2195 | ||