diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-01-23 20:43:19 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-01-26 06:25:47 -0500 |
commit | f17c13ca52d5c5a6a164536244a6debb8cd17983 (patch) | |
tree | a3a9a1fd3a0ed7cf1bb49f6c8c8591826fa58940 | |
parent | d7c5762bc72ea4184c413166c063899dffae7385 (diff) |
ASoC: sh: fsi: modify selection method of I2S/PCM/SPDIF format
Current format selection of FSI-codecs depended on platform information for FSI,
and chip default settings for codecs. It is not understandable/formal method.
This patch modify FSI and FSI-codecs to use snd_soc_dai_set_fmt.
But FSI can use I2S/PCM and SPDIF format today.
It can be selected to I2S/PCM by snd_soc_dai_set_fmt, but can not select SPDIF.
So, this patch change FSI platform information to have DAI/SPDIF mode.
If platform selects DAI mode (default),
FSI-codecs can select I2S/PCM by snd_soc_dai_set_fmt,
and if it is SPDIF mode, FSI become SPDIF format.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | arch/arm/mach-shmobile/board-ag5evm.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 6 | ||||
-rw-r--r-- | arch/sh/boards/mach-ecovec24/setup.c | 4 | ||||
-rw-r--r-- | arch/sh/boards/mach-se/7724/setup.c | 4 | ||||
-rw-r--r-- | include/sound/sh_fsi.h | 70 | ||||
-rw-r--r-- | sound/soc/sh/fsi-ak4642.c | 3 | ||||
-rw-r--r-- | sound/soc/sh/fsi-da7210.c | 3 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 106 |
9 files changed, 84 insertions, 126 deletions
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 9ee55e0fbeb1..343362d02075 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
@@ -118,11 +118,6 @@ static struct platform_device keysc_device = { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | /* FSI A */ | 120 | /* FSI A */ |
121 | static struct sh_fsi_platform_info fsi_info = { | ||
122 | .porta_flags = SH_FSI_OFMT(I2S) | | ||
123 | SH_FSI_IFMT(I2S), | ||
124 | }; | ||
125 | |||
126 | static struct resource fsi_resources[] = { | 121 | static struct resource fsi_resources[] = { |
127 | [0] = { | 122 | [0] = { |
128 | .name = "FSI", | 123 | .name = "FSI", |
@@ -141,9 +136,6 @@ static struct platform_device fsi_device = { | |||
141 | .id = -1, | 136 | .id = -1, |
142 | .num_resources = ARRAY_SIZE(fsi_resources), | 137 | .num_resources = ARRAY_SIZE(fsi_resources), |
143 | .resource = fsi_resources, | 138 | .resource = fsi_resources, |
144 | .dev = { | ||
145 | .platform_data = &fsi_info, | ||
146 | }, | ||
147 | }; | 139 | }; |
148 | 140 | ||
149 | static struct resource sh_mmcif_resources[] = { | 141 | static struct resource sh_mmcif_resources[] = { |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 920ed81f1c61..17f528a76a1c 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -673,14 +673,12 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) | |||
673 | } | 673 | } |
674 | 674 | ||
675 | static struct sh_fsi_platform_info fsi_info = { | 675 | static struct sh_fsi_platform_info fsi_info = { |
676 | .porta_flags = SH_FSI_BRS_INV | | 676 | .porta_flags = SH_FSI_BRS_INV, |
677 | SH_FSI_OFMT(PCM) | | ||
678 | SH_FSI_IFMT(PCM), | ||
679 | 677 | ||
680 | .portb_flags = SH_FSI_BRS_INV | | 678 | .portb_flags = SH_FSI_BRS_INV | |
681 | SH_FSI_BRM_INV | | 679 | SH_FSI_BRM_INV | |
682 | SH_FSI_LRS_INV | | 680 | SH_FSI_LRS_INV | |
683 | SH_FSI_OFMT(SPDIF), | 681 | SH_FSI_FMT_SPDIF, |
684 | .set_rate = fsi_set_rate, | 682 | .set_rate = fsi_set_rate, |
685 | }; | 683 | }; |
686 | 684 | ||
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index aa4bcc347044..73b8c90b5072 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -614,14 +614,12 @@ fsi_set_rate_end: | |||
614 | } | 614 | } |
615 | 615 | ||
616 | static struct sh_fsi_platform_info fsi_info = { | 616 | static struct sh_fsi_platform_info fsi_info = { |
617 | .porta_flags = SH_FSI_BRS_INV | | 617 | .porta_flags = SH_FSI_BRS_INV, |
618 | SH_FSI_OFMT(PCM) | | ||
619 | SH_FSI_IFMT(PCM), | ||
620 | 618 | ||
621 | .portb_flags = SH_FSI_BRS_INV | | 619 | .portb_flags = SH_FSI_BRS_INV | |
622 | SH_FSI_BRM_INV | | 620 | SH_FSI_BRM_INV | |
623 | SH_FSI_LRS_INV | | 621 | SH_FSI_LRS_INV | |
624 | SH_FSI_OFMT(SPDIF), | 622 | SH_FSI_FMT_SPDIF, |
625 | 623 | ||
626 | .set_rate = fsi_set_rate, | 624 | .set_rate = fsi_set_rate, |
627 | }; | 625 | }; |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 037416f346cf..b96b79b970b2 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -723,9 +723,7 @@ static struct platform_device camera_devices[] = { | |||
723 | 723 | ||
724 | /* FSI */ | 724 | /* FSI */ |
725 | static struct sh_fsi_platform_info fsi_info = { | 725 | static struct sh_fsi_platform_info fsi_info = { |
726 | .portb_flags = SH_FSI_BRS_INV | | 726 | .portb_flags = SH_FSI_BRS_INV, |
727 | SH_FSI_OFMT(I2S) | | ||
728 | SH_FSI_IFMT(I2S), | ||
729 | }; | 727 | }; |
730 | 728 | ||
731 | static struct resource fsi_resources[] = { | 729 | static struct resource fsi_resources[] = { |
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index b4aef05dd8b5..c8bcf6a19b55 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -286,9 +286,7 @@ static struct platform_device ceu1_device = { | |||
286 | /* FSI */ | 286 | /* FSI */ |
287 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ | 287 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ |
288 | static struct sh_fsi_platform_info fsi_info = { | 288 | static struct sh_fsi_platform_info fsi_info = { |
289 | .porta_flags = SH_FSI_BRS_INV | | 289 | .porta_flags = SH_FSI_BRS_INV, |
290 | SH_FSI_OFMT(PCM) | | ||
291 | SH_FSI_IFMT(PCM), | ||
292 | }; | 290 | }; |
293 | 291 | ||
294 | static struct resource fsi_resources[] = { | 292 | static struct resource fsi_resources[] = { |
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 18e43279f70f..9a155f9d0a12 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h | |||
@@ -15,61 +15,29 @@ | |||
15 | #define FSI_PORT_A 0 | 15 | #define FSI_PORT_A 0 |
16 | #define FSI_PORT_B 1 | 16 | #define FSI_PORT_B 1 |
17 | 17 | ||
18 | /* flags format | ||
19 | |||
20 | * 0xABC0EEFF | ||
21 | * | ||
22 | * A: channel size for TDM (input) | ||
23 | * B: channel size for TDM (ooutput) | ||
24 | * C: inversion | ||
25 | * E: input format | ||
26 | * F: output format | ||
27 | */ | ||
28 | |||
29 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
30 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
31 | 20 | ||
32 | /* TDM channel */ | 21 | /* |
33 | #define SH_FSI_SET_CH_I(x) ((x & 0xF) << 28) | 22 | * flags format |
34 | #define SH_FSI_SET_CH_O(x) ((x & 0xF) << 24) | 23 | * |
35 | 24 | * 0x000000BA | |
36 | #define SH_FSI_CH_IMASK 0xF0000000 | 25 | * |
37 | #define SH_FSI_CH_OMASK 0x0F000000 | 26 | * A: inversion |
38 | #define SH_FSI_GET_CH_I(x) ((x & SH_FSI_CH_IMASK) >> 28) | 27 | * B: format mode |
39 | #define SH_FSI_GET_CH_O(x) ((x & SH_FSI_CH_OMASK) >> 24) | 28 | */ |
40 | |||
41 | /* clock inversion */ | ||
42 | #define SH_FSI_INVERSION_MASK 0x00F00000 | ||
43 | #define SH_FSI_LRM_INV (1 << 20) | ||
44 | #define SH_FSI_BRM_INV (1 << 21) | ||
45 | #define SH_FSI_LRS_INV (1 << 22) | ||
46 | #define SH_FSI_BRS_INV (1 << 23) | ||
47 | |||
48 | /* DI format */ | ||
49 | #define SH_FSI_FMT_MASK 0x000000FF | ||
50 | #define SH_FSI_IFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 8) | ||
51 | #define SH_FSI_OFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 0) | ||
52 | #define SH_FSI_GET_IFMT(x) ((x >> 8) & SH_FSI_FMT_MASK) | ||
53 | #define SH_FSI_GET_OFMT(x) ((x >> 0) & SH_FSI_FMT_MASK) | ||
54 | |||
55 | #define SH_FSI_FMT_MONO 0 | ||
56 | #define SH_FSI_FMT_MONO_DELAY 1 | ||
57 | #define SH_FSI_FMT_PCM 2 | ||
58 | #define SH_FSI_FMT_I2S 3 | ||
59 | #define SH_FSI_FMT_TDM 4 | ||
60 | #define SH_FSI_FMT_TDM_DELAY 5 | ||
61 | #define SH_FSI_FMT_SPDIF 6 | ||
62 | |||
63 | |||
64 | #define SH_FSI_IFMT_TDM_CH(x) \ | ||
65 | (SH_FSI_IFMT(TDM) | SH_FSI_SET_CH_I(x)) | ||
66 | #define SH_FSI_IFMT_TDM_DELAY_CH(x) \ | ||
67 | (SH_FSI_IFMT(TDM_DELAY) | SH_FSI_SET_CH_I(x)) | ||
68 | 29 | ||
69 | #define SH_FSI_OFMT_TDM_CH(x) \ | 30 | /* A: clock inversion */ |
70 | (SH_FSI_OFMT(TDM) | SH_FSI_SET_CH_O(x)) | 31 | #define SH_FSI_INVERSION_MASK 0x0000000F |
71 | #define SH_FSI_OFMT_TDM_DELAY_CH(x) \ | 32 | #define SH_FSI_LRM_INV (1 << 0) |
72 | (SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x)) | 33 | #define SH_FSI_BRM_INV (1 << 1) |
34 | #define SH_FSI_LRS_INV (1 << 2) | ||
35 | #define SH_FSI_BRS_INV (1 << 3) | ||
36 | |||
37 | /* B: format mode */ | ||
38 | #define SH_FSI_FMT_MASK 0x000000F0 | ||
39 | #define SH_FSI_FMT_DAI (0 << 4) | ||
40 | #define SH_FSI_FMT_SPDIF (1 << 4) | ||
73 | 41 | ||
74 | 42 | ||
75 | /* | 43 | /* |
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index ce058c749e6a..d6f4703b3c07 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c | |||
@@ -36,7 +36,8 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
36 | if (ret < 0) | 36 | if (ret < 0) |
37 | return ret; | 37 | return ret; |
38 | 38 | ||
39 | ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBS_CFS); | 39 | ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J | |
40 | SND_SOC_DAIFMT_CBS_CFS); | ||
40 | 41 | ||
41 | return ret; | 42 | return ret; |
42 | } | 43 | } |
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c index 9b24ed466ab1..dbafd7ac5590 100644 --- a/sound/soc/sh/fsi-da7210.c +++ b/sound/soc/sh/fsi-da7210.c | |||
@@ -25,7 +25,8 @@ static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) | |||
25 | if (ret < 0) | 25 | if (ret < 0) |
26 | return ret; | 26 | return ret; |
27 | 27 | ||
28 | ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBS_CFS); | 28 | ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S | |
29 | SND_SOC_DAIFMT_CBS_CFS); | ||
29 | 30 | ||
30 | return ret; | 31 | return ret; |
31 | } | 32 | } |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3c53693d7266..0c9997e2d8c0 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -757,9 +757,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
757 | struct snd_soc_dai *dai) | 757 | struct snd_soc_dai *dai) |
758 | { | 758 | { |
759 | struct fsi_priv *fsi = fsi_get_priv(substream); | 759 | struct fsi_priv *fsi = fsi_get_priv(substream); |
760 | struct fsi_master *master = fsi_get_master(fsi); | ||
761 | u32 flags = fsi_get_info_flags(fsi); | 760 | u32 flags = fsi_get_info_flags(fsi); |
762 | u32 fmt; | ||
763 | u32 data; | 761 | u32 data; |
764 | int is_play = fsi_is_play(substream); | 762 | int is_play = fsi_is_play(substream); |
765 | 763 | ||
@@ -779,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
779 | 777 | ||
780 | fsi_reg_write(fsi, CKG2, data); | 778 | fsi_reg_write(fsi, CKG2, data); |
781 | 779 | ||
782 | /* do fmt, di fmt */ | ||
783 | data = 0; | ||
784 | fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); | ||
785 | switch (fmt) { | ||
786 | case SH_FSI_FMT_MONO: | ||
787 | data = CR_MONO; | ||
788 | fsi->chan_num = 1; | ||
789 | break; | ||
790 | case SH_FSI_FMT_MONO_DELAY: | ||
791 | data = CR_MONO_D; | ||
792 | fsi->chan_num = 1; | ||
793 | break; | ||
794 | case SH_FSI_FMT_PCM: | ||
795 | data = CR_PCM; | ||
796 | fsi->chan_num = 2; | ||
797 | break; | ||
798 | case SH_FSI_FMT_I2S: | ||
799 | data = CR_I2S; | ||
800 | fsi->chan_num = 2; | ||
801 | break; | ||
802 | case SH_FSI_FMT_TDM: | ||
803 | fsi->chan_num = is_play ? | ||
804 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); | ||
805 | data = CR_TDM | (fsi->chan_num - 1); | ||
806 | break; | ||
807 | case SH_FSI_FMT_TDM_DELAY: | ||
808 | fsi->chan_num = is_play ? | ||
809 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); | ||
810 | data = CR_TDM_D | (fsi->chan_num - 1); | ||
811 | break; | ||
812 | case SH_FSI_FMT_SPDIF: | ||
813 | if (master->core->ver < 2) { | ||
814 | dev_err(dai->dev, "This FSI can not use SPDIF\n"); | ||
815 | return -EINVAL; | ||
816 | } | ||
817 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; | ||
818 | fsi->chan_num = 2; | ||
819 | fsi_spdif_clk_ctrl(fsi, 1); | ||
820 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
821 | break; | ||
822 | default: | ||
823 | dev_err(dai->dev, "unknown format.\n"); | ||
824 | return -EINVAL; | ||
825 | } | ||
826 | is_play ? | ||
827 | fsi_reg_write(fsi, DO_FMT, data) : | ||
828 | fsi_reg_write(fsi, DI_FMT, data); | ||
829 | |||
830 | /* irq clear */ | 780 | /* irq clear */ |
831 | fsi_irq_disable(fsi, is_play); | 781 | fsi_irq_disable(fsi, is_play); |
832 | fsi_irq_clear_status(fsi); | 782 | fsi_irq_clear_status(fsi); |
@@ -881,9 +831,52 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
881 | return ret; | 831 | return ret; |
882 | } | 832 | } |
883 | 833 | ||
834 | static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) | ||
835 | { | ||
836 | u32 data = 0; | ||
837 | |||
838 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
839 | case SND_SOC_DAIFMT_I2S: | ||
840 | data = CR_I2S; | ||
841 | fsi->chan_num = 2; | ||
842 | break; | ||
843 | case SND_SOC_DAIFMT_LEFT_J: | ||
844 | data = CR_PCM; | ||
845 | fsi->chan_num = 2; | ||
846 | break; | ||
847 | default: | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | |||
851 | fsi_reg_write(fsi, DO_FMT, data); | ||
852 | fsi_reg_write(fsi, DI_FMT, data); | ||
853 | |||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | ||
858 | { | ||
859 | struct fsi_master *master = fsi_get_master(fsi); | ||
860 | u32 data = 0; | ||
861 | |||
862 | if (master->core->ver < 2) | ||
863 | return -EINVAL; | ||
864 | |||
865 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; | ||
866 | fsi->chan_num = 2; | ||
867 | fsi_spdif_clk_ctrl(fsi, 1); | ||
868 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
869 | |||
870 | fsi_reg_write(fsi, DO_FMT, data); | ||
871 | fsi_reg_write(fsi, DI_FMT, data); | ||
872 | |||
873 | return 0; | ||
874 | } | ||
875 | |||
884 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 876 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
885 | { | 877 | { |
886 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 878 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
879 | u32 flags = fsi_get_info_flags(fsi); | ||
887 | u32 data = 0; | 880 | u32 data = 0; |
888 | int ret; | 881 | int ret; |
889 | 882 | ||
@@ -901,7 +894,18 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
901 | goto set_fmt_exit; | 894 | goto set_fmt_exit; |
902 | } | 895 | } |
903 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); | 896 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); |
904 | ret = 0; | 897 | |
898 | /* set format */ | ||
899 | switch (flags & SH_FSI_FMT_MASK) { | ||
900 | case SH_FSI_FMT_DAI: | ||
901 | ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
902 | break; | ||
903 | case SH_FSI_FMT_SPDIF: | ||
904 | ret = fsi_set_fmt_spdif(fsi); | ||
905 | break; | ||
906 | default: | ||
907 | ret = -EINVAL; | ||
908 | } | ||
905 | 909 | ||
906 | set_fmt_exit: | 910 | set_fmt_exit: |
907 | pm_runtime_put_sync(dai->dev); | 911 | pm_runtime_put_sync(dai->dev); |