diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/renesas,fsi.txt | 26 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 11 | ||||
-rw-r--r-- | arch/sh/boards/mach-ecovec24/setup.c | 12 | ||||
-rw-r--r-- | arch/sh/boards/mach-se/7724/setup.c | 12 | ||||
-rw-r--r-- | include/sound/sh_fsi.h | 70 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 242 |
7 files changed, 122 insertions, 262 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,fsi.txt b/Documentation/devicetree/bindings/sound/renesas,fsi.txt new file mode 100644 index 000000000000..c5be003f413e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/renesas,fsi.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | Renesas FSI | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "renesas,sh_fsi2" or "renesas,sh_fsi" | ||
5 | - reg : Should contain the register physical address and length | ||
6 | - interrupts : Should contain FSI interrupt | ||
7 | |||
8 | - fsia,spdif-connection : FSI is connected by S/PDFI | ||
9 | - fsia,stream-mode-support : FSI supports 16bit stream mode. | ||
10 | - fsia,use-internal-clock : FSI uses internal clock when master mode. | ||
11 | |||
12 | - fsib,spdif-connection : same as fsia | ||
13 | - fsib,stream-mode-support : same as fsia | ||
14 | - fsib,use-internal-clock : same as fsia | ||
15 | |||
16 | Example: | ||
17 | |||
18 | sh_fsi2: sh_fsi2@0xec230000 { | ||
19 | compatible = "renesas,sh_fsi2"; | ||
20 | reg = <0xec230000 0x400>; | ||
21 | interrupts = <0 146 0x4>; | ||
22 | |||
23 | fsia,spdif-connection; | ||
24 | fsia,stream-mode-support; | ||
25 | fsia,use-internal-clock; | ||
26 | }; | ||
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 99ef190d0909..4c979039d97e 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -657,14 +657,8 @@ static struct platform_device lcdc_device = { | |||
657 | /* FSI */ | 657 | /* FSI */ |
658 | #define IRQ_FSI evt2irq(0x1840) | 658 | #define IRQ_FSI evt2irq(0x1840) |
659 | static struct sh_fsi_platform_info fsi_info = { | 659 | static struct sh_fsi_platform_info fsi_info = { |
660 | .port_a = { | ||
661 | .flags = SH_FSI_BRS_INV, | ||
662 | }, | ||
663 | .port_b = { | 660 | .port_b = { |
664 | .flags = SH_FSI_BRS_INV | | 661 | .flags = SH_FSI_CLK_CPG | |
665 | SH_FSI_BRM_INV | | ||
666 | SH_FSI_LRS_INV | | ||
667 | SH_FSI_CLK_CPG | | ||
668 | SH_FSI_FMT_SPDIF, | 662 | SH_FSI_FMT_SPDIF, |
669 | }, | 663 | }, |
670 | }; | 664 | }; |
@@ -816,7 +810,8 @@ static struct platform_device lcdc1_device = { | |||
816 | }; | 810 | }; |
817 | 811 | ||
818 | static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = { | 812 | static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = { |
819 | .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM, | 813 | .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM | |
814 | SND_SOC_DAIFMT_IB_NF, | ||
820 | }; | 815 | }; |
821 | 816 | ||
822 | static struct asoc_simple_card_info fsi2_hdmi_info = { | 817 | static struct asoc_simple_card_info fsi2_hdmi_info = { |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 2fed62f66045..b5d210b4264c 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -503,7 +503,8 @@ static struct platform_device hdmi_lcdc_device = { | |||
503 | }; | 503 | }; |
504 | 504 | ||
505 | static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = { | 505 | static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = { |
506 | .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM, | 506 | .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM | |
507 | SND_SOC_DAIFMT_IB_NF, | ||
507 | }; | 508 | }; |
508 | 509 | ||
509 | static struct asoc_simple_card_info fsi2_hdmi_info = { | 510 | static struct asoc_simple_card_info fsi2_hdmi_info = { |
@@ -858,16 +859,12 @@ static struct platform_device leds_device = { | |||
858 | #define IRQ_FSI evt2irq(0x1840) | 859 | #define IRQ_FSI evt2irq(0x1840) |
859 | static struct sh_fsi_platform_info fsi_info = { | 860 | static struct sh_fsi_platform_info fsi_info = { |
860 | .port_a = { | 861 | .port_a = { |
861 | .flags = SH_FSI_BRS_INV, | ||
862 | .tx_id = SHDMA_SLAVE_FSIA_TX, | 862 | .tx_id = SHDMA_SLAVE_FSIA_TX, |
863 | .rx_id = SHDMA_SLAVE_FSIA_RX, | 863 | .rx_id = SHDMA_SLAVE_FSIA_RX, |
864 | }, | 864 | }, |
865 | .port_b = { | 865 | .port_b = { |
866 | .flags = SH_FSI_BRS_INV | | 866 | .flags = SH_FSI_CLK_CPG | |
867 | SH_FSI_BRM_INV | | 867 | SH_FSI_FMT_SPDIF, |
868 | SH_FSI_LRS_INV | | ||
869 | SH_FSI_CLK_CPG | | ||
870 | SH_FSI_FMT_SPDIF, | ||
871 | } | 868 | } |
872 | }; | 869 | }; |
873 | 870 | ||
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index a0fa5791cd44..023b3f06b728 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -887,12 +887,6 @@ static struct platform_device camera_devices[] = { | |||
887 | }; | 887 | }; |
888 | 888 | ||
889 | /* FSI */ | 889 | /* FSI */ |
890 | static struct sh_fsi_platform_info fsi_info = { | ||
891 | .port_b = { | ||
892 | .flags = SH_FSI_BRS_INV, | ||
893 | }, | ||
894 | }; | ||
895 | |||
896 | static struct resource fsi_resources[] = { | 890 | static struct resource fsi_resources[] = { |
897 | [0] = { | 891 | [0] = { |
898 | .name = "FSI", | 892 | .name = "FSI", |
@@ -911,15 +905,13 @@ static struct platform_device fsi_device = { | |||
911 | .id = 0, | 905 | .id = 0, |
912 | .num_resources = ARRAY_SIZE(fsi_resources), | 906 | .num_resources = ARRAY_SIZE(fsi_resources), |
913 | .resource = fsi_resources, | 907 | .resource = fsi_resources, |
914 | .dev = { | ||
915 | .platform_data = &fsi_info, | ||
916 | }, | ||
917 | }; | 908 | }; |
918 | 909 | ||
919 | static struct asoc_simple_dai_init_info fsi_da7210_init_info = { | 910 | static struct asoc_simple_dai_init_info fsi_da7210_init_info = { |
920 | .fmt = SND_SOC_DAIFMT_I2S, | 911 | .fmt = SND_SOC_DAIFMT_I2S, |
921 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM, | 912 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM, |
922 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS, | 913 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS | |
914 | SND_SOC_DAIFMT_IB_NF, | ||
923 | }; | 915 | }; |
924 | 916 | ||
925 | static struct asoc_simple_card_info fsi_da7210_info = { | 917 | static struct asoc_simple_card_info fsi_da7210_info = { |
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 35f6efa3ac0e..975608f5e805 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -279,12 +279,6 @@ static struct platform_device ceu1_device = { | |||
279 | 279 | ||
280 | /* FSI */ | 280 | /* FSI */ |
281 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ | 281 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ |
282 | static struct sh_fsi_platform_info fsi_info = { | ||
283 | .port_a = { | ||
284 | .flags = SH_FSI_BRS_INV, | ||
285 | }, | ||
286 | }; | ||
287 | |||
288 | static struct resource fsi_resources[] = { | 282 | static struct resource fsi_resources[] = { |
289 | [0] = { | 283 | [0] = { |
290 | .name = "FSI", | 284 | .name = "FSI", |
@@ -303,15 +297,13 @@ static struct platform_device fsi_device = { | |||
303 | .id = 0, | 297 | .id = 0, |
304 | .num_resources = ARRAY_SIZE(fsi_resources), | 298 | .num_resources = ARRAY_SIZE(fsi_resources), |
305 | .resource = fsi_resources, | 299 | .resource = fsi_resources, |
306 | .dev = { | ||
307 | .platform_data = &fsi_info, | ||
308 | }, | ||
309 | }; | 300 | }; |
310 | 301 | ||
311 | static struct asoc_simple_dai_init_info fsi2_ak4642_init_info = { | 302 | static struct asoc_simple_dai_init_info fsi2_ak4642_init_info = { |
312 | .fmt = SND_SOC_DAIFMT_LEFT_J, | 303 | .fmt = SND_SOC_DAIFMT_LEFT_J, |
313 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM, | 304 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM, |
314 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS, | 305 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS | |
306 | SND_SOC_DAIFMT_IB_NF, | ||
315 | .sysclk = 11289600, | 307 | .sysclk = 11289600, |
316 | }; | 308 | }; |
317 | 309 | ||
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index cc1c919c6436..7a9710b4b799 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h | |||
@@ -11,82 +11,20 @@ | |||
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | |||
15 | #define FSI_PORT_A 0 | ||
16 | #define FSI_PORT_B 1 | ||
17 | |||
18 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
19 | #include <sound/soc.h> | 15 | #include <sound/soc.h> |
20 | 16 | ||
21 | /* | 17 | /* |
22 | * flags format | 18 | * flags |
23 | * | ||
24 | * 0x00000CBA | ||
25 | * | ||
26 | * A: inversion | ||
27 | * B: format mode | ||
28 | * C: chip specific | ||
29 | * D: clock selecter if master mode | ||
30 | */ | 19 | */ |
31 | 20 | #define SH_FSI_FMT_SPDIF (1 << 0) /* spdif for HDMI */ | |
32 | /* A: clock inversion */ | 21 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 1) /* for 16bit data */ |
33 | #define SH_FSI_INVERSION_MASK 0x0000000F | 22 | #define SH_FSI_CLK_CPG (1 << 2) /* FSIxCK + FSI-DIV */ |
34 | #define SH_FSI_LRM_INV (1 << 0) | ||
35 | #define SH_FSI_BRM_INV (1 << 1) | ||
36 | #define SH_FSI_LRS_INV (1 << 2) | ||
37 | #define SH_FSI_BRS_INV (1 << 3) | ||
38 | |||
39 | /* B: format mode */ | ||
40 | #define SH_FSI_FMT_MASK 0x000000F0 | ||
41 | #define SH_FSI_FMT_DAI (0 << 4) | ||
42 | #define SH_FSI_FMT_SPDIF (1 << 4) | ||
43 | |||
44 | /* C: chip specific */ | ||
45 | #define SH_FSI_OPTION_MASK 0x00000F00 | ||
46 | #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ | ||
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 | |||
53 | /* | ||
54 | * set_rate return value | ||
55 | * | ||
56 | * see ACKMD/BPFMD on | ||
57 | * ACK_MD (FSI2) | ||
58 | * CKG1 (FSI) | ||
59 | * | ||
60 | * err : return value < 0 | ||
61 | * no change : return value == 0 | ||
62 | * change xMD : return value > 0 | ||
63 | * | ||
64 | * 0x-00000AB | ||
65 | * | ||
66 | * A: ACKMD value | ||
67 | * B: BPFMD value | ||
68 | */ | ||
69 | |||
70 | #define SH_FSI_ACKMD_MASK (0xF << 0) | ||
71 | #define SH_FSI_ACKMD_512 (1 << 0) | ||
72 | #define SH_FSI_ACKMD_256 (2 << 0) | ||
73 | #define SH_FSI_ACKMD_128 (3 << 0) | ||
74 | #define SH_FSI_ACKMD_64 (4 << 0) | ||
75 | #define SH_FSI_ACKMD_32 (5 << 0) | ||
76 | |||
77 | #define SH_FSI_BPFMD_MASK (0xF << 4) | ||
78 | #define SH_FSI_BPFMD_512 (1 << 4) | ||
79 | #define SH_FSI_BPFMD_256 (2 << 4) | ||
80 | #define SH_FSI_BPFMD_128 (3 << 4) | ||
81 | #define SH_FSI_BPFMD_64 (4 << 4) | ||
82 | #define SH_FSI_BPFMD_32 (5 << 4) | ||
83 | #define SH_FSI_BPFMD_16 (6 << 4) | ||
84 | 23 | ||
85 | struct sh_fsi_port_info { | 24 | struct sh_fsi_port_info { |
86 | unsigned long flags; | 25 | unsigned long flags; |
87 | int tx_id; | 26 | int tx_id; |
88 | int rx_id; | 27 | int rx_id; |
89 | int (*set_rate)(struct device *dev, int rate, int enable); | ||
90 | }; | 28 | }; |
91 | 29 | ||
92 | struct sh_fsi_platform_info { | 30 | struct sh_fsi_platform_info { |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index a606d0f93d1c..c724026a246f 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/of.h> | ||
20 | #include <linux/of_device.h> | ||
19 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
20 | #include <linux/sh_dma.h> | 22 | #include <linux/sh_dma.h> |
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -131,8 +133,6 @@ | |||
131 | 133 | ||
132 | #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) | 134 | #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) |
133 | 135 | ||
134 | typedef int (*set_rate_func)(struct device *dev, int rate, int enable); | ||
135 | |||
136 | /* | 136 | /* |
137 | * bus options | 137 | * bus options |
138 | * | 138 | * |
@@ -244,8 +244,7 @@ struct fsi_clk { | |||
244 | struct clk *ick; | 244 | struct clk *ick; |
245 | struct clk *div; | 245 | struct clk *div; |
246 | int (*set_rate)(struct device *dev, | 246 | int (*set_rate)(struct device *dev, |
247 | struct fsi_priv *fsi, | 247 | struct fsi_priv *fsi); |
248 | unsigned long rate); | ||
249 | 248 | ||
250 | unsigned long rate; | 249 | unsigned long rate; |
251 | unsigned int count; | 250 | unsigned int count; |
@@ -254,7 +253,6 @@ struct fsi_clk { | |||
254 | struct fsi_priv { | 253 | struct fsi_priv { |
255 | void __iomem *base; | 254 | void __iomem *base; |
256 | struct fsi_master *master; | 255 | struct fsi_master *master; |
257 | struct sh_fsi_port_info *info; | ||
258 | 256 | ||
259 | struct fsi_stream playback; | 257 | struct fsi_stream playback; |
260 | struct fsi_stream capture; | 258 | struct fsi_stream capture; |
@@ -270,8 +268,6 @@ struct fsi_priv { | |||
270 | int enable_stream:1; | 268 | int enable_stream:1; |
271 | int bit_clk_inv:1; | 269 | int bit_clk_inv:1; |
272 | int lr_clk_inv:1; | 270 | int lr_clk_inv:1; |
273 | |||
274 | long rate; | ||
275 | }; | 271 | }; |
276 | 272 | ||
277 | struct fsi_stream_handler { | 273 | struct fsi_stream_handler { |
@@ -303,7 +299,7 @@ struct fsi_master { | |||
303 | int irq; | 299 | int irq; |
304 | struct fsi_priv fsia; | 300 | struct fsi_priv fsia; |
305 | struct fsi_priv fsib; | 301 | struct fsi_priv fsib; |
306 | struct fsi_core *core; | 302 | const struct fsi_core *core; |
307 | spinlock_t lock; | 303 | spinlock_t lock; |
308 | }; | 304 | }; |
309 | 305 | ||
@@ -431,22 +427,6 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) | |||
431 | return fsi_get_priv_frm_dai(fsi_get_dai(substream)); | 427 | return fsi_get_priv_frm_dai(fsi_get_dai(substream)); |
432 | } | 428 | } |
433 | 429 | ||
434 | static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi) | ||
435 | { | ||
436 | if (!fsi->info) | ||
437 | return NULL; | ||
438 | |||
439 | return fsi->info->set_rate; | ||
440 | } | ||
441 | |||
442 | static u32 fsi_get_info_flags(struct fsi_priv *fsi) | ||
443 | { | ||
444 | if (!fsi->info) | ||
445 | return 0; | ||
446 | |||
447 | return fsi->info->flags; | ||
448 | } | ||
449 | |||
450 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io) | 430 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io) |
451 | { | 431 | { |
452 | int is_play = fsi_stream_is_play(fsi, io); | 432 | int is_play = fsi_stream_is_play(fsi, io); |
@@ -757,8 +737,7 @@ static int fsi_clk_init(struct device *dev, | |||
757 | int ick, | 737 | int ick, |
758 | int div, | 738 | int div, |
759 | int (*set_rate)(struct device *dev, | 739 | int (*set_rate)(struct device *dev, |
760 | struct fsi_priv *fsi, | 740 | struct fsi_priv *fsi)) |
761 | unsigned long rate)) | ||
762 | { | 741 | { |
763 | struct fsi_clk *clock = &fsi->clock; | 742 | struct fsi_clk *clock = &fsi->clock; |
764 | int is_porta = fsi_is_port_a(fsi); | 743 | int is_porta = fsi_is_port_a(fsi); |
@@ -829,8 +808,7 @@ static int fsi_clk_is_valid(struct fsi_priv *fsi) | |||
829 | } | 808 | } |
830 | 809 | ||
831 | static int fsi_clk_enable(struct device *dev, | 810 | static int fsi_clk_enable(struct device *dev, |
832 | struct fsi_priv *fsi, | 811 | struct fsi_priv *fsi) |
833 | unsigned long rate) | ||
834 | { | 812 | { |
835 | struct fsi_clk *clock = &fsi->clock; | 813 | struct fsi_clk *clock = &fsi->clock; |
836 | int ret = -EINVAL; | 814 | int ret = -EINVAL; |
@@ -839,7 +817,7 @@ static int fsi_clk_enable(struct device *dev, | |||
839 | return ret; | 817 | return ret; |
840 | 818 | ||
841 | if (0 == clock->count) { | 819 | if (0 == clock->count) { |
842 | ret = clock->set_rate(dev, fsi, rate); | 820 | ret = clock->set_rate(dev, fsi); |
843 | if (ret < 0) { | 821 | if (ret < 0) { |
844 | fsi_clk_invalid(fsi); | 822 | fsi_clk_invalid(fsi); |
845 | return ret; | 823 | return ret; |
@@ -946,11 +924,11 @@ static int fsi_clk_set_ackbpf(struct device *dev, | |||
946 | } | 924 | } |
947 | 925 | ||
948 | static int fsi_clk_set_rate_external(struct device *dev, | 926 | static int fsi_clk_set_rate_external(struct device *dev, |
949 | struct fsi_priv *fsi, | 927 | struct fsi_priv *fsi) |
950 | unsigned long rate) | ||
951 | { | 928 | { |
952 | struct clk *xck = fsi->clock.xck; | 929 | struct clk *xck = fsi->clock.xck; |
953 | struct clk *ick = fsi->clock.ick; | 930 | struct clk *ick = fsi->clock.ick; |
931 | unsigned long rate = fsi->clock.rate; | ||
954 | unsigned long xrate; | 932 | unsigned long xrate; |
955 | int ackmd, bpfmd; | 933 | int ackmd, bpfmd; |
956 | int ret = 0; | 934 | int ret = 0; |
@@ -978,11 +956,11 @@ static int fsi_clk_set_rate_external(struct device *dev, | |||
978 | } | 956 | } |
979 | 957 | ||
980 | static int fsi_clk_set_rate_cpg(struct device *dev, | 958 | static int fsi_clk_set_rate_cpg(struct device *dev, |
981 | struct fsi_priv *fsi, | 959 | struct fsi_priv *fsi) |
982 | unsigned long rate) | ||
983 | { | 960 | { |
984 | struct clk *ick = fsi->clock.ick; | 961 | struct clk *ick = fsi->clock.ick; |
985 | struct clk *div = fsi->clock.div; | 962 | struct clk *div = fsi->clock.div; |
963 | unsigned long rate = fsi->clock.rate; | ||
986 | unsigned long target = 0; /* 12288000 or 11289600 */ | 964 | unsigned long target = 0; /* 12288000 or 11289600 */ |
987 | unsigned long actual, cout; | 965 | unsigned long actual, cout; |
988 | unsigned long diff, min; | 966 | unsigned long diff, min; |
@@ -1063,85 +1041,6 @@ static int fsi_clk_set_rate_cpg(struct device *dev, | |||
1063 | return ret; | 1041 | return ret; |
1064 | } | 1042 | } |
1065 | 1043 | ||
1066 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | ||
1067 | long rate, int enable) | ||
1068 | { | ||
1069 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | ||
1070 | int ret; | ||
1071 | |||
1072 | /* | ||
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 | } | ||
1083 | |||
1084 | ret = set_rate(dev, rate, enable); | ||
1085 | if (ret < 0) /* error */ | ||
1086 | return ret; | ||
1087 | |||
1088 | if (!enable) | ||
1089 | return 0; | ||
1090 | |||
1091 | if (ret > 0) { | ||
1092 | u32 data = 0; | ||
1093 | |||
1094 | switch (ret & SH_FSI_ACKMD_MASK) { | ||
1095 | default: | ||
1096 | /* FALL THROUGH */ | ||
1097 | case SH_FSI_ACKMD_512: | ||
1098 | data |= (0x0 << 12); | ||
1099 | break; | ||
1100 | case SH_FSI_ACKMD_256: | ||
1101 | data |= (0x1 << 12); | ||
1102 | break; | ||
1103 | case SH_FSI_ACKMD_128: | ||
1104 | data |= (0x2 << 12); | ||
1105 | break; | ||
1106 | case SH_FSI_ACKMD_64: | ||
1107 | data |= (0x3 << 12); | ||
1108 | break; | ||
1109 | case SH_FSI_ACKMD_32: | ||
1110 | data |= (0x4 << 12); | ||
1111 | break; | ||
1112 | } | ||
1113 | |||
1114 | switch (ret & SH_FSI_BPFMD_MASK) { | ||
1115 | default: | ||
1116 | /* FALL THROUGH */ | ||
1117 | case SH_FSI_BPFMD_32: | ||
1118 | data |= (0x0 << 8); | ||
1119 | break; | ||
1120 | case SH_FSI_BPFMD_64: | ||
1121 | data |= (0x1 << 8); | ||
1122 | break; | ||
1123 | case SH_FSI_BPFMD_128: | ||
1124 | data |= (0x2 << 8); | ||
1125 | break; | ||
1126 | case SH_FSI_BPFMD_256: | ||
1127 | data |= (0x3 << 8); | ||
1128 | break; | ||
1129 | case SH_FSI_BPFMD_512: | ||
1130 | data |= (0x4 << 8); | ||
1131 | break; | ||
1132 | case SH_FSI_BPFMD_16: | ||
1133 | data |= (0x7 << 8); | ||
1134 | break; | ||
1135 | } | ||
1136 | |||
1137 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
1138 | udelay(10); | ||
1139 | ret = 0; | ||
1140 | } | ||
1141 | |||
1142 | return ret; | ||
1143 | } | ||
1144 | |||
1145 | /* | 1044 | /* |
1146 | * pio data transfer handler | 1045 | * pio data transfer handler |
1147 | */ | 1046 | */ |
@@ -1637,7 +1536,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1637 | struct fsi_stream *io, | 1536 | struct fsi_stream *io, |
1638 | struct device *dev) | 1537 | struct device *dev) |
1639 | { | 1538 | { |
1640 | u32 flags = fsi_get_info_flags(fsi); | ||
1641 | u32 data = 0; | 1539 | u32 data = 0; |
1642 | 1540 | ||
1643 | /* clock setting */ | 1541 | /* clock setting */ |
@@ -1654,19 +1552,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1654 | data |= (1 << 4); | 1552 | data |= (1 << 4); |
1655 | if (fsi_is_clk_master(fsi)) | 1553 | if (fsi_is_clk_master(fsi)) |
1656 | data <<= 8; | 1554 | data <<= 8; |
1657 | /* FIXME | ||
1658 | * | ||
1659 | * SH_FSI_xxx_INV style will be removed | ||
1660 | */ | ||
1661 | if (SH_FSI_LRM_INV & flags) | ||
1662 | data |= 1 << 12; | ||
1663 | if (SH_FSI_BRM_INV & flags) | ||
1664 | data |= 1 << 8; | ||
1665 | if (SH_FSI_LRS_INV & flags) | ||
1666 | data |= 1 << 4; | ||
1667 | if (SH_FSI_BRS_INV & flags) | ||
1668 | data |= 1 << 0; | ||
1669 | |||
1670 | fsi_reg_write(fsi, CKG2, data); | 1555 | fsi_reg_write(fsi, CKG2, data); |
1671 | 1556 | ||
1672 | /* spdif ? */ | 1557 | /* spdif ? */ |
@@ -1698,7 +1583,7 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
1698 | 1583 | ||
1699 | /* start master clock */ | 1584 | /* start master clock */ |
1700 | if (fsi_is_clk_master(fsi)) | 1585 | if (fsi_is_clk_master(fsi)) |
1701 | return fsi_set_master_clk(dev, fsi, fsi->rate, 1); | 1586 | return fsi_clk_enable(dev, fsi); |
1702 | 1587 | ||
1703 | return 0; | 1588 | return 0; |
1704 | } | 1589 | } |
@@ -1708,7 +1593,7 @@ static int fsi_hw_shutdown(struct fsi_priv *fsi, | |||
1708 | { | 1593 | { |
1709 | /* stop master clock */ | 1594 | /* stop master clock */ |
1710 | if (fsi_is_clk_master(fsi)) | 1595 | if (fsi_is_clk_master(fsi)) |
1711 | return fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1596 | return fsi_clk_disable(dev, fsi); |
1712 | 1597 | ||
1713 | return 0; | 1598 | return 0; |
1714 | } | 1599 | } |
@@ -1719,7 +1604,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1719 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1604 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1720 | 1605 | ||
1721 | fsi_clk_invalid(fsi); | 1606 | fsi_clk_invalid(fsi); |
1722 | fsi->rate = 0; | ||
1723 | 1607 | ||
1724 | return 0; | 1608 | return 0; |
1725 | } | 1609 | } |
@@ -1730,7 +1614,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | |||
1730 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1614 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1731 | 1615 | ||
1732 | fsi_clk_invalid(fsi); | 1616 | fsi_clk_invalid(fsi); |
1733 | fsi->rate = 0; | ||
1734 | } | 1617 | } |
1735 | 1618 | ||
1736 | static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | 1619 | static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, |
@@ -1795,7 +1678,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
1795 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 1678 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
1796 | { | 1679 | { |
1797 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 1680 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
1798 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); | ||
1799 | int ret; | 1681 | int ret; |
1800 | 1682 | ||
1801 | /* set master/slave audio interface */ | 1683 | /* set master/slave audio interface */ |
@@ -1831,14 +1713,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1831 | } | 1713 | } |
1832 | 1714 | ||
1833 | if (fsi_is_clk_master(fsi)) { | 1715 | 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) | 1716 | if (fsi->clk_cpg) |
1843 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, | 1717 | fsi_clk_init(dai->dev, fsi, 0, 1, 1, |
1844 | fsi_clk_set_rate_cpg); | 1718 | fsi_clk_set_rate_cpg); |
@@ -1862,10 +1736,8 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
1862 | { | 1736 | { |
1863 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1737 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1864 | 1738 | ||
1865 | if (fsi_is_clk_master(fsi)) { | 1739 | if (fsi_is_clk_master(fsi)) |
1866 | fsi->rate = params_rate(params); | 1740 | fsi_clk_valid(fsi, params_rate(params)); |
1867 | fsi_clk_valid(fsi, fsi->rate); | ||
1868 | } | ||
1869 | 1741 | ||
1870 | return 0; | 1742 | return 0; |
1871 | } | 1743 | } |
@@ -2017,6 +1889,33 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
2017 | /* | 1889 | /* |
2018 | * platform function | 1890 | * platform function |
2019 | */ | 1891 | */ |
1892 | static void fsi_of_parse(char *name, | ||
1893 | struct device_node *np, | ||
1894 | struct sh_fsi_port_info *info, | ||
1895 | struct device *dev) | ||
1896 | { | ||
1897 | int i; | ||
1898 | char prop[128]; | ||
1899 | unsigned long flags = 0; | ||
1900 | struct { | ||
1901 | char *name; | ||
1902 | unsigned int val; | ||
1903 | } of_parse_property[] = { | ||
1904 | { "spdif-connection", SH_FSI_FMT_SPDIF }, | ||
1905 | { "stream-mode-support", SH_FSI_ENABLE_STREAM_MODE }, | ||
1906 | { "use-internal-clock", SH_FSI_CLK_CPG }, | ||
1907 | }; | ||
1908 | |||
1909 | for (i = 0; i < ARRAY_SIZE(of_parse_property); i++) { | ||
1910 | sprintf(prop, "%s,%s", name, of_parse_property[i].name); | ||
1911 | if (of_get_property(np, prop, NULL)) | ||
1912 | flags |= of_parse_property[i].val; | ||
1913 | } | ||
1914 | info->flags = flags; | ||
1915 | |||
1916 | dev_dbg(dev, "%s flags : %lx\n", name, info->flags); | ||
1917 | } | ||
1918 | |||
2020 | static void fsi_port_info_init(struct fsi_priv *fsi, | 1919 | static void fsi_port_info_init(struct fsi_priv *fsi, |
2021 | struct sh_fsi_port_info *info) | 1920 | struct sh_fsi_port_info *info) |
2022 | { | 1921 | { |
@@ -2044,23 +1943,40 @@ static void fsi_handler_init(struct fsi_priv *fsi, | |||
2044 | } | 1943 | } |
2045 | } | 1944 | } |
2046 | 1945 | ||
1946 | static struct of_device_id fsi_of_match[]; | ||
2047 | static int fsi_probe(struct platform_device *pdev) | 1947 | static int fsi_probe(struct platform_device *pdev) |
2048 | { | 1948 | { |
2049 | struct fsi_master *master; | 1949 | struct fsi_master *master; |
2050 | const struct platform_device_id *id_entry; | 1950 | struct device_node *np = pdev->dev.of_node; |
2051 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; | 1951 | struct sh_fsi_platform_info info; |
2052 | struct sh_fsi_port_info nul_info, *pinfo; | 1952 | const struct fsi_core *core; |
2053 | struct fsi_priv *fsi; | 1953 | struct fsi_priv *fsi; |
2054 | struct resource *res; | 1954 | struct resource *res; |
2055 | unsigned int irq; | 1955 | unsigned int irq; |
2056 | int ret; | 1956 | int ret; |
2057 | 1957 | ||
2058 | nul_info.flags = 0; | 1958 | memset(&info, 0, sizeof(info)); |
2059 | nul_info.tx_id = 0; | 1959 | |
2060 | nul_info.rx_id = 0; | 1960 | core = NULL; |
1961 | if (np) { | ||
1962 | const struct of_device_id *of_id; | ||
2061 | 1963 | ||
2062 | id_entry = pdev->id_entry; | 1964 | of_id = of_match_device(fsi_of_match, &pdev->dev); |
2063 | if (!id_entry) { | 1965 | if (of_id) { |
1966 | core = of_id->data; | ||
1967 | fsi_of_parse("fsia", np, &info.port_a, &pdev->dev); | ||
1968 | fsi_of_parse("fsib", np, &info.port_b, &pdev->dev); | ||
1969 | } | ||
1970 | } else { | ||
1971 | const struct platform_device_id *id_entry = pdev->id_entry; | ||
1972 | if (id_entry) | ||
1973 | core = (struct fsi_core *)id_entry->driver_data; | ||
1974 | |||
1975 | if (pdev->dev.platform_data) | ||
1976 | memcpy(&info, pdev->dev.platform_data, sizeof(info)); | ||
1977 | } | ||
1978 | |||
1979 | if (!core) { | ||
2064 | dev_err(&pdev->dev, "unknown fsi device\n"); | 1980 | dev_err(&pdev->dev, "unknown fsi device\n"); |
2065 | return -ENODEV; | 1981 | return -ENODEV; |
2066 | } | 1982 | } |
@@ -2087,17 +2003,15 @@ static int fsi_probe(struct platform_device *pdev) | |||
2087 | 2003 | ||
2088 | /* master setting */ | 2004 | /* master setting */ |
2089 | master->irq = irq; | 2005 | master->irq = irq; |
2090 | master->core = (struct fsi_core *)id_entry->driver_data; | 2006 | master->core = core; |
2091 | spin_lock_init(&master->lock); | 2007 | spin_lock_init(&master->lock); |
2092 | 2008 | ||
2093 | /* FSI A setting */ | 2009 | /* FSI A setting */ |
2094 | pinfo = (info) ? &info->port_a : &nul_info; | ||
2095 | fsi = &master->fsia; | 2010 | fsi = &master->fsia; |
2096 | fsi->base = master->base; | 2011 | fsi->base = master->base; |
2097 | fsi->master = master; | 2012 | fsi->master = master; |
2098 | fsi->info = pinfo; | 2013 | fsi_port_info_init(fsi, &info.port_a); |
2099 | fsi_port_info_init(fsi, pinfo); | 2014 | fsi_handler_init(fsi, &info.port_a); |
2100 | fsi_handler_init(fsi, pinfo); | ||
2101 | ret = fsi_stream_probe(fsi, &pdev->dev); | 2015 | ret = fsi_stream_probe(fsi, &pdev->dev); |
2102 | if (ret < 0) { | 2016 | if (ret < 0) { |
2103 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 2017 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
@@ -2105,13 +2019,11 @@ static int fsi_probe(struct platform_device *pdev) | |||
2105 | } | 2019 | } |
2106 | 2020 | ||
2107 | /* FSI B setting */ | 2021 | /* FSI B setting */ |
2108 | pinfo = (info) ? &info->port_b : &nul_info; | ||
2109 | fsi = &master->fsib; | 2022 | fsi = &master->fsib; |
2110 | fsi->base = master->base + 0x40; | 2023 | fsi->base = master->base + 0x40; |
2111 | fsi->master = master; | 2024 | fsi->master = master; |
2112 | fsi->info = pinfo; | 2025 | fsi_port_info_init(fsi, &info.port_b); |
2113 | fsi_port_info_init(fsi, pinfo); | 2026 | fsi_handler_init(fsi, &info.port_b); |
2114 | fsi_handler_init(fsi, pinfo); | ||
2115 | ret = fsi_stream_probe(fsi, &pdev->dev); | 2027 | ret = fsi_stream_probe(fsi, &pdev->dev); |
2116 | if (ret < 0) { | 2028 | if (ret < 0) { |
2117 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 2029 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
@@ -2122,7 +2034,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
2122 | dev_set_drvdata(&pdev->dev, master); | 2034 | dev_set_drvdata(&pdev->dev, master); |
2123 | 2035 | ||
2124 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, | 2036 | ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, |
2125 | id_entry->name, master); | 2037 | dev_name(&pdev->dev), master); |
2126 | if (ret) { | 2038 | if (ret) { |
2127 | dev_err(&pdev->dev, "irq request err\n"); | 2039 | dev_err(&pdev->dev, "irq request err\n"); |
2128 | goto exit_fsib; | 2040 | goto exit_fsib; |
@@ -2248,6 +2160,13 @@ static struct fsi_core fsi2_core = { | |||
2248 | .b_mclk = B_MST_CTLR, | 2160 | .b_mclk = B_MST_CTLR, |
2249 | }; | 2161 | }; |
2250 | 2162 | ||
2163 | static struct of_device_id fsi_of_match[] = { | ||
2164 | { .compatible = "renesas,sh_fsi", .data = &fsi1_core}, | ||
2165 | { .compatible = "renesas,sh_fsi2", .data = &fsi2_core}, | ||
2166 | {}, | ||
2167 | }; | ||
2168 | MODULE_DEVICE_TABLE(of, fsi_of_match); | ||
2169 | |||
2251 | static struct platform_device_id fsi_id_table[] = { | 2170 | static struct platform_device_id fsi_id_table[] = { |
2252 | { "sh_fsi", (kernel_ulong_t)&fsi1_core }, | 2171 | { "sh_fsi", (kernel_ulong_t)&fsi1_core }, |
2253 | { "sh_fsi2", (kernel_ulong_t)&fsi2_core }, | 2172 | { "sh_fsi2", (kernel_ulong_t)&fsi2_core }, |
@@ -2259,6 +2178,7 @@ static struct platform_driver fsi_driver = { | |||
2259 | .driver = { | 2178 | .driver = { |
2260 | .name = "fsi-pcm-audio", | 2179 | .name = "fsi-pcm-audio", |
2261 | .pm = &fsi_pm_ops, | 2180 | .pm = &fsi_pm_ops, |
2181 | .of_match_table = fsi_of_match, | ||
2262 | }, | 2182 | }, |
2263 | .probe = fsi_probe, | 2183 | .probe = fsi_probe, |
2264 | .remove = fsi_remove, | 2184 | .remove = fsi_remove, |