[alsa-devel] [PATCH 0/6] ASoC: fsi: independent from platform data pointer
Hi Mark
These patches modify FSI driver to be independent from platform data pointer. These are prepare for device tree support for FSI driver.
For that purpose, last patch adds SND_SOC_DAIFMT_INV_xxx type settings to FSI, but old type setting is still supported. Old type setting will be removed on next kernel.
These are based on mark/topic/fsi branch
Kuninori Morimoto (6): ASoC: fsi: tidyup FSIA/B settings ASoC: fsi: tidyup sh_fsi_platform_info pointer ASoC: fsi: SPDIF format become independent from platform flags ASoC: fsi: master clock selection become independent from platform flags ASoC: fsi: stream mode become independent from platform flags ASoC: fsi: add SND_SOC_DAIFMT_INV_xxx support
include/sound/sh_fsi.h | 4 +- sound/soc/sh/fsi.c | 125 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 39 deletions(-)
Best regards --- Kuninori Morimoto
This patch tidyup to use fsi pointer for FSIA/B settings
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/fsi.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index bdaca35..913916a 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -2009,6 +2009,7 @@ static int fsi_probe(struct platform_device *pdev) struct fsi_master *master; const struct platform_device_id *id_entry; struct sh_fsi_platform_info *info = pdev->dev.platform_data; + struct fsi_priv *fsi; struct resource *res; unsigned int irq; int ret; @@ -2045,22 +2046,24 @@ static int fsi_probe(struct platform_device *pdev) spin_lock_init(&master->lock);
/* FSI A setting */ - master->fsia.base = master->base; - master->fsia.master = master; - master->fsia.info = &info->port_a; - fsi_handler_init(&master->fsia); - ret = fsi_stream_probe(&master->fsia, &pdev->dev); + fsi = &master->fsia; + fsi->base = master->base; + fsi->master = master; + fsi->info = &info->port_a; + fsi_handler_init(fsi); + ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIA stream probe failed\n"); return ret; }
/* FSI B setting */ - master->fsib.base = master->base + 0x40; - master->fsib.master = master; - master->fsib.info = &info->port_b; - fsi_handler_init(&master->fsib); - ret = fsi_stream_probe(&master->fsib, &pdev->dev); + fsi = &master->fsib; + fsi->base = master->base + 0x40; + fsi->master = master; + fsi->info = &info->port_b; + fsi_handler_init(fsi); + ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIB stream probe failed\n"); goto exit_fsia;
Current FSI driver is requesting sh_fsi_platform_info pointer from platform, and it didn't allowed NULL pointer. This patch fixes it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/fsi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 913916a..3260d54 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1991,15 +1991,16 @@ static struct snd_soc_platform_driver fsi_soc_platform = { /* * platform function */ -static void fsi_handler_init(struct fsi_priv *fsi) +static void fsi_handler_init(struct fsi_priv *fsi, + struct sh_fsi_port_info *info) { fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ fsi->playback.priv = fsi; fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ fsi->capture.priv = fsi;
- if (fsi->info->tx_id) { - fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id; + if (info->tx_id) { + fsi->playback.slave.shdma_slave.slave_id = info->tx_id; fsi->playback.handler = &fsi_dma_push_handler; } } @@ -2009,11 +2010,16 @@ static int fsi_probe(struct platform_device *pdev) struct fsi_master *master; const struct platform_device_id *id_entry; struct sh_fsi_platform_info *info = pdev->dev.platform_data; + struct sh_fsi_port_info nul_info, *pinfo; struct fsi_priv *fsi; struct resource *res; unsigned int irq; int ret;
+ nul_info.flags = 0; + nul_info.tx_id = 0; + nul_info.rx_id = 0; + id_entry = pdev->id_entry; if (!id_entry) { dev_err(&pdev->dev, "unknown fsi device\n"); @@ -2046,11 +2052,12 @@ static int fsi_probe(struct platform_device *pdev) spin_lock_init(&master->lock);
/* FSI A setting */ + pinfo = (info) ? &info->port_a : &nul_info; fsi = &master->fsia; fsi->base = master->base; fsi->master = master; - fsi->info = &info->port_a; - fsi_handler_init(fsi); + fsi->info = pinfo; + fsi_handler_init(fsi, pinfo); ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIA stream probe failed\n"); @@ -2058,11 +2065,12 @@ static int fsi_probe(struct platform_device *pdev) }
/* FSI B setting */ + pinfo = (info) ? &info->port_b : &nul_info; fsi = &master->fsib; fsi->base = master->base + 0x40; fsi->master = master; - fsi->info = &info->port_b; - fsi_handler_init(fsi); + fsi->info = pinfo; + fsi_handler_init(fsi, pinfo); ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "FSIB stream probe failed\n");
Current FSI driver is using platform information pointer, but it is not good design for DT support. This patch makes spdif format independent from platform information pointer.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/fsi.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3260d54..cc81a49 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1771,7 +1771,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; fsi->chan_num = 2; - fsi->spdif = 1;
return 0; } @@ -1816,16 +1815,10 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) }
/* 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: + if (fsi_is_spdif(fsi)) ret = fsi_set_fmt_spdif(fsi); - break; - default: - ret = -EINVAL; - } + else + ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
return ret; } @@ -1991,6 +1984,13 @@ static struct snd_soc_platform_driver fsi_soc_platform = { /* * platform function */ +static void fsi_port_info_init(struct fsi_priv *fsi, + struct sh_fsi_port_info *info) +{ + if (info->flags & SH_FSI_FMT_SPDIF) + fsi->spdif = 1; +} + static void fsi_handler_init(struct fsi_priv *fsi, struct sh_fsi_port_info *info) { @@ -2057,6 +2057,7 @@ static int fsi_probe(struct platform_device *pdev) fsi->base = master->base; fsi->master = master; fsi->info = pinfo; + fsi_port_info_init(fsi, pinfo); fsi_handler_init(fsi, pinfo); ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) { @@ -2070,6 +2071,7 @@ static int fsi_probe(struct platform_device *pdev) fsi->base = master->base + 0x40; fsi->master = master; fsi->info = pinfo; + fsi_port_info_init(fsi, pinfo); fsi_handler_init(fsi, pinfo); ret = fsi_stream_probe(fsi, &pdev->dev); if (ret < 0) {
Current FSI driver is using platform information pointer, but it is not good design for DT support. This patch makes master clock selection independent from platform information pointer.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/sh_fsi.h | 4 ++-- sound/soc/sh/fsi.c | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 27ee1dc..cc1c919 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h @@ -47,8 +47,8 @@
/* D: clock selecter if master mode */ #define SH_FSI_CLK_MASK 0x0000F000 -#define SH_FSI_CLK_EXTERNAL (1 << 12) -#define SH_FSI_CLK_CPG (2 << 12) /* FSIxCK + FSI-DIV */ +#define SH_FSI_CLK_EXTERNAL (0 << 12) +#define SH_FSI_CLK_CPG (1 << 12) /* FSIxCK + FSI-DIV */
/* * set_rate return value diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index cc81a49..77747b0 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -264,6 +264,7 @@ struct fsi_priv {
int chan_num:16; int clk_master:1; + int clk_cpg:1; int spdif:1;
long rate; @@ -1779,7 +1780,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); set_rate_func set_rate = fsi_get_info_set_rate(fsi); - u32 flags = fsi_get_info_flags(fsi); int ret;
/* set master/slave audio interface */ @@ -1802,16 +1802,12 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) if (set_rate) dev_warn(dai->dev, "set_rate will be removed soon\n");
- switch (flags & SH_FSI_CLK_MASK) { - case SH_FSI_CLK_EXTERNAL: - fsi_clk_init(dai->dev, fsi, 1, 1, 0, - fsi_clk_set_rate_external); - break; - case SH_FSI_CLK_CPG: + if (fsi->clk_cpg) fsi_clk_init(dai->dev, fsi, 0, 1, 1, fsi_clk_set_rate_cpg); - break; - } + else + fsi_clk_init(dai->dev, fsi, 1, 1, 0, + fsi_clk_set_rate_external); }
/* set format */ @@ -1989,6 +1985,9 @@ static void fsi_port_info_init(struct fsi_priv *fsi, { if (info->flags & SH_FSI_FMT_SPDIF) fsi->spdif = 1; + + if (info->flags & SH_FSI_CLK_CPG) + fsi->clk_cpg = 1; }
static void fsi_handler_init(struct fsi_priv *fsi,
Current FSI driver is using platform information pointer, but it is not good design for DT support. This patch makes stream mode format independent from platform information pointer.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/fsi.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 77747b0..22037f1 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -266,6 +266,7 @@ struct fsi_priv { int clk_master:1; int clk_cpg:1; int spdif:1; + int enable_stream:1;
long rate; }; @@ -395,6 +396,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) return fsi->spdif; }
+static int fsi_is_enable_stream(struct fsi_priv *fsi) +{ + return fsi->enable_stream; +} + static int fsi_is_play(struct snd_pcm_substream *substream) { return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; @@ -1138,10 +1144,9 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, */ static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) { - u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; int i;
- if (enable_stream) { + if (fsi_is_enable_stream(fsi)) { /* * stream mode * see @@ -1299,8 +1304,6 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) { - u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; - /* * we can use 16bit stream mode * when "playback" and "16bit data" @@ -1308,7 +1311,7 @@ static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) * see * fsi_pio_push16() */ - if (enable_stream) + if (fsi_is_enable_stream(fsi)) io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); else @@ -1988,6 +1991,9 @@ static void fsi_port_info_init(struct fsi_priv *fsi,
if (info->flags & SH_FSI_CLK_CPG) fsi->clk_cpg = 1; + + if (info->flags & SH_FSI_ENABLE_STREAM_MODE) + fsi->enable_stream = 1; }
static void fsi_handler_init(struct fsi_priv *fsi,
Current FSI driver is using platform information pointer, but it is not good design for DT support. This patch adds SND_SOC_DAIFMT_INV_xxx support, and it is possible to independent from platform information pointer.
Old type SH_FSI_xxx_INV is still supported, but it will be removed soon.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/fsi.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 22037f1..e74c4eb 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -267,6 +267,8 @@ struct fsi_priv { int clk_cpg:1; int spdif:1; int enable_stream:1; + int bit_clk_inv:1; + int lr_clk_inv:1;
long rate; }; @@ -1645,6 +1647,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
/* clock inversion (CKG2) */ data = 0; + if (fsi->bit_clk_inv) + data |= (1 << 0); + if (fsi->lr_clk_inv) + data |= (1 << 4); + if (fsi_is_clk_master(fsi)) + data <<= 8; + /* FIXME + * + * SH_FSI_xxx_INV style will be removed + */ if (SH_FSI_LRM_INV & flags) data |= 1 << 12; if (SH_FSI_BRM_INV & flags) @@ -1796,6 +1808,27 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; }
+ /* set clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: + fsi->bit_clk_inv = 0; + fsi->lr_clk_inv = 1; + break; + case SND_SOC_DAIFMT_IB_NF: + fsi->bit_clk_inv = 1; + fsi->lr_clk_inv = 0; + break; + case SND_SOC_DAIFMT_IB_IF: + fsi->bit_clk_inv = 1; + fsi->lr_clk_inv = 1; + break; + case SND_SOC_DAIFMT_NB_NF: + default: + fsi->bit_clk_inv = 0; + fsi->lr_clk_inv = 0; + break; + } + if (fsi_is_clk_master(fsi)) { /* * CAUTION
On Fri, Nov 16, 2012 at 01:15:27AM -0800, Kuninori Morimoto wrote:
Hi Mark
These patches modify FSI driver to be independent from platform data pointer. These are prepare for device tree support for FSI driver.
Applied all, thanks.
participants (2)
-
Kuninori Morimoto
-
Mark Brown