summaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar/ssi.c
diff options
context:
space:
mode:
authorKuninori Morimoto2014-06-23 02:56:23 +0200
committerMark Brown2014-06-28 15:41:19 +0200
commitd9288d0ba12de1b5efb830b9128e4cc6877318fc (patch)
treef02a9aabd4c12c16bb320e18b827270a25b48689 /sound/soc/sh/rcar/ssi.c
parentASoC: fsi: use dmaengine_prep_dma_cyclic() for DMA transfer (diff)
downloadkernel-qcow2-linux-d9288d0ba12de1b5efb830b9128e4cc6877318fc.tar.gz
kernel-qcow2-linux-d9288d0ba12de1b5efb830b9128e4cc6877318fc.tar.xz
kernel-qcow2-linux-d9288d0ba12de1b5efb830b9128e4cc6877318fc.zip
ASoC: rsnd: SSI + DMA can select BUSIF
Sound data needs to be sent to R-Car sound SSI when playback. But, there are 2 interfaces for it. 1st is SSITDR/SSIRDR which are mapped on SSI. 2nd is SSIn_BUSIF which are mapped on SSIU. 2nd SSIn_BUSIF is used when DMA transfer, and it is always used if sound data came from via SRC. But, we can use it when SSI+DMA case too. (Current driver is assuming 1st SSITDR/SSIRDR for it) 2nd SSIn_BUSIF can be used as FIFO. This is very helpful/useful for SSI+DMA. But DMA address / DMA ID are not same between 1st/2nd cases. This patch care about these settings. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/sh/rcar/ssi.c')
-rw-r--r--sound/soc/sh/rcar/ssi.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 2df723df5d19..34e84009162b 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -90,6 +90,20 @@ struct rsnd_ssi {
#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
+static int rsnd_ssi_use_busif(struct rsnd_mod *mod)
+{
+ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+ struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
+ int use_busif = 0;
+
+ if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF))
+ use_busif = 1;
+ if (rsnd_io_to_mod_src(io))
+ use_busif = 1;
+
+ return use_busif;
+}
+
static void rsnd_ssi_status_check(struct rsnd_mod *mod,
u32 bit)
{
@@ -289,8 +303,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
ssi->cr_own = cr;
ssi->err = -1; /* ignore 1st error */
- rsnd_src_ssi_mode_init(mod, rdai);
-
return 0;
}
@@ -389,6 +401,8 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
/* enable PIO IRQ */
ssi->cr_etc = UIEN | OIEN | DIEN;
+ rsnd_src_ssiu_start(mod, rdai, 0);
+
rsnd_src_enable_ssi_irq(mod, rdai);
rsnd_ssi_hw_start(ssi, rdai, io);
@@ -405,6 +419,8 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
rsnd_ssi_hw_stop(ssi, rdai);
+ rsnd_src_ssiu_stop(mod, rdai, 0);
+
return 0;
}
@@ -457,6 +473,8 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
/* enable DMA transfer */
ssi->cr_etc = DMEN;
+ rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod));
+
rsnd_dma_start(dma);
rsnd_ssi_hw_start(ssi, ssi->rdai, io);
@@ -482,11 +500,19 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
rsnd_dma_stop(dma);
+ rsnd_src_ssiu_stop(mod, rdai, 1);
+
return 0;
}
+static char *rsnd_ssi_dma_name(struct rsnd_mod *mod)
+{
+ return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME;
+}
+
static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
.name = SSI_NAME,
+ .dma_name = rsnd_ssi_dma_name,
.probe = rsnd_ssi_dma_probe,
.remove = rsnd_ssi_dma_remove,
.init = rsnd_ssi_init,
@@ -595,6 +621,9 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
*/
ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ?
0 : 1;
+
+ if (of_get_property(np, "no-busif", NULL))
+ ssi_info->flags |= RSND_SSI_NO_BUSIF;
}
rsnd_of_parse_ssi_end: