diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/sh/fsi.c | 441 |
1 files changed, 401 insertions, 40 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9d7f30774a44..4a10e4d1bd43 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,6 +259,8 @@ 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; |
@@ -717,14 +742,335 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
717 | /* | 742 | /* |
718 | * clock function | 743 | * clock function |
719 | */ | 744 | */ |
745 | static int fsi_clk_init(struct device *dev, | ||
746 | struct fsi_priv *fsi, | ||
747 | int xck, | ||
748 | int ick, | ||
749 | int div, | ||
750 | int (*set_rate)(struct device *dev, | ||
751 | struct fsi_priv *fsi, | ||
752 | unsigned long rate)) | ||
753 | { | ||
754 | struct fsi_clk *clock = &fsi->clock; | ||
755 | int is_porta = fsi_is_port_a(fsi); | ||
756 | |||
757 | clock->xck = NULL; | ||
758 | clock->ick = NULL; | ||
759 | clock->div = NULL; | ||
760 | clock->rate = 0; | ||
761 | clock->count = 0; | ||
762 | clock->set_rate = set_rate; | ||
763 | |||
764 | clock->own = devm_clk_get(dev, NULL); | ||
765 | if (IS_ERR(clock->own)) | ||
766 | return -EINVAL; | ||
767 | |||
768 | /* external clock */ | ||
769 | if (xck) { | ||
770 | clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb"); | ||
771 | if (IS_ERR(clock->xck)) { | ||
772 | dev_err(dev, "can't get xck clock\n"); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | if (clock->xck == clock->own) { | ||
776 | dev_err(dev, "cpu doesn't support xck clock\n"); | ||
777 | return -EINVAL; | ||
778 | } | ||
779 | } | ||
780 | |||
781 | /* FSIACLK/FSIBCLK */ | ||
782 | if (ick) { | ||
783 | clock->ick = devm_clk_get(dev, is_porta ? "icka" : "ickb"); | ||
784 | if (IS_ERR(clock->ick)) { | ||
785 | dev_err(dev, "can't get ick clock\n"); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | if (clock->ick == clock->own) { | ||
789 | dev_err(dev, "cpu doesn't support ick clock\n"); | ||
790 | return -EINVAL; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | /* FSI-DIV */ | ||
795 | if (div) { | ||
796 | clock->div = devm_clk_get(dev, is_porta ? "diva" : "divb"); | ||
797 | if (IS_ERR(clock->div)) { | ||
798 | dev_err(dev, "can't get div clock\n"); | ||
799 | return -EINVAL; | ||
800 | } | ||
801 | if (clock->div == clock->own) { | ||
802 | dev_err(dev, "cpu doens't support div clock\n"); | ||
803 | return -EINVAL; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | #define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0) | ||
811 | static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate) | ||
812 | { | ||
813 | fsi->clock.rate = rate; | ||
814 | } | ||
815 | |||
816 | static int fsi_clk_is_valid(struct fsi_priv *fsi) | ||
817 | { | ||
818 | return fsi->clock.set_rate && | ||
819 | fsi->clock.rate; | ||
820 | } | ||
821 | |||
822 | static int fsi_clk_enable(struct device *dev, | ||
823 | struct fsi_priv *fsi, | ||
824 | unsigned long rate) | ||
825 | { | ||
826 | struct fsi_clk *clock = &fsi->clock; | ||
827 | int ret = -EINVAL; | ||
828 | |||
829 | if (!fsi_clk_is_valid(fsi)) | ||
830 | return ret; | ||
831 | |||
832 | if (0 == clock->count) { | ||
833 | ret = clock->set_rate(dev, fsi, rate); | ||
834 | if (ret < 0) { | ||
835 | fsi_clk_invalid(fsi); | ||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | if (clock->xck) | ||
840 | clk_enable(clock->xck); | ||
841 | if (clock->ick) | ||
842 | clk_enable(clock->ick); | ||
843 | if (clock->div) | ||
844 | clk_enable(clock->div); | ||
845 | |||
846 | clock->count++; | ||
847 | } | ||
848 | |||
849 | return ret; | ||
850 | } | ||
851 | |||
852 | static int fsi_clk_disable(struct device *dev, | ||
853 | struct fsi_priv *fsi) | ||
854 | { | ||
855 | struct fsi_clk *clock = &fsi->clock; | ||
856 | |||
857 | if (!fsi_clk_is_valid(fsi)) | ||
858 | return -EINVAL; | ||
859 | |||
860 | if (1 == clock->count--) { | ||
861 | if (clock->xck) | ||
862 | clk_disable(clock->xck); | ||
863 | if (clock->ick) | ||
864 | clk_disable(clock->ick); | ||
865 | if (clock->div) | ||
866 | clk_disable(clock->div); | ||
867 | } | ||
868 | |||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static int fsi_clk_set_ackbpf(struct device *dev, | ||
873 | struct fsi_priv *fsi, | ||
874 | int ackmd, int bpfmd) | ||
875 | { | ||
876 | u32 data = 0; | ||
877 | |||
878 | /* check ackmd/bpfmd relationship */ | ||
879 | if (bpfmd > ackmd) { | ||
880 | dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd); | ||
881 | return -EINVAL; | ||
882 | } | ||
883 | |||
884 | /* ACKMD */ | ||
885 | switch (ackmd) { | ||
886 | case 512: | ||
887 | data |= (0x0 << 12); | ||
888 | break; | ||
889 | case 256: | ||
890 | data |= (0x1 << 12); | ||
891 | break; | ||
892 | case 128: | ||
893 | data |= (0x2 << 12); | ||
894 | break; | ||
895 | case 64: | ||
896 | data |= (0x3 << 12); | ||
897 | break; | ||
898 | case 32: | ||
899 | data |= (0x4 << 12); | ||
900 | break; | ||
901 | default: | ||
902 | dev_err(dev, "unsupported ackmd (%d)\n", ackmd); | ||
903 | return -EINVAL; | ||
904 | } | ||
905 | |||
906 | /* BPFMD */ | ||
907 | switch (bpfmd) { | ||
908 | case 32: | ||
909 | data |= (0x0 << 8); | ||
910 | break; | ||
911 | case 64: | ||
912 | data |= (0x1 << 8); | ||
913 | break; | ||
914 | case 128: | ||
915 | data |= (0x2 << 8); | ||
916 | break; | ||
917 | case 256: | ||
918 | data |= (0x3 << 8); | ||
919 | break; | ||
920 | case 512: | ||
921 | data |= (0x4 << 8); | ||
922 | break; | ||
923 | case 16: | ||
924 | data |= (0x7 << 8); | ||
925 | break; | ||
926 | default: | ||
927 | dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd); | ||
928 | return -EINVAL; | ||
929 | } | ||
930 | |||
931 | dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd); | ||
932 | |||
933 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
934 | udelay(10); | ||
935 | |||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | static int fsi_clk_set_rate_external(struct device *dev, | ||
940 | struct fsi_priv *fsi, | ||
941 | unsigned long rate) | ||
942 | { | ||
943 | struct clk *xck = fsi->clock.xck; | ||
944 | struct clk *ick = fsi->clock.ick; | ||
945 | unsigned long xrate; | ||
946 | int ackmd, bpfmd; | ||
947 | int ret = 0; | ||
948 | |||
949 | /* check clock rate */ | ||
950 | xrate = clk_get_rate(xck); | ||
951 | if (xrate % rate) { | ||
952 | dev_err(dev, "unsupported clock rate\n"); | ||
953 | return -EINVAL; | ||
954 | } | ||
955 | |||
956 | clk_set_parent(ick, xck); | ||
957 | clk_set_rate(ick, xrate); | ||
958 | |||
959 | bpfmd = fsi->chan_num * 32; | ||
960 | ackmd = xrate / rate; | ||
961 | |||
962 | dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate); | ||
963 | |||
964 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
965 | if (ret < 0) | ||
966 | dev_err(dev, "%s failed", __func__); | ||
967 | |||
968 | return ret; | ||
969 | } | ||
970 | |||
971 | static int fsi_clk_set_rate_cpg(struct device *dev, | ||
972 | struct fsi_priv *fsi, | ||
973 | unsigned long rate) | ||
974 | { | ||
975 | struct clk *ick = fsi->clock.ick; | ||
976 | struct clk *div = fsi->clock.div; | ||
977 | unsigned long target = 0; /* 12288000 or 11289600 */ | ||
978 | unsigned long actual, cout; | ||
979 | unsigned long diff, min; | ||
980 | unsigned long best_cout, best_act; | ||
981 | int adj; | ||
982 | int ackmd, bpfmd; | ||
983 | int ret = -EINVAL; | ||
984 | |||
985 | if (!(12288000 % rate)) | ||
986 | target = 12288000; | ||
987 | if (!(11289600 % rate)) | ||
988 | target = 11289600; | ||
989 | if (!target) { | ||
990 | dev_err(dev, "unsupported rate\n"); | ||
991 | return ret; | ||
992 | } | ||
993 | |||
994 | bpfmd = fsi->chan_num * 32; | ||
995 | ackmd = target / rate; | ||
996 | ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd); | ||
997 | if (ret < 0) { | ||
998 | dev_err(dev, "%s failed", __func__); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | /* | ||
1003 | * The clock flow is | ||
1004 | * | ||
1005 | * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec] | ||
1006 | * | ||
1007 | * But, it needs to find best match of CPG and FSI_DIV | ||
1008 | * combination, since it is difficult to generate correct | ||
1009 | * frequency of audio clock from ick clock only. | ||
1010 | * Because ick is created from its parent clock. | ||
1011 | * | ||
1012 | * target = rate x [512/256/128/64]fs | ||
1013 | * cout = round(target x adjustment) | ||
1014 | * actual = cout / adjustment (by FSI-DIV) ~= target | ||
1015 | * audio = actual | ||
1016 | */ | ||
1017 | min = ~0; | ||
1018 | best_cout = 0; | ||
1019 | best_act = 0; | ||
1020 | for (adj = 1; adj < 0xffff; adj++) { | ||
1021 | |||
1022 | cout = target * adj; | ||
1023 | if (cout > 100000000) /* max clock = 100MHz */ | ||
1024 | break; | ||
1025 | |||
1026 | /* cout/actual audio clock */ | ||
1027 | cout = clk_round_rate(ick, cout); | ||
1028 | actual = cout / adj; | ||
1029 | |||
1030 | /* find best frequency */ | ||
1031 | diff = abs(actual - target); | ||
1032 | if (diff < min) { | ||
1033 | min = diff; | ||
1034 | best_cout = cout; | ||
1035 | best_act = actual; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | ret = clk_set_rate(ick, best_cout); | ||
1040 | if (ret < 0) { | ||
1041 | dev_err(dev, "ick clock failed\n"); | ||
1042 | return -EIO; | ||
1043 | } | ||
1044 | |||
1045 | ret = clk_set_rate(div, clk_round_rate(div, best_act)); | ||
1046 | if (ret < 0) { | ||
1047 | dev_err(dev, "div clock failed\n"); | ||
1048 | return -EIO; | ||
1049 | } | ||
1050 | |||
1051 | dev_dbg(dev, "ick/div = %ld/%ld\n", | ||
1052 | clk_get_rate(ick), clk_get_rate(div)); | ||
1053 | |||
1054 | return ret; | ||
1055 | } | ||
1056 | |||
720 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | 1057 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, |
721 | long rate, int enable) | 1058 | long rate, int enable) |
722 | { | 1059 | { |
723 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | 1060 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
724 | int ret; | 1061 | int ret; |
725 | 1062 | ||
726 | if (!set_rate) | 1063 | /* |
727 | return 0; | 1064 | * CAUTION |
1065 | * | ||
1066 | * set_rate will be deleted | ||
1067 | */ | ||
1068 | if (!set_rate) { | ||
1069 | if (enable) | ||
1070 | return fsi_clk_enable(dev, fsi, rate); | ||
1071 | else | ||
1072 | return fsi_clk_disable(dev, fsi); | ||
1073 | } | ||
728 | 1074 | ||
729 | ret = set_rate(dev, rate, enable); | 1075 | ret = set_rate(dev, rate, enable); |
730 | if (ret < 0) /* error */ | 1076 | if (ret < 0) /* error */ |
@@ -1334,14 +1680,21 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1334 | /* fifo init */ | 1680 | /* fifo init */ |
1335 | fsi_fifo_init(fsi, io, dev); | 1681 | fsi_fifo_init(fsi, io, dev); |
1336 | 1682 | ||
1683 | /* start master clock */ | ||
1684 | if (fsi_is_clk_master(fsi)) | ||
1685 | return fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1686 | |||
1337 | return 0; | 1687 | return 0; |
1338 | } | 1688 | } |
1339 | 1689 | ||
1340 | static void fsi_hw_shutdown(struct fsi_priv *fsi, | 1690 | static int fsi_hw_shutdown(struct fsi_priv *fsi, |
1341 | struct device *dev) | 1691 | struct device *dev) |
1342 | { | 1692 | { |
1693 | /* stop master clock */ | ||
1343 | if (fsi_is_clk_master(fsi)) | 1694 | if (fsi_is_clk_master(fsi)) |
1344 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1695 | return fsi_set_master_clk(dev, fsi, fsi->rate, 0); |
1696 | |||
1697 | return 0; | ||
1345 | } | 1698 | } |
1346 | 1699 | ||
1347 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | 1700 | static int fsi_dai_startup(struct snd_pcm_substream *substream, |
@@ -1349,6 +1702,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1349 | { | 1702 | { |
1350 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1703 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1351 | 1704 | ||
1705 | fsi_clk_invalid(fsi); | ||
1352 | fsi->rate = 0; | 1706 | fsi->rate = 0; |
1353 | 1707 | ||
1354 | return 0; | 1708 | return 0; |
@@ -1359,6 +1713,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | |||
1359 | { | 1713 | { |
1360 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1714 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1361 | 1715 | ||
1716 | fsi_clk_invalid(fsi); | ||
1362 | fsi->rate = 0; | 1717 | fsi->rate = 0; |
1363 | } | 1718 | } |
1364 | 1719 | ||
@@ -1372,13 +1727,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1372 | switch (cmd) { | 1727 | switch (cmd) { |
1373 | case SNDRV_PCM_TRIGGER_START: | 1728 | case SNDRV_PCM_TRIGGER_START: |
1374 | fsi_stream_init(fsi, io, substream); | 1729 | fsi_stream_init(fsi, io, substream); |
1375 | fsi_hw_startup(fsi, io, dai->dev); | 1730 | if (!ret) |
1376 | ret = fsi_stream_transfer(io); | 1731 | ret = fsi_hw_startup(fsi, io, dai->dev); |
1377 | if (0 == ret) | 1732 | if (!ret) |
1733 | ret = fsi_stream_transfer(io); | ||
1734 | if (!ret) | ||
1378 | fsi_stream_start(fsi, io); | 1735 | fsi_stream_start(fsi, io); |
1379 | break; | 1736 | break; |
1380 | case SNDRV_PCM_TRIGGER_STOP: | 1737 | case SNDRV_PCM_TRIGGER_STOP: |
1381 | fsi_hw_shutdown(fsi, dai->dev); | 1738 | if (!ret) |
1739 | ret = fsi_hw_shutdown(fsi, dai->dev); | ||
1382 | fsi_stream_stop(fsi, io); | 1740 | fsi_stream_stop(fsi, io); |
1383 | fsi_stream_quit(fsi, io); | 1741 | fsi_stream_quit(fsi, io); |
1384 | break; | 1742 | break; |
@@ -1437,9 +1795,25 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1437 | return -EINVAL; | 1795 | return -EINVAL; |
1438 | } | 1796 | } |
1439 | 1797 | ||
1440 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1798 | if (fsi_is_clk_master(fsi)) { |
1441 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1799 | /* |
1442 | return -EINVAL; | 1800 | * CAUTION |
1801 | * | ||
1802 | * set_rate will be deleted | ||
1803 | */ | ||
1804 | if (set_rate) | ||
1805 | dev_warn(dai->dev, "set_rate will be removed soon\n"); | ||
1806 | |||
1807 | switch (flags & SH_FSI_CLK_MASK) { | ||
1808 | case SH_FSI_CLK_EXTERNAL: | ||
1809 | fsi_clk_init(dai->dev, fsi, 1, 1, 0, | ||
1810 | fsi_clk_set_rate_external); | ||
1811 | break; | ||
1812 | case SH_FSI_CLK_CPG: | ||
1813 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, | ||
1814 | fsi_clk_set_rate_cpg); | ||
1815 | break; | ||
1816 | } | ||
1443 | } | 1817 | } |
1444 | 1818 | ||
1445 | /* set format */ | 1819 | /* set format */ |
@@ -1462,19 +1836,13 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
1462 | struct snd_soc_dai *dai) | 1836 | struct snd_soc_dai *dai) |
1463 | { | 1837 | { |
1464 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1838 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1465 | long rate = params_rate(params); | ||
1466 | int ret; | ||
1467 | |||
1468 | if (!fsi_is_clk_master(fsi)) | ||
1469 | return 0; | ||
1470 | 1839 | ||
1471 | ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); | 1840 | if (fsi_is_clk_master(fsi)) { |
1472 | if (ret < 0) | 1841 | fsi->rate = params_rate(params); |
1473 | return ret; | 1842 | fsi_clk_valid(fsi, fsi->rate); |
1474 | 1843 | } | |
1475 | fsi->rate = rate; | ||
1476 | 1844 | ||
1477 | return ret; | 1845 | return 0; |
1478 | } | 1846 | } |
1479 | 1847 | ||
1480 | static const struct snd_soc_dai_ops fsi_dai_ops = { | 1848 | static const struct snd_soc_dai_ops fsi_dai_ops = { |
@@ -1498,7 +1866,7 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { | |||
1498 | .rates = FSI_RATES, | 1866 | .rates = FSI_RATES, |
1499 | .rate_min = 8000, | 1867 | .rate_min = 8000, |
1500 | .rate_max = 192000, | 1868 | .rate_max = 192000, |
1501 | .channels_min = 1, | 1869 | .channels_min = 2, |
1502 | .channels_max = 2, | 1870 | .channels_max = 2, |
1503 | .buffer_bytes_max = 64 * 1024, | 1871 | .buffer_bytes_max = 64 * 1024, |
1504 | .period_bytes_min = 32, | 1872 | .period_bytes_min = 32, |
@@ -1586,14 +1954,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1586 | .playback = { | 1954 | .playback = { |
1587 | .rates = FSI_RATES, | 1955 | .rates = FSI_RATES, |
1588 | .formats = FSI_FMTS, | 1956 | .formats = FSI_FMTS, |
1589 | .channels_min = 1, | 1957 | .channels_min = 2, |
1590 | .channels_max = 8, | 1958 | .channels_max = 2, |
1591 | }, | 1959 | }, |
1592 | .capture = { | 1960 | .capture = { |
1593 | .rates = FSI_RATES, | 1961 | .rates = FSI_RATES, |
1594 | .formats = FSI_FMTS, | 1962 | .formats = FSI_FMTS, |
1595 | .channels_min = 1, | 1963 | .channels_min = 2, |
1596 | .channels_max = 8, | 1964 | .channels_max = 2, |
1597 | }, | 1965 | }, |
1598 | .ops = &fsi_dai_ops, | 1966 | .ops = &fsi_dai_ops, |
1599 | }, | 1967 | }, |
@@ -1602,14 +1970,14 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1602 | .playback = { | 1970 | .playback = { |
1603 | .rates = FSI_RATES, | 1971 | .rates = FSI_RATES, |
1604 | .formats = FSI_FMTS, | 1972 | .formats = FSI_FMTS, |
1605 | .channels_min = 1, | 1973 | .channels_min = 2, |
1606 | .channels_max = 8, | 1974 | .channels_max = 2, |
1607 | }, | 1975 | }, |
1608 | .capture = { | 1976 | .capture = { |
1609 | .rates = FSI_RATES, | 1977 | .rates = FSI_RATES, |
1610 | .formats = FSI_FMTS, | 1978 | .formats = FSI_FMTS, |
1611 | .channels_min = 1, | 1979 | .channels_min = 2, |
1612 | .channels_max = 8, | 1980 | .channels_max = 2, |
1613 | }, | 1981 | }, |
1614 | .ops = &fsi_dai_ops, | 1982 | .ops = &fsi_dai_ops, |
1615 | }, | 1983 | }, |
@@ -1702,7 +2070,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1702 | pm_runtime_enable(&pdev->dev); | 2070 | pm_runtime_enable(&pdev->dev); |
1703 | dev_set_drvdata(&pdev->dev, master); | 2071 | dev_set_drvdata(&pdev->dev, master); |
1704 | 2072 | ||
1705 | ret = request_irq(irq, &fsi_interrupt, 0, | 2073 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, |
1706 | id_entry->name, master); | 2074 | id_entry->name, master); |
1707 | if (ret) { | 2075 | if (ret) { |
1708 | dev_err(&pdev->dev, "irq request err\n"); | 2076 | dev_err(&pdev->dev, "irq request err\n"); |
@@ -1712,7 +2080,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1712 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); | 2080 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); |
1713 | if (ret < 0) { | 2081 | if (ret < 0) { |
1714 | dev_err(&pdev->dev, "cannot snd soc register\n"); | 2082 | dev_err(&pdev->dev, "cannot snd soc register\n"); |
1715 | goto exit_free_irq; | 2083 | goto exit_fsib; |
1716 | } | 2084 | } |
1717 | 2085 | ||
1718 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, | 2086 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, |
@@ -1726,8 +2094,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
1726 | 2094 | ||
1727 | exit_snd_soc: | 2095 | exit_snd_soc: |
1728 | snd_soc_unregister_platform(&pdev->dev); | 2096 | snd_soc_unregister_platform(&pdev->dev); |
1729 | exit_free_irq: | ||
1730 | free_irq(irq, master); | ||
1731 | exit_fsib: | 2097 | exit_fsib: |
1732 | pm_runtime_disable(&pdev->dev); | 2098 | pm_runtime_disable(&pdev->dev); |
1733 | fsi_stream_remove(&master->fsib); | 2099 | fsi_stream_remove(&master->fsib); |
@@ -1743,7 +2109,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1743 | 2109 | ||
1744 | master = dev_get_drvdata(&pdev->dev); | 2110 | master = dev_get_drvdata(&pdev->dev); |
1745 | 2111 | ||
1746 | free_irq(master->irq, master); | ||
1747 | pm_runtime_disable(&pdev->dev); | 2112 | pm_runtime_disable(&pdev->dev); |
1748 | 2113 | ||
1749 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 2114 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); |
@@ -1774,10 +2139,6 @@ static void __fsi_resume(struct fsi_priv *fsi, | |||
1774 | return; | 2139 | return; |
1775 | 2140 | ||
1776 | fsi_hw_startup(fsi, io, dev); | 2141 | 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); | 2142 | fsi_stream_start(fsi, io); |
1782 | } | 2143 | } |
1783 | 2144 | ||