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 /sound/soc/sh | |
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>
Diffstat (limited to 'sound/soc/sh')
-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 |
3 files changed, 59 insertions, 53 deletions
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); |