mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
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>
This commit is contained in:
parent
d7c5762bc7
commit
f17c13ca52
@ -118,11 +118,6 @@ static struct platform_device keysc_device = {
|
||||
};
|
||||
|
||||
/* FSI A */
|
||||
static struct sh_fsi_platform_info fsi_info = {
|
||||
.porta_flags = SH_FSI_OFMT(I2S) |
|
||||
SH_FSI_IFMT(I2S),
|
||||
};
|
||||
|
||||
static struct resource fsi_resources[] = {
|
||||
[0] = {
|
||||
.name = "FSI",
|
||||
@ -141,9 +136,6 @@ static struct platform_device fsi_device = {
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(fsi_resources),
|
||||
.resource = fsi_resources,
|
||||
.dev = {
|
||||
.platform_data = &fsi_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource sh_mmcif_resources[] = {
|
||||
|
@ -673,14 +673,12 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
|
||||
}
|
||||
|
||||
static struct sh_fsi_platform_info fsi_info = {
|
||||
.porta_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_OFMT(PCM) |
|
||||
SH_FSI_IFMT(PCM),
|
||||
.porta_flags = SH_FSI_BRS_INV,
|
||||
|
||||
.portb_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_BRM_INV |
|
||||
SH_FSI_LRS_INV |
|
||||
SH_FSI_OFMT(SPDIF),
|
||||
SH_FSI_FMT_SPDIF,
|
||||
.set_rate = fsi_set_rate,
|
||||
};
|
||||
|
||||
|
@ -614,14 +614,12 @@ fsi_set_rate_end:
|
||||
}
|
||||
|
||||
static struct sh_fsi_platform_info fsi_info = {
|
||||
.porta_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_OFMT(PCM) |
|
||||
SH_FSI_IFMT(PCM),
|
||||
.porta_flags = SH_FSI_BRS_INV,
|
||||
|
||||
.portb_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_BRM_INV |
|
||||
SH_FSI_LRS_INV |
|
||||
SH_FSI_OFMT(SPDIF),
|
||||
SH_FSI_FMT_SPDIF,
|
||||
|
||||
.set_rate = fsi_set_rate,
|
||||
};
|
||||
|
@ -723,9 +723,7 @@ static struct platform_device camera_devices[] = {
|
||||
|
||||
/* FSI */
|
||||
static struct sh_fsi_platform_info fsi_info = {
|
||||
.portb_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_OFMT(I2S) |
|
||||
SH_FSI_IFMT(I2S),
|
||||
.portb_flags = SH_FSI_BRS_INV,
|
||||
};
|
||||
|
||||
static struct resource fsi_resources[] = {
|
||||
|
@ -286,9 +286,7 @@ static struct platform_device ceu1_device = {
|
||||
/* FSI */
|
||||
/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
|
||||
static struct sh_fsi_platform_info fsi_info = {
|
||||
.porta_flags = SH_FSI_BRS_INV |
|
||||
SH_FSI_OFMT(PCM) |
|
||||
SH_FSI_IFMT(PCM),
|
||||
.porta_flags = SH_FSI_BRS_INV,
|
||||
};
|
||||
|
||||
static struct resource fsi_resources[] = {
|
||||
|
@ -15,61 +15,29 @@
|
||||
#define FSI_PORT_A 0
|
||||
#define FSI_PORT_B 1
|
||||
|
||||
/* flags format
|
||||
|
||||
* 0xABC0EEFF
|
||||
*
|
||||
* A: channel size for TDM (input)
|
||||
* B: channel size for TDM (ooutput)
|
||||
* C: inversion
|
||||
* E: input format
|
||||
* F: output format
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
/* TDM channel */
|
||||
#define SH_FSI_SET_CH_I(x) ((x & 0xF) << 28)
|
||||
#define SH_FSI_SET_CH_O(x) ((x & 0xF) << 24)
|
||||
/*
|
||||
* flags format
|
||||
*
|
||||
* 0x000000BA
|
||||
*
|
||||
* A: inversion
|
||||
* B: format mode
|
||||
*/
|
||||
|
||||
#define SH_FSI_CH_IMASK 0xF0000000
|
||||
#define SH_FSI_CH_OMASK 0x0F000000
|
||||
#define SH_FSI_GET_CH_I(x) ((x & SH_FSI_CH_IMASK) >> 28)
|
||||
#define SH_FSI_GET_CH_O(x) ((x & SH_FSI_CH_OMASK) >> 24)
|
||||
/* A: clock inversion */
|
||||
#define SH_FSI_INVERSION_MASK 0x0000000F
|
||||
#define SH_FSI_LRM_INV (1 << 0)
|
||||
#define SH_FSI_BRM_INV (1 << 1)
|
||||
#define SH_FSI_LRS_INV (1 << 2)
|
||||
#define SH_FSI_BRS_INV (1 << 3)
|
||||
|
||||
/* clock inversion */
|
||||
#define SH_FSI_INVERSION_MASK 0x00F00000
|
||||
#define SH_FSI_LRM_INV (1 << 20)
|
||||
#define SH_FSI_BRM_INV (1 << 21)
|
||||
#define SH_FSI_LRS_INV (1 << 22)
|
||||
#define SH_FSI_BRS_INV (1 << 23)
|
||||
|
||||
/* DI format */
|
||||
#define SH_FSI_FMT_MASK 0x000000FF
|
||||
#define SH_FSI_IFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 8)
|
||||
#define SH_FSI_OFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 0)
|
||||
#define SH_FSI_GET_IFMT(x) ((x >> 8) & SH_FSI_FMT_MASK)
|
||||
#define SH_FSI_GET_OFMT(x) ((x >> 0) & SH_FSI_FMT_MASK)
|
||||
|
||||
#define SH_FSI_FMT_MONO 0
|
||||
#define SH_FSI_FMT_MONO_DELAY 1
|
||||
#define SH_FSI_FMT_PCM 2
|
||||
#define SH_FSI_FMT_I2S 3
|
||||
#define SH_FSI_FMT_TDM 4
|
||||
#define SH_FSI_FMT_TDM_DELAY 5
|
||||
#define SH_FSI_FMT_SPDIF 6
|
||||
|
||||
|
||||
#define SH_FSI_IFMT_TDM_CH(x) \
|
||||
(SH_FSI_IFMT(TDM) | SH_FSI_SET_CH_I(x))
|
||||
#define SH_FSI_IFMT_TDM_DELAY_CH(x) \
|
||||
(SH_FSI_IFMT(TDM_DELAY) | SH_FSI_SET_CH_I(x))
|
||||
|
||||
#define SH_FSI_OFMT_TDM_CH(x) \
|
||||
(SH_FSI_OFMT(TDM) | SH_FSI_SET_CH_O(x))
|
||||
#define SH_FSI_OFMT_TDM_DELAY_CH(x) \
|
||||
(SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x))
|
||||
/* B: format mode */
|
||||
#define SH_FSI_FMT_MASK 0x000000F0
|
||||
#define SH_FSI_FMT_DAI (0 << 4)
|
||||
#define SH_FSI_FMT_SPDIF (1 << 4)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,8 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBS_CFS);
|
||||
ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
|
||||
SND_SOC_DAIFMT_CBS_CFS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBS_CFS);
|
||||
ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_CBS_CFS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -757,9 +757,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct fsi_priv *fsi = fsi_get_priv(substream);
|
||||
struct fsi_master *master = fsi_get_master(fsi);
|
||||
u32 flags = fsi_get_info_flags(fsi);
|
||||
u32 fmt;
|
||||
u32 data;
|
||||
int is_play = fsi_is_play(substream);
|
||||
|
||||
@ -779,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
|
||||
|
||||
fsi_reg_write(fsi, CKG2, data);
|
||||
|
||||
/* do fmt, di fmt */
|
||||
data = 0;
|
||||
fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
|
||||
switch (fmt) {
|
||||
case SH_FSI_FMT_MONO:
|
||||
data = CR_MONO;
|
||||
fsi->chan_num = 1;
|
||||
break;
|
||||
case SH_FSI_FMT_MONO_DELAY:
|
||||
data = CR_MONO_D;
|
||||
fsi->chan_num = 1;
|
||||
break;
|
||||
case SH_FSI_FMT_PCM:
|
||||
data = CR_PCM;
|
||||
fsi->chan_num = 2;
|
||||
break;
|
||||
case SH_FSI_FMT_I2S:
|
||||
data = CR_I2S;
|
||||
fsi->chan_num = 2;
|
||||
break;
|
||||
case SH_FSI_FMT_TDM:
|
||||
fsi->chan_num = is_play ?
|
||||
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
|
||||
data = CR_TDM | (fsi->chan_num - 1);
|
||||
break;
|
||||
case SH_FSI_FMT_TDM_DELAY:
|
||||
fsi->chan_num = is_play ?
|
||||
SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
|
||||
data = CR_TDM_D | (fsi->chan_num - 1);
|
||||
break;
|
||||
case SH_FSI_FMT_SPDIF:
|
||||
if (master->core->ver < 2) {
|
||||
dev_err(dai->dev, "This FSI can not use SPDIF\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
|
||||
fsi->chan_num = 2;
|
||||
fsi_spdif_clk_ctrl(fsi, 1);
|
||||
fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "unknown format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
is_play ?
|
||||
fsi_reg_write(fsi, DO_FMT, data) :
|
||||
fsi_reg_write(fsi, DI_FMT, data);
|
||||
|
||||
/* irq clear */
|
||||
fsi_irq_disable(fsi, is_play);
|
||||
fsi_irq_clear_status(fsi);
|
||||
@ -881,9 +831,52 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
|
||||
{
|
||||
u32 data = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
data = CR_I2S;
|
||||
fsi->chan_num = 2;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
data = CR_PCM;
|
||||
fsi->chan_num = 2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fsi_reg_write(fsi, DO_FMT, data);
|
||||
fsi_reg_write(fsi, DI_FMT, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
|
||||
{
|
||||
struct fsi_master *master = fsi_get_master(fsi);
|
||||
u32 data = 0;
|
||||
|
||||
if (master->core->ver < 2)
|
||||
return -EINVAL;
|
||||
|
||||
data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
|
||||
fsi->chan_num = 2;
|
||||
fsi_spdif_clk_ctrl(fsi, 1);
|
||||
fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
|
||||
|
||||
fsi_reg_write(fsi, DO_FMT, data);
|
||||
fsi_reg_write(fsi, DI_FMT, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
|
||||
u32 flags = fsi_get_info_flags(fsi);
|
||||
u32 data = 0;
|
||||
int ret;
|
||||
|
||||
@ -901,7 +894,18 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
goto set_fmt_exit;
|
||||
}
|
||||
fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
|
||||
ret = 0;
|
||||
|
||||
/* set format */
|
||||
switch (flags & SH_FSI_FMT_MASK) {
|
||||
case SH_FSI_FMT_DAI:
|
||||
ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
|
||||
break;
|
||||
case SH_FSI_FMT_SPDIF:
|
||||
ret = fsi_set_fmt_spdif(fsi);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
set_fmt_exit:
|
||||
pm_runtime_put_sync(dai->dev);
|
||||
|
Loading…
Reference in New Issue
Block a user