Commit f17c13ca52d5c5a6a164536244a6debb8cd17983
Committed by
Mark Brown
1 parent
d7c5762bc7
Exists in
master
and in
7 other branches
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>
Showing 9 changed files with 84 additions and 126 deletions Side-by-side Diff
arch/arm/mach-shmobile/board-ag5evm.c
... | ... | @@ -118,11 +118,6 @@ |
118 | 118 | }; |
119 | 119 | |
120 | 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 | 121 | static struct resource fsi_resources[] = { |
127 | 122 | [0] = { |
128 | 123 | .name = "FSI", |
... | ... | @@ -141,9 +136,6 @@ |
141 | 136 | .id = -1, |
142 | 137 | .num_resources = ARRAY_SIZE(fsi_resources), |
143 | 138 | .resource = fsi_resources, |
144 | - .dev = { | |
145 | - .platform_data = &fsi_info, | |
146 | - }, | |
147 | 139 | }; |
148 | 140 | |
149 | 141 | static struct resource sh_mmcif_resources[] = { |
arch/arm/mach-shmobile/board-ap4evb.c
... | ... | @@ -673,14 +673,12 @@ |
673 | 673 | } |
674 | 674 | |
675 | 675 | static struct sh_fsi_platform_info fsi_info = { |
676 | - .porta_flags = SH_FSI_BRS_INV | | |
677 | - SH_FSI_OFMT(PCM) | | |
678 | - SH_FSI_IFMT(PCM), | |
676 | + .porta_flags = SH_FSI_BRS_INV, | |
679 | 677 | |
680 | 678 | .portb_flags = SH_FSI_BRS_INV | |
681 | 679 | SH_FSI_BRM_INV | |
682 | 680 | SH_FSI_LRS_INV | |
683 | - SH_FSI_OFMT(SPDIF), | |
681 | + SH_FSI_FMT_SPDIF, | |
684 | 682 | .set_rate = fsi_set_rate, |
685 | 683 | }; |
686 | 684 |
arch/arm/mach-shmobile/board-mackerel.c
... | ... | @@ -614,14 +614,12 @@ |
614 | 614 | } |
615 | 615 | |
616 | 616 | static struct sh_fsi_platform_info fsi_info = { |
617 | - .porta_flags = SH_FSI_BRS_INV | | |
618 | - SH_FSI_OFMT(PCM) | | |
619 | - SH_FSI_IFMT(PCM), | |
617 | + .porta_flags = SH_FSI_BRS_INV, | |
620 | 618 | |
621 | 619 | .portb_flags = SH_FSI_BRS_INV | |
622 | 620 | SH_FSI_BRM_INV | |
623 | 621 | SH_FSI_LRS_INV | |
624 | - SH_FSI_OFMT(SPDIF), | |
622 | + SH_FSI_FMT_SPDIF, | |
625 | 623 | |
626 | 624 | .set_rate = fsi_set_rate, |
627 | 625 | }; |
arch/sh/boards/mach-ecovec24/setup.c
... | ... | @@ -723,9 +723,7 @@ |
723 | 723 | |
724 | 724 | /* FSI */ |
725 | 725 | static struct sh_fsi_platform_info fsi_info = { |
726 | - .portb_flags = SH_FSI_BRS_INV | | |
727 | - SH_FSI_OFMT(I2S) | | |
728 | - SH_FSI_IFMT(I2S), | |
726 | + .portb_flags = SH_FSI_BRS_INV, | |
729 | 727 | }; |
730 | 728 | |
731 | 729 | static struct resource fsi_resources[] = { |
arch/sh/boards/mach-se/7724/setup.c
... | ... | @@ -286,9 +286,7 @@ |
286 | 286 | /* FSI */ |
287 | 287 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ |
288 | 288 | static struct sh_fsi_platform_info fsi_info = { |
289 | - .porta_flags = SH_FSI_BRS_INV | | |
290 | - SH_FSI_OFMT(PCM) | | |
291 | - SH_FSI_IFMT(PCM), | |
289 | + .porta_flags = SH_FSI_BRS_INV, | |
292 | 290 | }; |
293 | 291 | |
294 | 292 | static struct resource fsi_resources[] = { |
include/sound/sh_fsi.h
... | ... | @@ -15,61 +15,29 @@ |
15 | 15 | #define FSI_PORT_A 0 |
16 | 16 | #define FSI_PORT_B 1 |
17 | 17 | |
18 | -/* flags format | |
18 | +#include <linux/clk.h> | |
19 | +#include <sound/soc.h> | |
19 | 20 | |
20 | - * 0xABC0EEFF | |
21 | +/* | |
22 | + * flags format | |
21 | 23 | * |
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 | |
24 | + * 0x000000BA | |
25 | + * | |
26 | + * A: inversion | |
27 | + * B: format mode | |
27 | 28 | */ |
28 | 29 | |
29 | -#include <linux/clk.h> | |
30 | -#include <sound/soc.h> | |
30 | +/* A: clock inversion */ | |
31 | +#define SH_FSI_INVERSION_MASK 0x0000000F | |
32 | +#define SH_FSI_LRM_INV (1 << 0) | |
33 | +#define SH_FSI_BRM_INV (1 << 1) | |
34 | +#define SH_FSI_LRS_INV (1 << 2) | |
35 | +#define SH_FSI_BRS_INV (1 << 3) | |
31 | 36 | |
32 | -/* TDM channel */ | |
33 | -#define SH_FSI_SET_CH_I(x) ((x & 0xF) << 28) | |
34 | -#define SH_FSI_SET_CH_O(x) ((x & 0xF) << 24) | |
35 | - | |
36 | -#define SH_FSI_CH_IMASK 0xF0000000 | |
37 | -#define SH_FSI_CH_OMASK 0x0F000000 | |
38 | -#define SH_FSI_GET_CH_I(x) ((x & SH_FSI_CH_IMASK) >> 28) | |
39 | -#define SH_FSI_GET_CH_O(x) ((x & SH_FSI_CH_OMASK) >> 24) | |
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 | - | |
69 | -#define SH_FSI_OFMT_TDM_CH(x) \ | |
70 | - (SH_FSI_OFMT(TDM) | SH_FSI_SET_CH_O(x)) | |
71 | -#define SH_FSI_OFMT_TDM_DELAY_CH(x) \ | |
72 | - (SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x)) | |
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 | /* |
sound/soc/sh/fsi-ak4642.c
sound/soc/sh/fsi-da7210.c
sound/soc/sh/fsi.c
... | ... | @@ -757,9 +757,7 @@ |
757 | 757 | struct snd_soc_dai *dai) |
758 | 758 | { |
759 | 759 | struct fsi_priv *fsi = fsi_get_priv(substream); |
760 | - struct fsi_master *master = fsi_get_master(fsi); | |
761 | 760 | u32 flags = fsi_get_info_flags(fsi); |
762 | - u32 fmt; | |
763 | 761 | u32 data; |
764 | 762 | int is_play = fsi_is_play(substream); |
765 | 763 | |
... | ... | @@ -779,54 +777,6 @@ |
779 | 777 | |
780 | 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 | 780 | /* irq clear */ |
831 | 781 | fsi_irq_disable(fsi, is_play); |
832 | 782 | fsi_irq_clear_status(fsi); |
833 | 783 | |
... | ... | @@ -881,9 +831,52 @@ |
881 | 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 | 876 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
885 | 877 | { |
886 | 878 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
879 | + u32 flags = fsi_get_info_flags(fsi); | |
887 | 880 | u32 data = 0; |
888 | 881 | int ret; |
889 | 882 | |
... | ... | @@ -901,7 +894,18 @@ |
901 | 894 | goto set_fmt_exit; |
902 | 895 | } |
903 | 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 | 910 | set_fmt_exit: |
907 | 911 | pm_runtime_put_sync(dai->dev); |