Commit f17c13ca52d5c5a6a164536244a6debb8cd17983

Authored by Kuninori Morimoto
Committed by Mark Brown
1 parent d7c5762bc7

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
... ... @@ -36,7 +36,8 @@
36 36 if (ret < 0)
37 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 42 return ret;
42 43 }
sound/soc/sh/fsi-da7210.c
... ... @@ -25,7 +25,8 @@
25 25 if (ret < 0)
26 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 31 return ret;
31 32 }
... ... @@ -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);