From 232c00b6e55558c216cbf50358549a1967ee1419 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:38:26 +0000 Subject: ASoC: rsnd: DMA become SSI/SRC member Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. Current rsnd_mod is member of rsnd_mod. But the DMA user is only SSI/SRC. This DMA will be implemented as module. As 1st step, DMA become SSI/SRC member by this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 19 ++++++++++++++++--- sound/soc/sh/rcar/rsnd.h | 8 ++++---- sound/soc/sh/rcar/src.c | 19 +++++++++++++------ sound/soc/sh/rcar/ssi.c | 16 ++++++++++------ 4 files changed, 43 insertions(+), 19 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 5d084d040961..923120c7b250 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -606,14 +606,17 @@ void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) dma->ops->quit(io, dma); } -int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) +struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, + struct rsnd_mod *mod, int id) { struct rsnd_mod *mod_from = NULL; struct rsnd_mod *mod_to = NULL; struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); + struct rsnd_dma *dma; struct device *dev = rsnd_priv_to_dev(priv); int is_play = rsnd_io_is_play(io); + int ret; /* * DMA failed. try to PIO mode @@ -622,7 +625,13 @@ int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) * rsnd_rdai_continuance_probe() */ if (!dmac) - return -EAGAIN; + return ERR_PTR(-EAGAIN); + + dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); + if (!dma) + return ERR_PTR(-ENOMEM); + + dma->mod = mod; rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); @@ -644,7 +653,11 @@ int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); - return dma->ops->init(io, dma, id, mod_from, mod_to); + ret = dma->ops->init(io, dma, id, mod_from, mod_to); + if (ret < 0) + return ERR_PTR(ret); + + return dma; } int rsnd_dma_probe(struct platform_device *pdev, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 085329878525..1c08eaa51430 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -206,6 +206,7 @@ struct rsnd_dmapp { struct rsnd_dma { struct rsnd_dma_ops *ops; + struct rsnd_mod *mod; dma_addr_t src_addr; dma_addr_t dst_addr; union { @@ -215,11 +216,12 @@ struct rsnd_dma { }; #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) -#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) +#define rsnd_dma_to_mod(_dma) ((dma)->mod) void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); -int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id); +struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, + struct rsnd_mod *mod, int id); void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma); int rsnd_dma_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, @@ -278,7 +280,6 @@ struct rsnd_mod { int id; enum rsnd_mod_type type; struct rsnd_mod_ops *ops; - struct rsnd_dma dma; struct rsnd_priv *priv; struct clk *clk; u32 status; @@ -328,7 +329,6 @@ struct rsnd_mod { #define __rsnd_mod_call_hw_params 0 #define rsnd_mod_to_priv(mod) ((mod)->priv) -#define rsnd_mod_to_dma(mod) (&(mod)->dma) #define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) #define rsnd_mod_power_on(mod) clk_enable((mod)->clk) #define rsnd_mod_power_off(mod) clk_disable((mod)->clk) diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 261b50217c48..3296f1e96d30 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -22,6 +22,7 @@ struct rsnd_src { struct rsnd_src_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; + struct rsnd_dma *dma; struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ struct rsnd_kctrl_cfg_s sync; /* sync convert */ u32 convert_rate; /* sampling rate convert */ @@ -30,6 +31,7 @@ struct rsnd_src { #define RSND_SRC_NAME_SIZE 16 +#define rsnd_src_to_dma(src) ((src)->dma) #define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_enable_sync_convert(src) ((src)->sen.val) #define rsnd_src_of_node(priv) \ @@ -839,9 +841,9 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, return ret; } - ret = rsnd_dma_init(io, - rsnd_mod_to_dma(mod), - src->info->dma_id); + src->dma = rsnd_dma_init(io, mod, src->info->dma_id); + if (IS_ERR(src->dma)) + return PTR_ERR(src->dma); return ret; } @@ -850,7 +852,9 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); + struct rsnd_src *src = rsnd_mod_to_src(mod); + + rsnd_dma_quit(io, rsnd_src_to_dma(src)); return 0; } @@ -880,7 +884,9 @@ static int rsnd_src_start_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - rsnd_dma_start(io, rsnd_mod_to_dma(mod)); + struct rsnd_src *src = rsnd_mod_to_src(mod); + + rsnd_dma_start(io, rsnd_src_to_dma(src)); return _rsnd_src_start_gen2(mod, io); } @@ -889,11 +895,12 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { + struct rsnd_src *src = rsnd_mod_to_src(mod); int ret; ret = _rsnd_src_stop_gen2(mod); - rsnd_dma_stop(io, rsnd_mod_to_dma(mod)); + rsnd_dma_stop(io, rsnd_src_to_dma(src)); return ret; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 1427ec21bd7e..eec17bcc89fa 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -63,6 +63,7 @@ struct rsnd_ssi { struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ struct rsnd_ssi *parent; struct rsnd_mod mod; + struct rsnd_dma *dma; u32 cr_own; u32 cr_clk; @@ -77,6 +78,7 @@ struct rsnd_ssi { ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \ i++) +#define rsnd_ssi_to_dma(mod) ((ssi)->dma) #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) @@ -537,9 +539,9 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, if (ret) return ret; - ret = rsnd_dma_init( - io, rsnd_mod_to_dma(mod), - dma_id); + ssi->dma = rsnd_dma_init(io, mod, dma_id); + if (IS_ERR(ssi->dma)) + return PTR_ERR(ssi->dma); return ret; } @@ -552,7 +554,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); int irq = ssi->info->irq; - rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); + rsnd_dma_quit(io, rsnd_ssi_to_dma(ssi)); /* PIO will request IRQ again */ devm_free_irq(dev, irq, mod); @@ -585,7 +587,8 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_dma *dma = rsnd_ssi_to_dma(ssi); rsnd_dma_start(io, dma); @@ -598,7 +601,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_dma *dma = rsnd_ssi_to_dma(ssi); rsnd_ssi_stop(mod, io, priv); -- cgit v1.2.3 From 3e5afa73a9fb4001789508d6f9f0fca3e3475f5a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:38:58 +0000 Subject: ASoC: rsnd: DMA related definition goes to dma.c Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. DMA will be implemented as module. Current DMA definition is no longer needed on rsnd.h. Let's move it to dma.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 24 ++++++++++++++++++++++++ sound/soc/sh/rcar/rsnd.h | 23 ----------------------- 2 files changed, 24 insertions(+), 23 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 923120c7b250..00e83e0670e7 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -22,6 +22,27 @@ /* PDMACHCR */ #define PDMACHCR_DE (1 << 0) + +struct rsnd_dmaen { + struct dma_chan *chan; +}; + +struct rsnd_dmapp { + int dmapp_id; + u32 chcr; +}; + +struct rsnd_dma { + struct rsnd_dma_ops *ops; + struct rsnd_mod *mod; + dma_addr_t src_addr; + dma_addr_t dst_addr; + union { + struct rsnd_dmaen en; + struct rsnd_dmapp pp; + } dma; +}; + struct rsnd_dma_ctrl { void __iomem *base; int dmapp_num; @@ -37,6 +58,9 @@ struct rsnd_dma_ops { }; #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) +#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) +#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) +#define rsnd_dma_to_mod(_dma) ((dma)->mod) /* * Audio DMAC diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 1c08eaa51430..1dc05a24c01c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -195,29 +195,6 @@ void rsnd_path_parse(struct rsnd_priv *priv, */ struct rsnd_dma; -struct rsnd_dmaen { - struct dma_chan *chan; -}; - -struct rsnd_dmapp { - int dmapp_id; - u32 chcr; -}; - -struct rsnd_dma { - struct rsnd_dma_ops *ops; - struct rsnd_mod *mod; - dma_addr_t src_addr; - dma_addr_t dst_addr; - union { - struct rsnd_dmaen en; - struct rsnd_dmapp pp; - } dma; -}; -#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) -#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) -#define rsnd_dma_to_mod(_dma) ((dma)->mod) - void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, -- cgit v1.2.3 From 81ecbb654e1015840dec6a1ef3fcfef34d28feed Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:39:20 +0000 Subject: ASoC: rsnd: rename rsnd_dma_init() to rsnd_dma_attach() Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. DMA will be implemented as module. Then each rsnd_dma_ops will be rsnd_mod_ops. But current rsnd_dma_ops::init means "DMA attach". This patch removes .init from rsnd_dma_ops, and renames rsnd_dma_init() to rsnd_dma_attach() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 35 +++++++++++++++++++---------------- sound/soc/sh/rcar/rsnd.h | 2 +- sound/soc/sh/rcar/src.c | 2 +- sound/soc/sh/rcar/ssi.c | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 00e83e0670e7..705e524b0892 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -52,8 +52,6 @@ struct rsnd_dma_ops { char *name; void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); - int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, - struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); }; @@ -176,7 +174,7 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io, return rsnd_mod_dma_req(io, mod_to); } -static int rsnd_dmaen_init(struct rsnd_dai_stream *io, +static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { @@ -221,11 +219,11 @@ static int rsnd_dmaen_init(struct rsnd_dai_stream *io, ret = dmaengine_slave_config(dmaen->chan, &cfg); if (ret < 0) - goto rsnd_dma_init_err; + goto rsnd_dma_attach_err; return 0; -rsnd_dma_init_err: +rsnd_dma_attach_err: rsnd_dma_quit(io, dma); rsnd_dma_channel_err: @@ -252,7 +250,6 @@ static struct rsnd_dma_ops rsnd_dmaen_ops = { .name = "audmac", .start = rsnd_dmaen_start, .stop = rsnd_dmaen_stop, - .init = rsnd_dmaen_init, .quit = rsnd_dmaen_quit, }; @@ -372,9 +369,9 @@ static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); } -static int rsnd_dmapp_init(struct rsnd_dai_stream *io, - struct rsnd_dma *dma, int id, - struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) +static int rsnd_dmapp_attach(struct rsnd_dai_stream *io, + struct rsnd_dma *dma, int id, + struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); struct rsnd_priv *priv = rsnd_io_to_priv(io); @@ -398,7 +395,6 @@ static struct rsnd_dma_ops rsnd_dmapp_ops = { .name = "audmac-pp", .start = rsnd_dmapp_start, .stop = rsnd_dmapp_stop, - .init = rsnd_dmapp_init, .quit = rsnd_dmapp_stop, }; @@ -630,8 +626,8 @@ void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) dma->ops->quit(io, dma); } -struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, - struct rsnd_mod *mod, int id) +struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, + struct rsnd_mod *mod, int id) { struct rsnd_mod *mod_from = NULL; struct rsnd_mod *mod_to = NULL; @@ -639,6 +635,8 @@ struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); struct rsnd_dma *dma; struct device *dev = rsnd_priv_to_dev(priv); + int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, + struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); int is_play = rsnd_io_is_play(io); int ret; @@ -663,21 +661,26 @@ struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); /* for Gen2 */ - if (mod_from && mod_to) + if (mod_from && mod_to) { dma->ops = &rsnd_dmapp_ops; - else + attach = rsnd_dmapp_attach; + } else { dma->ops = &rsnd_dmaen_ops; + attach = rsnd_dmaen_attach; + } /* for Gen1, overwrite */ - if (rsnd_is_gen1(priv)) + if (rsnd_is_gen1(priv)) { dma->ops = &rsnd_dmaen_ops; + attach = rsnd_dmaen_attach; + } dev_dbg(dev, "%s %s[%d] -> %s[%d]\n", dma->ops->name, rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); - ret = dma->ops->init(io, dma, id, mod_from, mod_to); + ret = attach(io, dma, id, mod_from, mod_to); if (ret < 0) return ERR_PTR(ret); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 1dc05a24c01c..dc31f6d84ee4 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -197,7 +197,7 @@ struct rsnd_dma; void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); -struct rsnd_dma *rsnd_dma_init(struct rsnd_dai_stream *io, +struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma); int rsnd_dma_probe(struct platform_device *pdev, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 3296f1e96d30..abfcc2480cf6 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -841,7 +841,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, return ret; } - src->dma = rsnd_dma_init(io, mod, src->info->dma_id); + src->dma = rsnd_dma_attach(io, mod, src->info->dma_id); if (IS_ERR(src->dma)) return PTR_ERR(src->dma); diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index eec17bcc89fa..d4803a82497d 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -539,7 +539,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, if (ret) return ret; - ssi->dma = rsnd_dma_init(io, mod, dma_id); + ssi->dma = rsnd_dma_attach(io, mod, dma_id); if (IS_ERR(ssi->dma)) return PTR_ERR(ssi->dma); -- cgit v1.2.3 From 27924f3208c9f37a1d58b80d999bb9cfc96536d4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:39:41 +0000 Subject: ASoC: rsnd: enable to use rsnd_dai_connect() from each mod Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. DMAC/SSIU/SSI-parent/CMD will be implemented as module, but these are not customer controlled module. These should be automatically install to system. Because of this, rsnd_dai_connect() should be called from each mod. SSI can be very special, because it will be installed as SSI-parent / SSI-child. Thus, new rsnd_dai_connect() has type parameter which should be mod->type except SSI-parent Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 32 +++++++++++++++++--------------- sound/soc/sh/rcar/rsnd.h | 3 +++ 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index deed48ef28b8..d7d2a59d0553 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -332,8 +332,9 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) ret; \ }) -static int rsnd_dai_connect(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) +int rsnd_dai_connect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + enum rsnd_mod_type type) { struct rsnd_priv *priv; struct device *dev; @@ -344,7 +345,7 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, priv = rsnd_mod_to_priv(mod); dev = rsnd_priv_to_dev(priv); - io->mod[mod->type] = mod; + io->mod[type] = mod; dev_dbg(dev, "%s[%d] is connected to io (%s)\n", rsnd_mod_name(mod), rsnd_mod_id(mod), @@ -354,9 +355,10 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, } static void rsnd_dai_disconnect(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) + struct rsnd_dai_stream *io, + enum rsnd_mod_type type) { - io->mod[mod->type] = NULL; + io->mod[type] = NULL; } struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id) @@ -572,32 +574,32 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .set_fmt = rsnd_soc_dai_set_fmt, }; -#define rsnd_path_add(priv, io, type) \ +#define rsnd_path_add(priv, io, _type) \ ({ \ struct rsnd_mod *mod; \ int ret = 0; \ int id = -1; \ \ - if (rsnd_is_enable_path(io, type)) { \ - id = rsnd_info_id(priv, io, type); \ + if (rsnd_is_enable_path(io, _type)) { \ + id = rsnd_info_id(priv, io, _type); \ if (id >= 0) { \ - mod = rsnd_##type##_mod_get(priv, id); \ - ret = rsnd_dai_connect(mod, io); \ + mod = rsnd_##_type##_mod_get(priv, id); \ + ret = rsnd_dai_connect(mod, io, mod->type);\ } \ } \ ret; \ }) -#define rsnd_path_remove(priv, io, type) \ +#define rsnd_path_remove(priv, io, _type) \ { \ struct rsnd_mod *mod; \ int id = -1; \ \ - if (rsnd_is_enable_path(io, type)) { \ - id = rsnd_info_id(priv, io, type); \ + if (rsnd_is_enable_path(io, _type)) { \ + id = rsnd_info_id(priv, io, _type); \ if (id >= 0) { \ - mod = rsnd_##type##_mod_get(priv, id); \ - rsnd_dai_disconnect(mod, io); \ + mod = rsnd_##_type##_mod_get(priv, id); \ + rsnd_dai_disconnect(mod, io, mod->type);\ } \ } \ } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index dc31f6d84ee4..996fa1ebe7c8 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -380,6 +380,9 @@ struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); +int rsnd_dai_connect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + enum rsnd_mod_type type); /* * R-Car Gen1/Gen2 -- cgit v1.2.3 From 48d582819fdc38cda1aeb17f26cfe586d3900f2f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:40:02 +0000 Subject: ASoC: rsnd: remove all modules when PIO fallback Current Renesas sound is supporting PIO fallback if it can't use DMA. In such case, it should remove all attached modules, but current driver is missing about CTU/MIX. Because current implement requests specific mod for remove. To avoid same things in future, this patch removes all mods, and re-connects SSI when PIO fallback case. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index d7d2a59d0553..b6fc0d86c03d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -590,20 +590,6 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { ret; \ }) -#define rsnd_path_remove(priv, io, _type) \ -{ \ - struct rsnd_mod *mod; \ - int id = -1; \ - \ - if (rsnd_is_enable_path(io, _type)) { \ - id = rsnd_info_id(priv, io, _type); \ - if (id >= 0) { \ - mod = rsnd_##_type##_mod_get(priv, id); \ - rsnd_dai_disconnect(mod, io, mod->type);\ - } \ - } \ -} - void rsnd_path_parse(struct rsnd_priv *priv, struct rsnd_dai_stream *io) { @@ -1163,6 +1149,9 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, ret = rsnd_dai_call(probe, io, priv); if (ret == -EAGAIN) { + struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io); + int i; + /* * Fallback to PIO mode */ @@ -1177,10 +1166,12 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, rsnd_dai_call(remove, io, priv); /* - * remove SRC/DVC from DAI, + * remove all mod from io + * and, re connect ssi */ - rsnd_path_remove(priv, io, src); - rsnd_path_remove(priv, io, dvc); + for (i = 0; i < RSND_MOD_MAX; i++) + rsnd_dai_disconnect((io)->mod[i], io, i); + rsnd_dai_connect(ssi_mod, io, RSND_MOD_SSI); /* * fallback -- cgit v1.2.3 From 40854c648ee79019a90034fc1f73ba2822812099 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:40:19 +0000 Subject: ASoC: rsnd: fixup rsnd_dma_of_path method for mod base common method Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. Current rsnd_dma_of_path is assuming that all mods are related to DMA. But it will be wrong. This patch tidyup this wrong assumption Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 705e524b0892..697f8825215f 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -533,7 +533,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, struct rsnd_mod *mod_start, *mod_end; struct rsnd_priv *priv = rsnd_mod_to_priv(this); struct device *dev = rsnd_priv_to_dev(priv); - int nr, i; + int nr, i, idx; if (!ssi) return; @@ -562,23 +562,24 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, mod_start = (is_play) ? NULL : ssi; mod_end = (is_play) ? ssi : NULL; - mod[0] = mod_start; + idx = 0; + mod[idx++] = mod_start; for (i = 1; i < nr; i++) { if (src) { - mod[i] = src; + mod[idx++] = src; src = NULL; } else if (ctu) { - mod[i] = ctu; + mod[idx++] = ctu; ctu = NULL; } else if (mix) { - mod[i] = mix; + mod[idx++] = mix; mix = NULL; } else if (dvc) { - mod[i] = dvc; + mod[idx++] = dvc; dvc = NULL; } } - mod[i] = mod_end; + mod[idx] = mod_end; /* * | SSI | SRC | @@ -587,8 +588,8 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, * !is_play | * | o | */ if ((this == ssi) == (is_play)) { - *mod_from = mod[nr - 1]; - *mod_to = mod[nr]; + *mod_from = mod[idx - 1]; + *mod_to = mod[idx]; } else { *mod_from = mod[0]; *mod_to = mod[1]; @@ -596,7 +597,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, dev_dbg(dev, "module connection (this is %s[%d])\n", rsnd_mod_name(this), rsnd_mod_id(this)); - for (i = 0; i <= nr; i++) { + for (i = 0; i <= idx; i++) { dev_dbg(dev, " %s[%d]%s\n", rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]), (mod[i] == *mod_from) ? " from" : -- cgit v1.2.3 From 37447b46e8c54c807e368d31ef6423c772b8dbbf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:40:41 +0000 Subject: ASoC: rsnd: move rsnd_src_ssi_irq_enable/disable() to ssi.c Part of SSI IRQ enable/disable was controlled by SRU (on Gen1) or CMD (on Gen2). Because of this reason SSI IRQ function was implemented under src.c. but it is not understandable. Let's move it to ssi.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsnd.h | 2 -- sound/soc/sh/rcar/src.c | 28 ---------------------------- sound/soc/sh/rcar/ssi.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 32 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 996fa1ebe7c8..d6365dc2ac99 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -576,8 +576,6 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, int use_busif); int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, struct rsnd_dai_stream *io); -int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); -int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); /* * R-Car CTU diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index abfcc2480cf6..513094ec2312 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -210,34 +210,6 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, return 0; } -int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod) -{ - struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); - - if (rsnd_is_gen1(priv)) - return 0; - - /* enable SSI interrupt if Gen2 */ - rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, - rsnd_ssi_is_dma_mode(ssi_mod) ? - 0x0e000000 : 0x0f000000); - - return 0; -} - -int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) -{ - struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); - - if (rsnd_is_gen1(priv)) - return 0; - - /* disable SSI interrupt if Gen2 */ - rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000); - - return 0; -} - static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, struct rsnd_src *src) { diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index d4803a82497d..c7d943411ae5 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -124,6 +124,34 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod, dev_warn(dev, "status check failed\n"); } +static int rsnd_ssi_irq_enable(struct rsnd_mod *ssi_mod) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); + + if (rsnd_is_gen1(priv)) + return 0; + + /* enable SSI interrupt if Gen2 */ + rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, + rsnd_ssi_is_dma_mode(ssi_mod) ? + 0x0e000000 : 0x0f000000); + + return 0; +} + +static int rsnd_ssi_irq_disable(struct rsnd_mod *ssi_mod) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); + + if (rsnd_is_gen1(priv)) + return 0; + + /* disable SSI interrupt if Gen2 */ + rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000); + + return 0; +} + static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, struct rsnd_dai_stream *io) { @@ -401,7 +429,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, rsnd_ssi_hw_start(ssi, io); - rsnd_src_ssi_irq_enable(mod); + rsnd_ssi_irq_enable(mod); return 0; } @@ -412,7 +440,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - rsnd_src_ssi_irq_disable(mod); + rsnd_ssi_irq_disable(mod); rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); -- cgit v1.2.3 From b761bf272bce6dff4d8a7ccf4385c9f3d4018094 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:40:59 +0000 Subject: ASoC: rsnd: disable SRC.out only when stop timing Because SRC is connected to DMA and DMA want to keep dreq when stop timing. This patch makes SRC stop SRC.out only when stop timing. And it stops both SRC.out/SRC.in when quit timing Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 513094ec2312..3f6993facf69 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -665,13 +665,27 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) { rsnd_src_irq_disable_gen2(mod); - rsnd_mod_write(mod, SRC_CTRL, 0); + /* + * stop SRC output only + * see rsnd_src_quit_gen2 + */ + rsnd_mod_write(mod, SRC_CTRL, 0x01); rsnd_src_error_record_gen2(mod); return rsnd_src_stop(mod); } +static int rsnd_src_quit_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + /* stop both out/in */ + rsnd_mod_write(mod, SRC_CTRL, 0); + + return 0; +} + static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { @@ -943,7 +957,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = { .probe = rsnd_src_probe_gen2, .remove = rsnd_src_remove_gen2, .init = rsnd_src_init_gen2, - .quit = rsnd_src_quit, + .quit = rsnd_src_quit_gen2, .start = rsnd_src_start_gen2, .stop = rsnd_src_stop_gen2, .hw_params = rsnd_src_hw_params, -- cgit v1.2.3 From c2dc47d5cff62bfe21a691bef40eb30a585caa3c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:41:17 +0000 Subject: ASoC: rsnd: rsnd_dai_stream has each mod's status insted of rsnd_mod Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. Current rsnd is controling each mod's status on mod. But it was not good design for SSI, because stream might has SSI-parent. In such case, it can't play/capture in same time, because SSI-parent is used as normal SSI in other stream, but it shares same status. To avoid this issue each mod's status is controlled by rsnd_dai_stream instead of rsnd_mod. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 12 +++++++----- sound/soc/sh/rcar/rsnd.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index b6fc0d86c03d..5f20d6776281 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -300,20 +300,22 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) /* * rsnd_dai functions */ -#define rsnd_mod_call(mod, io, func, param...) \ +#define rsnd_mod_call(idx, io, func, param...) \ ({ \ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ + struct rsnd_mod *mod = (io)->mod[idx]; \ struct device *dev = rsnd_priv_to_dev(priv); \ + u32 *status = (io)->mod_status + idx; \ u32 mask = 0xF << __rsnd_mod_shift_##func; \ - u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ + u8 val = (*status >> __rsnd_mod_shift_##func) & 0xF; \ u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ int ret = 0; \ int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \ - mod->status = (mod->status & ~mask) + \ + *status = (*status & ~mask) + \ (add << __rsnd_mod_shift_##func); \ dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \ rsnd_mod_name(mod), rsnd_mod_id(mod), \ - mod->status, call ? #func : ""); \ + *status, call ? #func : ""); \ if (call) \ ret = (mod)->ops->func(mod, io, param); \ ret; \ @@ -327,7 +329,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) mod = (io)->mod[i]; \ if (!mod) \ continue; \ - ret |= rsnd_mod_call(mod, io, fn, param); \ + ret |= rsnd_mod_call(i, io, fn, param); \ } \ ret; \ }) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index d6365dc2ac99..774cb24b7338 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -259,7 +259,6 @@ struct rsnd_mod { struct rsnd_mod_ops *ops; struct rsnd_priv *priv; struct clk *clk; - u32 status; }; /* * status @@ -335,6 +334,7 @@ struct rsnd_dai_stream { struct rsnd_mod *mod[RSND_MOD_MAX]; struct rsnd_dai_path_info *info; /* rcar_snd.h */ struct rsnd_dai *rdai; + u32 mod_status[RSND_MOD_MAX]; int byte_pos; int period_pos; int byte_per_period; -- cgit v1.2.3 From 69e32a58bde67490f57b6172da198b50c7aa6ab1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:41:36 +0000 Subject: ASoC: rsnd: Don't stop HW even if a large number of errors occur Current SSI/SRC restarts HW if under/over flow happened to avoid L/R invert issue. But it will stop HW if too many error happen. But if it stops on HW, other side under/over flow happen. OTHA, it will be forever loop interrupt if something strange error happen on HW/driver without escape route of large number error. To avoid this issue, it indicates error message if large number error occur, and disables error interrupt. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 17 ++++++++++------- sound/soc/sh/rcar/ssi.c | 15 +++++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 3f6993facf69..0d96ce5ed9cc 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -690,6 +690,8 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_src *src = rsnd_mod_to_src(mod); + struct device *dev = rsnd_priv_to_dev(priv); spin_lock(&priv->lock); @@ -698,18 +700,19 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, goto rsnd_src_interrupt_gen2_out; if (rsnd_src_error_record_gen2(mod)) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_src *src = rsnd_mod_to_src(mod); - struct device *dev = rsnd_priv_to_dev(priv); dev_dbg(dev, "%s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); _rsnd_src_stop_gen2(mod); - if (src->err < 1024) - _rsnd_src_start_gen2(mod, io); - else - dev_warn(dev, "no more SRC restart\n"); + _rsnd_src_start_gen2(mod, io); + } + + if (src->err > 1024) { + rsnd_src_irq_disable_gen2(mod); + + dev_warn(dev, "no more %s[%d] restart\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); } rsnd_src_interrupt_gen2_out: diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index c7d943411ae5..86e51ce66b10 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -456,6 +456,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); int is_dma = rsnd_ssi_is_dma_mode(mod); u32 status; bool elapsed = false; @@ -489,8 +490,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, /* DMA only */ if (is_dma && (status & (UIRQ | OIRQ))) { - struct device *dev = rsnd_priv_to_dev(priv); - /* * restart SSI */ @@ -498,14 +497,18 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, rsnd_mod_name(mod), rsnd_mod_id(mod)); rsnd_ssi_stop(mod, io, priv); - if (ssi->err < 1024) - rsnd_ssi_start(mod, io, priv); - else - dev_warn(dev, "no more SSI restart\n"); + rsnd_ssi_start(mod, io, priv); } rsnd_ssi_record_error(ssi, status); + if (ssi->err > 1024) { + rsnd_ssi_irq_disable(mod); + + dev_warn(dev, "no more %s[%d] restart\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + } + rsnd_ssi_interrupt_out: spin_unlock(&priv->lock); -- cgit v1.2.3 From 2daf71ad8da6cb57f919c9c876ee7e42530371df Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:41:53 +0000 Subject: ASoC: rsnd: avoid pointless loop in rsnd_mod_interrupt() Current Renesas sound driver doesn't have 1:1 relationship between stream <-> mod because it is supporting MIX. Because of this reason rsnd_mod_interrupt() is searching correspond mod by for loop. But this loop is not needed, because each mod has own type. This patch avoid pointless loop by using mod->type. This patch is good for SSI-parent support, because stream might have 2 SSI as SSI-parent/child. SSI interrupt handler will be called twice if stream has SSI-parent without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5f20d6776281..8af2d22d0cd3 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -192,19 +192,16 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dai_stream *io; struct rsnd_dai *rdai; - int i, j; - - for_each_rsnd_dai(rdai, priv, j) { + int i; - for (i = 0; i < RSND_MOD_MAX; i++) { - io = &rdai->playback; - if (mod == io->mod[i]) - callback(mod, io); + for_each_rsnd_dai(rdai, priv, i) { + io = &rdai->playback; + if (mod == io->mod[mod->type]) + callback(mod, io); - io = &rdai->capture; - if (mod == io->mod[i]) - callback(mod, io); - } + io = &rdai->capture; + if (mod == io->mod[mod->type]) + callback(mod, io); } } -- cgit v1.2.3 From e10369d88c16456b0ff3ae31b4e30a3d2795a243 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:42:09 +0000 Subject: ASoC: rsnd: use common rsnd_ssi_status_xxx() Current ssi.c driver has random access to SSISR register. Let's use common rsnd_ssi_status_xxx() function Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 86e51ce66b10..ad5539def58f 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -105,6 +105,16 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) return use_busif; } +static void rsnd_ssi_status_clear(struct rsnd_mod *mod) +{ + rsnd_mod_write(mod, SSISR, 0); +} + +static u32 rsnd_ssi_status_get(struct rsnd_mod *mod) +{ + return rsnd_mod_read(mod, SSISR); +} + static void rsnd_ssi_status_check(struct rsnd_mod *mod, u32 bit) { @@ -114,7 +124,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod, int i; for (i = 0; i < 1024; i++) { - status = rsnd_mod_read(mod, SSISR); + status = rsnd_ssi_status_get(mod); if (status & bit) return; @@ -245,7 +255,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, rsnd_mod_write(mod, SSIWSR, CONT); /* clear error status */ - rsnd_mod_write(mod, SSISR, 0); + rsnd_ssi_status_clear(mod); ssi->usrcnt++; @@ -406,17 +416,20 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, return 0; } -static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) +static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi) { struct rsnd_mod *mod = rsnd_mod_get(ssi); + u32 status = rsnd_ssi_status_get(mod); /* under/over flow error */ if (status & (UIRQ | OIRQ)) { ssi->err++; /* clear error status */ - rsnd_mod_write(mod, SSISR, 0); + rsnd_ssi_status_clear(mod); } + + return status; } static int rsnd_ssi_start(struct rsnd_mod *mod, @@ -442,7 +455,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, rsnd_ssi_irq_disable(mod); - rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); + rsnd_ssi_record_error(ssi); rsnd_ssi_hw_stop(io, ssi); @@ -467,7 +480,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, if (!rsnd_io_is_working(io)) goto rsnd_ssi_interrupt_out; - status = rsnd_mod_read(mod, SSISR); + status = rsnd_ssi_record_error(ssi); /* PIO only */ if (!is_dma && (status & DIRQ)) { @@ -500,8 +513,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, rsnd_ssi_start(mod, io, priv); } - rsnd_ssi_record_error(ssi, status); - if (ssi->err > 1024) { rsnd_ssi_irq_disable(mod); -- cgit v1.2.3 From 940e947926cab8637e7a664e1f6e4bf8b94e42c5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:42:25 +0000 Subject: ASoC: rsnd: use mod base common method on DMA phase1 Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. DMA will be implemented as module. Then rsnd_dma will be mod base. This patch makes rsnd_dma mod base, but still not yet completely finished. This mod is not yet installed to system at this point. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 61 ++++++++++++++++++++++++++++++++---------------- sound/soc/sh/rcar/rsnd.h | 14 +++++------ sound/soc/sh/rcar/src.c | 2 +- sound/soc/sh/rcar/ssi.c | 6 ++--- 4 files changed, 52 insertions(+), 31 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 697f8825215f..45d30b8e6226 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -34,7 +34,8 @@ struct rsnd_dmapp { struct rsnd_dma { struct rsnd_dma_ops *ops; - struct rsnd_mod *mod; + struct rsnd_mod mod; + struct rsnd_mod *user_mod; dma_addr_t src_addr; dma_addr_t dst_addr; union { @@ -45,6 +46,7 @@ struct rsnd_dma { struct rsnd_dma_ctrl { void __iomem *base; + int dmaen_num; int dmapp_num; }; @@ -56,9 +58,9 @@ struct rsnd_dma_ops { }; #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) +#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod) #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) -#define rsnd_dma_to_mod(_dma) ((dma)->mod) /* * Audio DMAC @@ -109,8 +111,8 @@ static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) { struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_mod *user_mod = dma->user_mod; + struct rsnd_priv *priv = rsnd_io_to_priv(io); struct snd_pcm_substream *substream = io->substream; struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; @@ -129,7 +131,7 @@ static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) } desc->callback = rsnd_dmaen_complete; - desc->callback_param = mod; + desc->callback_param = user_mod; if (dmaengine_submit(desc) < 0) { dev_err(dev, "dmaengine_submit() fail\n"); @@ -180,6 +182,7 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, { struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct rsnd_priv *priv = rsnd_io_to_priv(io); + struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); struct device *dev = rsnd_priv_to_dev(priv); struct dma_slave_config cfg = {}; int is_play = rsnd_io_is_play(io); @@ -221,10 +224,12 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, if (ret < 0) goto rsnd_dma_attach_err; + dmac->dmaen_num++; + return 0; rsnd_dma_attach_err: - rsnd_dma_quit(io, dma); + rsnd_dma_quit(io, rsnd_mod_get(dma)); rsnd_dma_channel_err: /* @@ -328,7 +333,7 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io, (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id)) static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) { - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_mod *mod = rsnd_mod_get(dma); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); struct device *dev = rsnd_priv_to_dev(priv); @@ -340,7 +345,7 @@ static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) { - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_mod *mod = rsnd_mod_get(dma); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); @@ -517,13 +522,12 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, } #define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */ -static void rsnd_dma_of_path(struct rsnd_dma *dma, +static void rsnd_dma_of_path(struct rsnd_mod *this, struct rsnd_dai_stream *io, int is_play, struct rsnd_mod **mod_from, struct rsnd_mod **mod_to) { - struct rsnd_mod *this = rsnd_dma_to_mod(dma); struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); struct rsnd_mod *src = rsnd_io_to_mod_src(io); struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io); @@ -605,19 +609,23 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, } } -void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); + dma->ops->stop(io, dma); } -void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); + dma->ops->start(io, dma); } -void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { - struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); @@ -627,9 +635,13 @@ void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) dma->ops->quit(io, dma); } -struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, +static struct rsnd_mod_ops rsnd_dma_ops = { +}; + +struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id) { + struct rsnd_mod *dma_mod; struct rsnd_mod *mod_from = NULL; struct rsnd_mod *mod_to = NULL; struct rsnd_priv *priv = rsnd_io_to_priv(io); @@ -639,7 +651,7 @@ struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); int is_play = rsnd_io_is_play(io); - int ret; + int ret, dma_id; /* * DMA failed. try to PIO mode @@ -654,10 +666,9 @@ struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, if (!dma) return ERR_PTR(-ENOMEM); - dma->mod = mod; - - rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); + rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to); + dma->user_mod = mod; dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); @@ -665,27 +676,37 @@ struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, if (mod_from && mod_to) { dma->ops = &rsnd_dmapp_ops; attach = rsnd_dmapp_attach; + dma_id = dmac->dmapp_num; } else { dma->ops = &rsnd_dmaen_ops; attach = rsnd_dmaen_attach; + dma_id = dmac->dmaen_num; } /* for Gen1, overwrite */ if (rsnd_is_gen1(priv)) { dma->ops = &rsnd_dmaen_ops; attach = rsnd_dmaen_attach; + dma_id = dmac->dmaen_num; } + dma_mod = rsnd_mod_get(dma); + dev_dbg(dev, "%s %s[%d] -> %s[%d]\n", dma->ops->name, rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); + ret = rsnd_mod_init(priv, dma_mod, + &rsnd_dma_ops, NULL, 0, dma_id); + if (ret < 0) + return ERR_PTR(ret); + ret = attach(io, dma, id, mod_from, mod_to); if (ret < 0) return ERR_PTR(ret); - return dma; + return rsnd_mod_get(dma); } int rsnd_dma_probe(struct platform_device *pdev, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 774cb24b7338..6a0bd3e6c8d1 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -193,13 +193,11 @@ void rsnd_path_parse(struct rsnd_priv *priv, /* * R-Car DMA */ -struct rsnd_dma; - -void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); -void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); -struct rsnd_dma *rsnd_dma_attach(struct rsnd_dai_stream *io, +void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_mod *mod); +void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_mod *mod); +struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); -void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma); +void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_mod *mod); int rsnd_dma_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); @@ -210,7 +208,9 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, * R-Car sound mod */ enum rsnd_mod_type { - RSND_MOD_DVC = 0, + RSND_MOD_AUDMAPP, + RSND_MOD_AUDMA, + RSND_MOD_DVC, RSND_MOD_MIX, RSND_MOD_CTU, RSND_MOD_SRC, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 0d96ce5ed9cc..517a1e176795 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -22,7 +22,7 @@ struct rsnd_src { struct rsnd_src_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; - struct rsnd_dma *dma; + struct rsnd_mod *dma; struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ struct rsnd_kctrl_cfg_s sync; /* sync convert */ u32 convert_rate; /* sampling rate convert */ diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index ad5539def58f..66f9f2a9c167 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -63,7 +63,7 @@ struct rsnd_ssi { struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ struct rsnd_ssi *parent; struct rsnd_mod mod; - struct rsnd_dma *dma; + struct rsnd_mod *dma; u32 cr_own; u32 cr_clk; @@ -630,7 +630,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dma *dma = rsnd_ssi_to_dma(ssi); + struct rsnd_mod *dma = rsnd_ssi_to_dma(ssi); rsnd_dma_start(io, dma); @@ -644,7 +644,7 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dma *dma = rsnd_ssi_to_dma(ssi); + struct rsnd_mod *dma = rsnd_ssi_to_dma(ssi); rsnd_ssi_stop(mod, io, priv); -- cgit v1.2.3 From 76c80b5b3fa666da1a551c47b4597e4efaf2d8c4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:42:46 +0000 Subject: ASoC: rsnd: use mod base common method on DMA phase2 Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. DMA will be implemented as module. Then rsnd_dma_ops will be rebased to rsnd_mod_ops, but these are similar, but different function. This patch modify rsnd_dma_ops same style as rsnd_mod_ops. This is prepare for final merge Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 62 +++++++++++++++++++++++++++++++++--------------- sound/soc/sh/rcar/rsnd.h | 12 +++++++--- sound/soc/sh/rcar/src.c | 6 ++--- sound/soc/sh/rcar/ssi.c | 6 ++--- 4 files changed, 58 insertions(+), 28 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 45d30b8e6226..4905e82c3788 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -52,9 +52,15 @@ struct rsnd_dma_ctrl { struct rsnd_dma_ops { char *name; - void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); - void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); - void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma); + void (*start)(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); + void (*stop)(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); + void (*quit)(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); }; #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) @@ -101,18 +107,23 @@ static void rsnd_dmaen_complete(void *data) rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); } -static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +static void rsnd_dmaen_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); dmaengine_terminate_all(dmaen->chan); } -static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +static void rsnd_dmaen_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct rsnd_mod *user_mod = dma->user_mod; - struct rsnd_priv *priv = rsnd_io_to_priv(io); struct snd_pcm_substream *substream = io->substream; struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; @@ -229,7 +240,7 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, return 0; rsnd_dma_attach_err: - rsnd_dma_quit(io, rsnd_mod_get(dma)); + rsnd_dma_quit(rsnd_mod_get(dma), io, priv); rsnd_dma_channel_err: /* @@ -241,8 +252,11 @@ rsnd_dma_channel_err: return -EAGAIN; } -static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +static void rsnd_dmaen_quit(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); if (dmaen->chan) @@ -352,8 +366,11 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); } -static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +static void rsnd_dmapp_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); int i; rsnd_dmapp_write(dma, 0, PDMACHCR); @@ -365,8 +382,11 @@ static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) } } -static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) +static void rsnd_dmapp_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); @@ -388,8 +408,6 @@ static int rsnd_dmapp_attach(struct rsnd_dai_stream *io, dmac->dmapp_num++; - rsnd_dmapp_stop(io, dma); - dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); @@ -609,30 +627,36 @@ static void rsnd_dma_of_path(struct rsnd_mod *this, } } -void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_mod *mod) +void rsnd_dma_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) + { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - dma->ops->stop(io, dma); + dma->ops->stop(mod, io, priv); } -void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_mod *mod) +void rsnd_dma_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - dma->ops->start(io, dma); + dma->ops->start(mod, io, priv); } -void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_mod *mod) +void rsnd_dma_quit(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); if (!dmac) return; - dma->ops->quit(io, dma); + dma->ops->quit(mod, io, priv); } static struct rsnd_mod_ops rsnd_dma_ops = { diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 6a0bd3e6c8d1..f0b4a71b6a48 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -193,11 +193,17 @@ void rsnd_path_parse(struct rsnd_priv *priv, /* * R-Car DMA */ -void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_mod *mod); -void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_mod *mod); +void rsnd_dma_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); +void rsnd_dma_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); +void rsnd_dma_quit(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv); struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); -void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_mod *mod); int rsnd_dma_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 517a1e176795..b0c653afa7aa 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -843,7 +843,7 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); - rsnd_dma_quit(io, rsnd_src_to_dma(src)); + rsnd_dma_quit(rsnd_src_to_dma(src), io, priv); return 0; } @@ -875,7 +875,7 @@ static int rsnd_src_start_gen2(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); - rsnd_dma_start(io, rsnd_src_to_dma(src)); + rsnd_dma_start(rsnd_src_to_dma(src), io, priv); return _rsnd_src_start_gen2(mod, io); } @@ -889,7 +889,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, ret = _rsnd_src_stop_gen2(mod); - rsnd_dma_stop(io, rsnd_src_to_dma(src)); + rsnd_dma_stop(rsnd_src_to_dma(src), io, priv); return ret; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 66f9f2a9c167..67b6bd55957c 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -596,7 +596,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); int irq = ssi->info->irq; - rsnd_dma_quit(io, rsnd_ssi_to_dma(ssi)); + rsnd_dma_quit(rsnd_ssi_to_dma(ssi), io, priv); /* PIO will request IRQ again */ devm_free_irq(dev, irq, mod); @@ -632,7 +632,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_mod *dma = rsnd_ssi_to_dma(ssi); - rsnd_dma_start(io, dma); + rsnd_dma_start(dma, io, priv); rsnd_ssi_start(mod, io, priv); @@ -648,7 +648,7 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, rsnd_ssi_stop(mod, io, priv); - rsnd_dma_stop(io, dma); + rsnd_dma_stop(dma, io, priv); return 0; } -- cgit v1.2.3 From 497debaa803e25fc0163fe4380335b8626acad44 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:43:01 +0000 Subject: ASoC: rsnd: use mod base common method on DMA phase3 Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. This patch makes DMA mod bse common method Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 154 +++++++++++++++++++---------------------------- sound/soc/sh/rcar/rsnd.h | 9 --- sound/soc/sh/rcar/src.c | 50 +++------------ sound/soc/sh/rcar/ssi.c | 34 +---------- 4 files changed, 71 insertions(+), 176 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 4905e82c3788..fc70e97500ad 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -33,9 +33,7 @@ struct rsnd_dmapp { }; struct rsnd_dma { - struct rsnd_dma_ops *ops; struct rsnd_mod mod; - struct rsnd_mod *user_mod; dma_addr_t src_addr; dma_addr_t dst_addr; union { @@ -50,19 +48,6 @@ struct rsnd_dma_ctrl { int dmapp_num; }; -struct rsnd_dma_ops { - char *name; - void (*start)(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); - void (*stop)(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); - void (*quit)(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); -}; - #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) #define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod) #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) @@ -107,23 +92,24 @@ static void rsnd_dmaen_complete(void *data) rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); } -static void rsnd_dmaen_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_dmaen_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); dmaengine_terminate_all(dmaen->chan); + + return 0; } -static void rsnd_dmaen_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_dmaen_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); - struct rsnd_mod *user_mod = dma->user_mod; struct snd_pcm_substream *substream = io->substream; struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; @@ -138,18 +124,20 @@ static void rsnd_dmaen_start(struct rsnd_mod *mod, if (!desc) { dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); - return; + return -EIO; } desc->callback = rsnd_dmaen_complete; - desc->callback_param = user_mod; + desc->callback_param = rsnd_mod_get(dma); if (dmaengine_submit(desc) < 0) { dev_err(dev, "dmaengine_submit() fail\n"); - return; + return -EIO; } dma_async_issue_pending(dmaen->chan); + + return 0; } struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, @@ -187,10 +175,26 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io, return rsnd_mod_dma_req(io, mod_to); } +static int rsnd_dmaen_remove(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_dma *dma = rsnd_mod_to_dma(mod); + struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); + + if (dmaen->chan) + dma_release_channel(dmaen->chan); + + dmaen->chan = NULL; + + return 0; +} + static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) { + struct rsnd_mod *mod = rsnd_mod_get(dma); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); @@ -227,8 +231,8 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - dev_dbg(dev, "%s %pad -> %pad\n", - dma->ops->name, + dev_dbg(dev, "%s[%d] %pad -> %pad\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), &cfg.src_addr, &cfg.dst_addr); ret = dmaengine_slave_config(dmaen->chan, &cfg); @@ -240,7 +244,7 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io, return 0; rsnd_dma_attach_err: - rsnd_dma_quit(rsnd_mod_get(dma), io, priv); + rsnd_dmaen_remove(mod, io, priv); rsnd_dma_channel_err: /* @@ -252,24 +256,11 @@ rsnd_dma_channel_err: return -EAGAIN; } -static void rsnd_dmaen_quit(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); - - if (dmaen->chan) - dma_release_channel(dmaen->chan); - - dmaen->chan = NULL; -} - -static struct rsnd_dma_ops rsnd_dmaen_ops = { +static struct rsnd_mod_ops rsnd_dmaen_ops = { .name = "audmac", .start = rsnd_dmaen_start, .stop = rsnd_dmaen_stop, - .quit = rsnd_dmaen_quit, + .remove = rsnd_dmaen_remove, }; /* @@ -366,9 +357,9 @@ static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); } -static void rsnd_dmapp_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_dmapp_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); int i; @@ -377,14 +368,16 @@ static void rsnd_dmapp_stop(struct rsnd_mod *mod, for (i = 0; i < 1024; i++) { if (0 == rsnd_dmapp_read(dma, PDMACHCR)) - return; + return -EIO; udelay(1); } + + return 0; } -static void rsnd_dmapp_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_dmapp_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); @@ -392,6 +385,8 @@ static void rsnd_dmapp_start(struct rsnd_mod *mod, rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); + + return 0; } static int rsnd_dmapp_attach(struct rsnd_dai_stream *io, @@ -414,7 +409,7 @@ static int rsnd_dmapp_attach(struct rsnd_dai_stream *io, return 0; } -static struct rsnd_dma_ops rsnd_dmapp_ops = { +static struct rsnd_mod_ops rsnd_dmapp_ops = { .name = "audmac-pp", .start = rsnd_dmapp_start, .stop = rsnd_dmapp_stop, @@ -627,41 +622,6 @@ static void rsnd_dma_of_path(struct rsnd_mod *this, } } -void rsnd_dma_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) - -{ - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - - dma->ops->stop(mod, io, priv); -} - -void rsnd_dma_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - - dma->ops->start(mod, io, priv); -} - -void rsnd_dma_quit(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_dma *dma = rsnd_mod_to_dma(mod); - struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); - - if (!dmac) - return; - - dma->ops->quit(mod, io, priv); -} - -static struct rsnd_mod_ops rsnd_dma_ops = { -}; - struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id) { @@ -672,6 +632,8 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); struct rsnd_dma *dma; struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_mod_ops *ops; + enum rsnd_mod_type type; int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id, struct rsnd_mod *mod_from, struct rsnd_mod *mod_to); int is_play = rsnd_io_is_play(io); @@ -692,37 +654,39 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to); - dma->user_mod = mod; dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); /* for Gen2 */ if (mod_from && mod_to) { - dma->ops = &rsnd_dmapp_ops; + ops = &rsnd_dmapp_ops; attach = rsnd_dmapp_attach; dma_id = dmac->dmapp_num; + type = RSND_MOD_AUDMAPP; } else { - dma->ops = &rsnd_dmaen_ops; + ops = &rsnd_dmaen_ops; attach = rsnd_dmaen_attach; dma_id = dmac->dmaen_num; + type = RSND_MOD_AUDMA; } /* for Gen1, overwrite */ if (rsnd_is_gen1(priv)) { - dma->ops = &rsnd_dmaen_ops; + ops = &rsnd_dmaen_ops; attach = rsnd_dmaen_attach; dma_id = dmac->dmaen_num; + type = RSND_MOD_AUDMA; } dma_mod = rsnd_mod_get(dma); - dev_dbg(dev, "%s %s[%d] -> %s[%d]\n", - dma->ops->name, + dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", + rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod), rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); ret = rsnd_mod_init(priv, dma_mod, - &rsnd_dma_ops, NULL, 0, dma_id); + ops, NULL, type, dma_id); if (ret < 0) return ERR_PTR(ret); @@ -730,6 +694,10 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, if (ret < 0) return ERR_PTR(ret); + ret = rsnd_dai_connect(dma_mod, io, type); + if (ret < 0) + return ERR_PTR(ret); + return rsnd_mod_get(dma); } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index f0b4a71b6a48..8d42642b1a45 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -193,15 +193,6 @@ void rsnd_path_parse(struct rsnd_priv *priv, /* * R-Car DMA */ -void rsnd_dma_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); -void rsnd_dma_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); -void rsnd_dma_quit(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv); struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); int rsnd_dma_probe(struct platform_device *pdev, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index b0c653afa7aa..3faf9d619614 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -632,8 +632,9 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) return ret; } -static int _rsnd_src_start_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) +static int rsnd_src_start_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 val; @@ -661,7 +662,9 @@ static int _rsnd_src_start_gen2(struct rsnd_mod *mod, return 0; } -static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) +static int rsnd_src_stop_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { rsnd_src_irq_disable_gen2(mod); @@ -704,8 +707,8 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, dev_dbg(dev, "%s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - _rsnd_src_stop_gen2(mod); - _rsnd_src_start_gen2(mod, io); + rsnd_src_stop_gen2(mod, io, priv); + rsnd_src_start_gen2(mod, io, priv); } if (src->err > 1024) { @@ -837,17 +840,6 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, return ret; } -static int rsnd_src_remove_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_src *src = rsnd_mod_to_src(mod); - - rsnd_dma_quit(rsnd_src_to_dma(src), io, priv); - - return 0; -} - static int rsnd_src_init_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -869,31 +861,6 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, return 0; } -static int rsnd_src_start_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_src *src = rsnd_mod_to_src(mod); - - rsnd_dma_start(rsnd_src_to_dma(src), io, priv); - - return _rsnd_src_start_gen2(mod, io); -} - -static int rsnd_src_stop_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_src *src = rsnd_mod_to_src(mod); - int ret; - - ret = _rsnd_src_stop_gen2(mod); - - rsnd_dma_stop(rsnd_src_to_dma(src), io, priv); - - return ret; -} - static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { @@ -958,7 +925,6 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = { .name = SRC_NAME, .dma_req = rsnd_src_dma_req, .probe = rsnd_src_probe_gen2, - .remove = rsnd_src_remove_gen2, .init = rsnd_src_init_gen2, .quit = rsnd_src_quit_gen2, .start = rsnd_src_start_gen2, diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 67b6bd55957c..a4e5c55eec5b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -596,8 +596,6 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); int irq = ssi->info->irq; - rsnd_dma_quit(rsnd_ssi_to_dma(ssi), io, priv); - /* PIO will request IRQ again */ devm_free_irq(dev, irq, mod); @@ -625,34 +623,6 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, return 0; } -static int rsnd_ssi_dma_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *dma = rsnd_ssi_to_dma(ssi); - - rsnd_dma_start(dma, io, priv); - - rsnd_ssi_start(mod, io, priv); - - return 0; -} - -static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *dma = rsnd_ssi_to_dma(ssi); - - rsnd_ssi_stop(mod, io, priv); - - rsnd_dma_stop(dma, io, priv); - - return 0; -} - static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { @@ -676,8 +646,8 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .remove = rsnd_ssi_dma_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, - .start = rsnd_ssi_dma_start, - .stop = rsnd_ssi_dma_stop, + .start = rsnd_ssi_start, + .stop = rsnd_ssi_stop, .fallback = rsnd_ssi_fallback, .hw_params = rsnd_ssi_hw_params, }; -- cgit v1.2.3 From 1b2ca0adf1a0cb3aa766259650eddd25b44486b7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:43:21 +0000 Subject: ASoC: rsnd: use mod base common method on CMD Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. This patch makes CMD mod base common method Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/Makefile | 2 +- sound/soc/sh/rcar/cmd.c | 153 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/sh/rcar/core.c | 75 +--------------------- sound/soc/sh/rcar/ctu.c | 8 +++ sound/soc/sh/rcar/dvc.c | 18 ++++-- sound/soc/sh/rcar/mix.c | 10 ++- sound/soc/sh/rcar/rsnd.h | 20 +++++- 7 files changed, 202 insertions(+), 84 deletions(-) create mode 100644 sound/soc/sh/rcar/cmd.c (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index 8b258501aa35..5f1000269cfb 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile @@ -1,4 +1,4 @@ -snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o +snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o cmd.o obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o snd-soc-rsrc-card-objs := rsrc-card.o diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c new file mode 100644 index 000000000000..731d74b13e92 --- /dev/null +++ b/sound/soc/sh/rcar/cmd.c @@ -0,0 +1,153 @@ +/* + * Renesas R-Car CMD support + * + * Copyright (C) 2015 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include "rsnd.h" + +struct rsnd_cmd { + struct rsnd_mod mod; +}; + +#define CMD_NAME "cmd" + +#define rsnd_cmd_nr(priv) ((priv)->cmd_nr) +#define for_each_rsnd_cmd(pos, priv, i) \ + for ((i) = 0; \ + ((i) < rsnd_cmd_nr(priv)) && \ + ((pos) = (struct rsnd_cmd *)(priv)->cmd + i); \ + i++) + +static int rsnd_cmd_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); + struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); + struct rsnd_mod *src = rsnd_io_to_mod_src(io); + struct device *dev = rsnd_priv_to_dev(priv); + u32 data; + + if (!mix && !dvc) + return 0; + + if (mix) { + struct rsnd_dai *rdai; + int i; + u32 path[] = { + [0] = 0, + [1] = 1 << 0, + [2] = 0, + [3] = 0, + [4] = 0, + [5] = 1 << 8 + }; + + /* + * it is assuming that integrater is well understanding about + * data path. Here doesn't check impossible connection, + * like src2 + src5 + */ + data = 0; + for_each_rsnd_dai(rdai, priv, i) { + io = &rdai->playback; + if (mix == rsnd_io_to_mod_mix(io)) + data |= path[rsnd_mod_id(src)]; + + io = &rdai->capture; + if (mix == rsnd_io_to_mod_mix(io)) + data |= path[rsnd_mod_id(src)]; + } + + } else { + u32 path[] = { + [0] = 0x30000, + [1] = 0x30001, + [2] = 0x40000, + [3] = 0x10000, + [4] = 0x20000, + [5] = 0x40100 + }; + + data = path[rsnd_mod_id(src)]; + } + + dev_dbg(dev, "ctu/mix path = 0x%08x", data); + + rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); + + rsnd_mod_write(mod, CMD_CTRL, 0x10); + + return 0; +} + +static struct rsnd_mod_ops rsnd_cmd_ops = { + .name = CMD_NAME, + .init = rsnd_cmd_init, +}; + +int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id) +{ + struct rsnd_priv *priv = rsnd_io_to_priv(io); + struct rsnd_mod *mod = rsnd_cmd_mod_get(priv, id); + + return rsnd_dai_connect(mod, io, mod->type); +} + +struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id) +{ + if (WARN_ON(id < 0 || id >= rsnd_cmd_nr(priv))) + id = 0; + + return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id); +} + +int rsnd_cmd_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_cmd *cmd; + int i, nr, ret; + + /* This driver doesn't support Gen1 at this point */ + if (rsnd_is_gen1(priv)) + return 0; + + /* same number as DVC */ + nr = priv->dvc_nr; + if (!nr) + return 0; + + cmd = devm_kzalloc(dev, sizeof(*cmd) * nr, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + priv->cmd_nr = nr; + priv->cmd = cmd; + + for_each_rsnd_cmd(cmd, priv, i) { + ret = rsnd_mod_init(priv, rsnd_mod_get(cmd), + &rsnd_cmd_ops, NULL, RSND_MOD_CMD, i); + if (ret) + return ret; + } + + return 0; +} + +void rsnd_cmd_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_cmd *cmd; + int i; + + for_each_rsnd_cmd(cmd, priv, i) { + rsnd_mod_quit(rsnd_mod_get(cmd)); + } +} diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8af2d22d0cd3..1cbd20f311b8 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -589,79 +589,6 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { ret; \ }) -void rsnd_path_parse(struct rsnd_priv *priv, - struct rsnd_dai_stream *io) -{ - struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); - struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); - struct rsnd_mod *src = rsnd_io_to_mod_src(io); - struct rsnd_mod *cmd; - struct device *dev = rsnd_priv_to_dev(priv); - u32 data; - - /* Gen1 is not supported */ - if (rsnd_is_gen1(priv)) - return; - - if (!mix && !dvc) - return; - - if (mix) { - struct rsnd_dai *rdai; - int i; - u32 path[] = { - [0] = 0, - [1] = 1 << 0, - [2] = 0, - [3] = 0, - [4] = 0, - [5] = 1 << 8 - }; - - /* - * it is assuming that integrater is well understanding about - * data path. Here doesn't check impossible connection, - * like src2 + src5 - */ - data = 0; - for_each_rsnd_dai(rdai, priv, i) { - io = &rdai->playback; - if (mix == rsnd_io_to_mod_mix(io)) - data |= path[rsnd_mod_id(src)]; - - io = &rdai->capture; - if (mix == rsnd_io_to_mod_mix(io)) - data |= path[rsnd_mod_id(src)]; - } - - /* - * We can't use ctu = rsnd_io_ctu() here. - * Since, ID of dvc/mix are 0 or 1 (= same as CMD number) - * but ctu IDs are 0 - 7 (= CTU00 - CTU13) - */ - cmd = mix; - } else { - u32 path[] = { - [0] = 0x30000, - [1] = 0x30001, - [2] = 0x40000, - [3] = 0x10000, - [4] = 0x20000, - [5] = 0x40100 - }; - - data = path[rsnd_mod_id(src)]; - - cmd = dvc; - } - - dev_dbg(dev, "ctu/mix path = 0x%08x", data); - - rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data); - - rsnd_mod_write(cmd, CMD_CTRL, 0x10); -} - static int rsnd_path_init(struct rsnd_priv *priv, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -1208,6 +1135,7 @@ static int rsnd_probe(struct platform_device *pdev) rsnd_ctu_probe, rsnd_mix_probe, rsnd_dvc_probe, + rsnd_cmd_probe, rsnd_adg_probe, rsnd_dai_probe, }; @@ -1296,6 +1224,7 @@ static int rsnd_remove(struct platform_device *pdev) rsnd_ctu_remove, rsnd_mix_remove, rsnd_dvc_remove, + rsnd_cmd_remove, }; int ret = 0, i; diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 3cb214ab848b..6b76ae6cf549 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -31,6 +31,13 @@ static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable) rsnd_mod_write(mod, CTU_CTUIR, enable); } +static int rsnd_ctu_probe_(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + return rsnd_cmd_attach(io, rsnd_mod_id(mod) / 4); +} + static int rsnd_ctu_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -57,6 +64,7 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_ctu_ops = { .name = CTU_NAME, + .probe = rsnd_ctu_probe_, .init = rsnd_ctu_init, .quit = rsnd_ctu_quit, }; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 58f690900e6d..d207000efef0 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -134,9 +134,16 @@ static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, rsnd_mod_write(mod, DVC_DVUER, 1); } -static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_dvc_probe_(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + return rsnd_cmd_attach(io, rsnd_mod_id(mod)); +} + +static int rsnd_dvc_remove_(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); @@ -159,8 +166,6 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, rsnd_dvc_initialize_lock(mod); - rsnd_path_parse(priv, io); - rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); /* ch0/ch1 Volume */ @@ -269,7 +274,8 @@ static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io, static struct rsnd_mod_ops rsnd_dvc_ops = { .name = DVC_NAME, .dma_req = rsnd_dvc_dma_req, - .remove = rsnd_dvc_remove_gen2, + .probe = rsnd_dvc_probe_, + .remove = rsnd_dvc_remove_, .init = rsnd_dvc_init, .quit = rsnd_dvc_quit, .start = rsnd_dvc_start, diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 953dd0be9b60..bcbd821981a9 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -54,6 +54,13 @@ static void rsnd_mix_volume_update(struct rsnd_dai_stream *io, rsnd_mod_write(mod, MIX_MDBER, 1); } +static int rsnd_mix_probe_(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + return rsnd_cmd_attach(io, rsnd_mod_id(mod)); +} + static int rsnd_mix_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -66,8 +73,6 @@ static int rsnd_mix_init(struct rsnd_mod *mod, rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io)); - rsnd_path_parse(priv, io); - /* volume step */ rsnd_mod_write(mod, MIX_MIXMR, 0); rsnd_mod_write(mod, MIX_MVPDR, 0); @@ -90,6 +95,7 @@ static int rsnd_mix_quit(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_mix_ops = { .name = MIX_NAME, + .probe = rsnd_mix_probe_, .init = rsnd_mix_init, .quit = rsnd_mix_quit, }; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 8d42642b1a45..5286f28de831 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -187,8 +187,6 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io); u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); -void rsnd_path_parse(struct rsnd_priv *priv, - struct rsnd_dai_stream *io); /* * R-Car DMA @@ -210,6 +208,7 @@ enum rsnd_mod_type { RSND_MOD_DVC, RSND_MOD_MIX, RSND_MOD_CTU, + RSND_MOD_CMD, RSND_MOD_SRC, RSND_MOD_SSI, RSND_MOD_MAX, @@ -474,6 +473,12 @@ struct rsnd_priv { void *dvc; int dvc_nr; + /* + * below value will be filled on rsnd_cmd_probe() + */ + void *cmd; + int cmd_nr; + /* * below value will be filled on rsnd_dai_probe() */ @@ -606,6 +611,17 @@ void rsnd_dvc_remove(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); +/* + * R-Car CMD + */ +int rsnd_cmd_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv); +void rsnd_cmd_remove(struct platform_device *pdev, + struct rsnd_priv *priv); +int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); +struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); + #ifdef DEBUG void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); #define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) -- cgit v1.2.3 From c7f69ab5364da21a2fc7f01c5bc32a5b5b5fee5d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:43:41 +0000 Subject: ASoC: rsnd: use mod base common method on SSIU Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. This patch makes SSIU mod base common method Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/Makefile | 2 +- sound/soc/sh/rcar/core.c | 2 + sound/soc/sh/rcar/rsnd.h | 23 ++++-- sound/soc/sh/rcar/src.c | 65 ---------------- sound/soc/sh/rcar/ssi.c | 22 +++--- sound/soc/sh/rcar/ssiu.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 211 insertions(+), 84 deletions(-) create mode 100644 sound/soc/sh/rcar/ssiu.c (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index 5f1000269cfb..a89ddf758695 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile @@ -1,4 +1,4 @@ -snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o cmd.o +snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o snd-soc-rsrc-card-objs := rsrc-card.o diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1cbd20f311b8..5586b888db56 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1131,6 +1131,7 @@ static int rsnd_probe(struct platform_device *pdev) rsnd_gen_probe, rsnd_dma_probe, rsnd_ssi_probe, + rsnd_ssiu_probe, rsnd_src_probe, rsnd_ctu_probe, rsnd_mix_probe, @@ -1220,6 +1221,7 @@ static int rsnd_remove(struct platform_device *pdev) void (*remove_func[])(struct platform_device *pdev, struct rsnd_priv *priv) = { rsnd_ssi_remove, + rsnd_ssiu_remove, rsnd_src_remove, rsnd_ctu_remove, rsnd_mix_remove, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5286f28de831..81c789f8e9a6 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -210,6 +210,7 @@ enum rsnd_mod_type { RSND_MOD_CTU, RSND_MOD_CMD, RSND_MOD_SRC, + RSND_MOD_SSIU, RSND_MOD_SSI, RSND_MOD_MAX, }; @@ -449,6 +450,12 @@ struct rsnd_priv { void *ssi; int ssi_nr; + /* + * below value will be filled on rsnd_ssiu_probe() + */ + void *ssiu; + int ssiu_nr; + /* * below value will be filled on rsnd_src_probe() */ @@ -561,6 +568,17 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); +/* + * R-Car SSIU + */ +int rsnd_ssiu_attach(struct rsnd_dai_stream *io, + struct rsnd_mod *mod); +int rsnd_ssiu_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv); +void rsnd_ssiu_remove(struct platform_device *pdev, + struct rsnd_priv *priv); + /* * R-Car SRC */ @@ -573,11 +591,6 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, struct snd_pcm_runtime *runtime); -int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, - struct rsnd_dai_stream *io, - int use_busif); -int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, - struct rsnd_dai_stream *io); /* * R-Car CTU diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 3faf9d619614..a710799cb3a1 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -145,71 +145,6 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, is_play ? "rx" : "tx"); } -int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, - struct rsnd_dai_stream *io, - int use_busif) -{ - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - int ssi_id = rsnd_mod_id(ssi_mod); - - /* - * SSI_MODE0 - */ - rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), - !use_busif << ssi_id); - - /* - * SSI_MODE1 - */ - if (rsnd_ssi_is_pin_sharing(io)) { - int shift = -1; - switch (ssi_id) { - case 1: - shift = 0; - break; - case 2: - shift = 2; - break; - case 4: - shift = 16; - break; - } - - if (shift >= 0) - rsnd_mod_bset(ssi_mod, SSI_MODE1, - 0x3 << shift, - rsnd_rdai_is_clk_master(rdai) ? - 0x2 << shift : 0x1 << shift); - } - - /* - * DMA settings for SSIU - */ - if (use_busif) { - u32 val = rsnd_get_dalign(ssi_mod, io); - - rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, - rsnd_get_adinr_bit(ssi_mod, io)); - rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); - rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); - - rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val); - } - - return 0; -} - -int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, - struct rsnd_dai_stream *io) -{ - /* - * DMA settings for SSIU - */ - rsnd_mod_write(ssi_mod, SSI_CTRL, 0); - - return 0; -} - static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, struct rsnd_src *src) { diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index a4e5c55eec5b..bb08d6624d7d 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -438,8 +438,6 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io)); - rsnd_ssi_hw_start(ssi, io); rsnd_ssi_irq_enable(mod); @@ -459,8 +457,6 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, rsnd_ssi_hw_stop(io, ssi); - rsnd_src_ssiu_stop(mod, io); - return 0; } @@ -539,14 +535,18 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) /* * SSI PIO */ -static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_ssi_common_probe(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); int ret; + ret = rsnd_ssiu_attach(io, mod); + if (ret < 0) + return ret; + ret = devm_request_irq(dev, ssi->info->irq, rsnd_ssi_interrupt, IRQF_SHARED, @@ -557,7 +557,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .name = SSI_NAME, - .probe = rsnd_ssi_pio_probe, + .probe = rsnd_ssi_common_probe, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -570,14 +570,10 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct device *dev = rsnd_priv_to_dev(priv); int dma_id = ssi->info->dma_id; int ret; - ret = devm_request_irq(dev, ssi->info->irq, - rsnd_ssi_interrupt, - IRQF_SHARED, - dev_name(dev), mod); + ret = rsnd_ssi_common_probe(mod, io, priv); if (ret) return ret; diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c new file mode 100644 index 000000000000..fc5ec17fe37e --- /dev/null +++ b/sound/soc/sh/rcar/ssiu.c @@ -0,0 +1,181 @@ +/* + * Renesas R-Car SSIU support + * + * Copyright (c) 2015 Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include "rsnd.h" + +#define SSIU_NAME "ssiu" + +struct rsnd_ssiu { + struct rsnd_mod mod; +}; + +#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr) +#define for_each_rsnd_ssiu(pos, priv, i) \ + for (i = 0; \ + (i < rsnd_ssiu_nr(priv)) && \ + ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \ + i++) + +static int rsnd_ssiu_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + int use_busif = rsnd_ssi_use_busif(io); + int id = rsnd_mod_id(mod); + + /* + * SSI_MODE0 + */ + rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id); + + /* + * SSI_MODE1 + */ + if (rsnd_ssi_is_pin_sharing(io)) { + int shift = -1; + + switch (id) { + case 1: + shift = 0; + break; + case 2: + shift = 2; + break; + case 4: + shift = 16; + break; + } + + if (shift >= 0) + rsnd_mod_bset(mod, SSI_MODE1, + 0x3 << shift, + rsnd_rdai_is_clk_master(rdai) ? + 0x2 << shift : 0x1 << shift); + } + + return 0; +} + +static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = { + .name = SSIU_NAME, + .init = rsnd_ssiu_init, +}; + +static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + int ret; + + ret = rsnd_ssiu_init(mod, io, priv); + if (ret < 0) + return ret; + + if (rsnd_ssi_use_busif(io)) { + u32 val = rsnd_get_dalign(mod, io); + + rsnd_mod_write(mod, SSI_BUSIF_ADINR, + rsnd_get_adinr_bit(mod, io)); + rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); + rsnd_mod_write(mod, SSI_BUSIF_DALIGN, val); + } + + return 0; +} + +static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + if (rsnd_ssi_use_busif(io)) + rsnd_mod_write(mod, SSI_CTRL, 0x1); + + return 0; +} + +static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + if (rsnd_ssi_use_busif(io)) + rsnd_mod_write(mod, SSI_CTRL, 0); + + return 0; +} + +static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = { + .name = SSIU_NAME, + .init = rsnd_ssiu_init_gen2, + .start = rsnd_ssiu_start_gen2, + .stop = rsnd_ssiu_stop_gen2, +}; + +static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id) +{ + if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv))) + id = 0; + + return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id); +} + +int rsnd_ssiu_attach(struct rsnd_dai_stream *io, + struct rsnd_mod *ssi_mod) +{ + struct rsnd_priv *priv = rsnd_io_to_priv(io); + struct rsnd_mod *mod = rsnd_ssiu_mod_get(priv, rsnd_mod_id(ssi_mod)); + + rsnd_mod_confirm_ssi(ssi_mod); + + return rsnd_dai_connect(mod, io, mod->type); +} + +int rsnd_ssiu_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_ssiu *ssiu; + static struct rsnd_mod_ops *ops; + int i, nr, ret; + + /* same number to SSI */ + nr = priv->ssi_nr; + ssiu = devm_kzalloc(dev, sizeof(*ssiu) * nr, GFP_KERNEL); + if (!ssiu) + return -ENOMEM; + + priv->ssiu = ssiu; + priv->ssiu_nr = nr; + + if (rsnd_is_gen1(priv)) + ops = &rsnd_ssiu_ops_gen1; + else + ops = &rsnd_ssiu_ops_gen2; + + for_each_rsnd_ssiu(ssiu, priv, i) { + ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu), + ops, NULL, RSND_MOD_SSIU, i); + if (ret) + return ret; + } + + return 0; +} + +void rsnd_ssiu_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_ssiu *ssiu; + int i; + + for_each_rsnd_ssiu(ssiu, priv, i) { + rsnd_mod_quit(rsnd_mod_get(ssiu)); + } +} -- cgit v1.2.3 From e7d850dd10f4e61b728495a87ce096509843315f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 26 Oct 2015 08:43:57 +0000 Subject: ASoC: rsnd: use mod base common method on SSI-parent Renesas sound needs many devices (SSI/SSIU/SRC/CTU/MIX/DVC/CMD/AudioDMAC/AudioDMACpp). SSI/SRC/CTU/MIX/DVC are implemented as module. SSI parent, SSIU are implemented as part of SSI CMD is implemented as part of CTU/MIX/DVC AudioDMAC/AudioDMACpp are implemented as part of SSI/SRC It is nice sense that these all devices are implemented as mod. This patch makes SSI parent mod base common method Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsnd.h | 2 + sound/soc/sh/rcar/ssi.c | 301 +++++++++++++++++++++++++---------------------- 2 files changed, 161 insertions(+), 142 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 81c789f8e9a6..599dfb69555a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -211,6 +211,7 @@ enum rsnd_mod_type { RSND_MOD_CMD, RSND_MOD_SRC, RSND_MOD_SSIU, + RSND_MOD_SSIP, /* SSI parent */ RSND_MOD_SSI, RSND_MOD_MAX, }; @@ -339,6 +340,7 @@ struct rsnd_dai_stream { }; #define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) #define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) +#define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP) #define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC) #define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) #define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index bb08d6624d7d..3e814711f301 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -67,7 +67,9 @@ struct rsnd_ssi { u32 cr_own; u32 cr_clk; + u32 cr_mode; int chan; + int rate; int err; unsigned int usrcnt; }; @@ -82,9 +84,9 @@ struct rsnd_ssi { #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) -#define rsnd_ssi_parent(ssi) ((ssi)->parent) #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) +#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) #define rsnd_ssi_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") @@ -168,7 +170,9 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, struct rsnd_priv *priv = rsnd_io_to_priv(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_mod *mod = rsnd_mod_get(ssi); + struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); int j, ret; int ssi_clk_mul_table[] = { 1, 2, 4, 8, 16, 6, 12, @@ -176,6 +180,21 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, unsigned int main_rate; unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime); + if (!rsnd_rdai_is_clk_master(rdai)) + return 0; + + if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + return 0; + + if (ssi->usrcnt > 1) { + if (ssi->rate != rate) { + dev_err(dev, "SSI parent/child should use same rate\n"); + return -EINVAL; + } + + return 0; + } + /* * Find best clock, and try to start ADG */ @@ -193,6 +212,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(j); + ssi->rate = rate; + + rsnd_mod_write(mod, SSIWSR, CONT); + dev_dbg(dev, "%s[%d] outputs %u Hz\n", rsnd_mod_name(mod), rsnd_mod_id(mod), rate); @@ -205,113 +228,26 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, return -EIO; } -static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) -{ - struct rsnd_mod *mod = rsnd_mod_get(ssi); - - ssi->cr_clk = 0; - rsnd_adg_ssi_clk_stop(mod); -} - -static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, - struct rsnd_dai_stream *io) +static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi, + struct rsnd_dai_stream *io) { - struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_mod *mod = rsnd_mod_get(ssi); - u32 cr_mode; - u32 cr; - - if (0 == ssi->usrcnt) { - rsnd_mod_power_on(mod); - - if (rsnd_rdai_is_clk_master(rdai)) { - struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); - - if (ssi_parent) - rsnd_ssi_hw_start(ssi_parent, io); - else - rsnd_ssi_master_clk_start(ssi, io); - } - } - - if (rsnd_ssi_is_dma_mode(mod)) { - cr_mode = UIEN | OIEN | /* over/under run */ - DMEN; /* DMA : enable DMA */ - } else { - cr_mode = DIEN; /* PIO : enable Data interrupt */ - } - - cr = ssi->cr_own | - ssi->cr_clk | - cr_mode | - EN; - - rsnd_mod_write(mod, SSICR, cr); - - /* enable WS continue */ - if (rsnd_rdai_is_clk_master(rdai)) - rsnd_mod_write(mod, SSIWSR, CONT); - - /* clear error status */ - rsnd_ssi_status_clear(mod); + struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); - ssi->usrcnt++; - - dev_dbg(dev, "%s[%d] hw started\n", - rsnd_mod_name(mod), rsnd_mod_id(mod)); -} - -static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) -{ - struct rsnd_mod *mod = rsnd_mod_get(ssi); - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - struct device *dev = rsnd_priv_to_dev(priv); - u32 cr; - - if (0 == ssi->usrcnt) { - dev_err(dev, "%s called without starting\n", __func__); + if (!rsnd_rdai_is_clk_master(rdai)) return; - } - - ssi->usrcnt--; - - if (0 == ssi->usrcnt) { - /* - * disable all IRQ, - * and, wait all data was sent - */ - cr = ssi->cr_own | - ssi->cr_clk; - - rsnd_mod_write(mod, SSICR, cr | EN); - rsnd_ssi_status_check(mod, DIRQ); - - /* - * disable SSI, - * and, wait idle state - */ - rsnd_mod_write(mod, SSICR, cr); /* disabled all */ - rsnd_ssi_status_check(mod, IIRQ); - if (rsnd_rdai_is_clk_master(rdai)) { - struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); - - if (ssi_parent) - rsnd_ssi_hw_stop(io, ssi_parent); - else - rsnd_ssi_master_clk_stop(ssi); - } + if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + return; - rsnd_mod_power_off(mod); + if (ssi->usrcnt > 1) + return; - ssi->chan = 0; - } + ssi->cr_clk = 0; + ssi->rate = 0; - dev_dbg(dev, "%s[%d] hw stopped\n", - rsnd_mod_name(mod), rsnd_mod_id(mod)); + rsnd_adg_ssi_clk_stop(mod); } /* @@ -325,6 +261,18 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); u32 cr; + int ret; + + ssi->usrcnt++; + + rsnd_mod_power_on(mod); + + ret = rsnd_ssi_master_clk_start(ssi, io); + if (ret < 0) + return ret; + + if (rsnd_ssi_is_parent(mod, io)) + return 0; cr = FORCE; @@ -359,12 +307,24 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (rsnd_io_is_play(io)) cr |= TRMD; - /* - * set ssi parameter - */ ssi->cr_own = cr; + + if (rsnd_ssi_is_dma_mode(mod)) { + cr = UIEN | OIEN | /* over/under run */ + DMEN; /* DMA : enable DMA */ + } else { + cr = DIEN; /* PIO : enable Data interrupt */ + } + + ssi->cr_mode = cr; + ssi->err = -1; /* ignore 1st error */ + /* clear error status */ + rsnd_ssi_status_clear(mod); + + rsnd_ssi_irq_enable(mod); + return 0; } @@ -375,6 +335,9 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct device *dev = rsnd_priv_to_dev(priv); + if (rsnd_ssi_is_parent(mod, io)) + goto rsnd_ssi_quit_end; + if (ssi->err > 0) dev_warn(dev, "%s[%d] under/over flow err = %d\n", rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err); @@ -382,6 +345,19 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, ssi->cr_own = 0; ssi->err = 0; + rsnd_ssi_irq_disable(mod); + +rsnd_ssi_quit_end: + rsnd_ssi_master_clk_stop(ssi, io); + + rsnd_mod_power_off(mod); + + ssi->usrcnt--; + + if (ssi->usrcnt < 0) + dev_err(dev, "%s[%d] usrcnt error\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + return 0; } @@ -391,14 +367,13 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, struct snd_pcm_hw_params *params) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); int chan = params_channels(params); /* * Already working. * It will happen if SSI has parent/child connection. */ - if (ssi->usrcnt) { + if (ssi->usrcnt > 1) { /* * it is error if child <-> parent SSI uses * different channels. @@ -407,11 +382,7 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, return -EIO; } - /* It will be removed on rsnd_ssi_hw_stop */ ssi->chan = chan; - if (ssi_parent) - return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io, - substream, params); return 0; } @@ -432,15 +403,59 @@ static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi) return status; } +static int __rsnd_ssi_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + u32 cr; + + cr = ssi->cr_own | + ssi->cr_clk | + ssi->cr_mode | + EN; + + rsnd_mod_write(mod, SSICR, cr); + + return 0; +} + static int rsnd_ssi_start(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) +{ + /* + * no limit to start + * see also + * rsnd_ssi_stop + * rsnd_ssi_interrupt + */ + return __rsnd_ssi_start(mod, io, priv); +} + +static int __rsnd_ssi_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + u32 cr; + + /* + * disable all IRQ, + * and, wait all data was sent + */ + cr = ssi->cr_own | + ssi->cr_clk; - rsnd_ssi_hw_start(ssi, io); + rsnd_mod_write(mod, SSICR, cr | EN); + rsnd_ssi_status_check(mod, DIRQ); - rsnd_ssi_irq_enable(mod); + /* + * disable SSI, + * and, wait idle state + */ + rsnd_mod_write(mod, SSICR, cr); /* disabled all */ + rsnd_ssi_status_check(mod, IIRQ); return 0; } @@ -451,13 +466,16 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - rsnd_ssi_irq_disable(mod); - - rsnd_ssi_record_error(ssi); - - rsnd_ssi_hw_stop(io, ssi); + /* + * don't stop if not last user + * see also + * rsnd_ssi_start + * rsnd_ssi_interrupt + */ + if (ssi->usrcnt > 1) + return 0; - return 0; + return __rsnd_ssi_stop(mod, io, priv); } static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, @@ -505,8 +523,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, dev_dbg(dev, "%s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - rsnd_ssi_stop(mod, io, priv); - rsnd_ssi_start(mod, io, priv); + __rsnd_ssi_stop(mod, io, priv); + __rsnd_ssi_start(mod, io, priv); } if (ssi->err > 1024) { @@ -535,6 +553,27 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) /* * SSI PIO */ +static void rsnd_ssi_parent_attach(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + if (!__rsnd_ssi_is_pin_sharing(mod)) + return; + + switch (rsnd_mod_id(mod)) { + case 1: + case 2: + rsnd_dai_connect(rsnd_ssi_mod_get(priv, 0), io, RSND_MOD_SSIP); + break; + case 4: + rsnd_dai_connect(rsnd_ssi_mod_get(priv, 3), io, RSND_MOD_SSIP); + break; + case 8: + rsnd_dai_connect(rsnd_ssi_mod_get(priv, 7), io, RSND_MOD_SSIP); + break; + } +} + static int rsnd_ssi_common_probe(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -543,6 +582,8 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); int ret; + rsnd_ssi_parent_attach(mod, io, priv); + ret = rsnd_ssiu_attach(io, mod); if (ret < 0) return ret; @@ -679,28 +720,6 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); } -static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) -{ - struct rsnd_mod *mod = rsnd_mod_get(ssi); - - if (!__rsnd_ssi_is_pin_sharing(mod)) - return; - - switch (rsnd_mod_id(mod)) { - case 1: - case 2: - ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); - break; - case 4: - ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 3)); - break; - case 8: - ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 7)); - break; - } -} - - static void rsnd_of_parse_ssi(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) @@ -810,8 +829,6 @@ int rsnd_ssi_probe(struct platform_device *pdev, RSND_MOD_SSI, i); if (ret) return ret; - - rsnd_ssi_parent_setup(priv, ssi); } return 0; -- cgit v1.2.3 From f36a82264d5a4ba90f093d397d65b7fdc763885a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 28 Oct 2015 04:30:11 +0000 Subject: ASoC: rsnd: call rsnd_src_quit() from rsnd_src_quit_gen2() 2d604e03("ASoC: rsnd: disable SRC.out only when stop timing") added rsnd_src_quit_gen2(), but it should call rsnd_src_quit() same as before. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index a710799cb3a1..776b0efec4d6 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -621,7 +621,7 @@ static int rsnd_src_quit_gen2(struct rsnd_mod *mod, /* stop both out/in */ rsnd_mod_write(mod, SRC_CTRL, 0); - return 0; + return rsnd_src_quit(mod, io, priv); } static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, -- cgit v1.2.3 From 9c66eedc17bdf180d952e8d3550a23c2f93d9fff Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 28 Oct 2015 04:31:03 +0000 Subject: ASoC: rsnd: fixup rsnd_dmapp_stop() return value 45a4394d03("ASoC: rsnd: use mod base common method on DMA phase3") Exchanged "void rsnd_dmapp_stop()" to "int rsnd_dmapp_stop()", but it returns inverted value. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index fc70e97500ad..9917b985c403 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -368,11 +368,11 @@ static int rsnd_dmapp_stop(struct rsnd_mod *mod, for (i = 0; i < 1024; i++) { if (0 == rsnd_dmapp_read(dma, PDMACHCR)) - return -EIO; + return 0; udelay(1); } - return 0; + return -EIO; } static int rsnd_dmapp_start(struct rsnd_mod *mod, -- cgit v1.2.3 From 8b27418f300cafbdbbb8cfa9c29d398ed34d6723 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 28 Oct 2015 16:03:48 +0100 Subject: ASoC: rsnd: Add missing initialization of ADG req_rate If the "clock-frequency" DT property is not found, req_rate is used uninitialized, and the "audio_clkout" clock will be created with an arbitrary clock rate. This uninitialized kernel stack data may leak to userspace through /sys/kernel/debug/clk/clk_summary, cfr. the value in the "rate" column: clock enable_cnt prepare_cnt rate accuracy phase -------------------------------------------------------------------- audio_clkout 0 0 4001836240 0 0 Signed-off-by: Geert Uytterhoeven Acked-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 2a5b3a293cd2..b123734f9fbd 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -437,7 +437,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np = dev->of_node; u32 ckr, rbgx, rbga, rbgb; - u32 rate, req_rate, div; + u32 rate, req_rate = 0, div; uint32_t count = 0; unsigned long req_48kHz_rate, req_441kHz_rate; int i; -- cgit v1.2.3 From dcc5a7b3b069cca17f3c5254006c66b99e87ffd3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 4 Nov 2015 08:43:33 +0000 Subject: ASoC: rsnd: move CMD related operation to cmd.c 8cca6e11c1 ("ASoC: rsnd: use mod base common method on CMD") added cmd.c. Let's move CMD related operation to cmd.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/cmd.c | 20 ++++++++++++++++++++ sound/soc/sh/rcar/dvc.c | 24 +----------------------- 2 files changed, 21 insertions(+), 23 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index 731d74b13e92..47ef47c22217 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c @@ -81,14 +81,34 @@ static int rsnd_cmd_init(struct rsnd_mod *mod, rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); + rsnd_adg_set_cmd_timsel_gen2(mod, io); + + return 0; +} + +static int rsnd_cmd_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ rsnd_mod_write(mod, CMD_CTRL, 0x10); return 0; } +static int rsnd_cmd_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + rsnd_mod_write(mod, CMD_CTRL, 0); + + return 0; +} + static struct rsnd_mod_ops rsnd_cmd_ops = { .name = CMD_NAME, .init = rsnd_cmd_init, + .start = rsnd_cmd_start, + .stop = rsnd_cmd_stop, }; int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index d207000efef0..651c057b2113 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -171,7 +171,7 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, /* ch0/ch1 Volume */ rsnd_dvc_volume_update(io, mod); - rsnd_adg_set_cmd_timsel_gen2(mod, io); + rsnd_dvc_initialize_unlock(mod); return 0; } @@ -185,26 +185,6 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod, return 0; } -static int rsnd_dvc_start(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - rsnd_dvc_initialize_unlock(mod); - - rsnd_mod_write(mod, CMD_CTRL, 0x10); - - return 0; -} - -static int rsnd_dvc_stop(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - rsnd_mod_write(mod, CMD_CTRL, 0); - - return 0; -} - static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd) @@ -278,8 +258,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = { .remove = rsnd_dvc_remove_, .init = rsnd_dvc_init, .quit = rsnd_dvc_quit, - .start = rsnd_dvc_start, - .stop = rsnd_dvc_stop, .pcm_new = rsnd_dvc_pcm_new, }; -- cgit v1.2.3 From ca16cc61592377ebd48d5f22fd823b592c80038e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 4 Nov 2015 08:44:12 +0000 Subject: ASoC: rsnd: DVC settings matches to datasheet Current DVC settings order was rough. This patch makes it match to datasheet. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 119 +++++++++++++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 42 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 651c057b2113..0dc8a2a99fa4 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -70,65 +70,105 @@ static void rsnd_dvc_soft_reset(struct rsnd_mod *mod) rsnd_mod_write(mod, DVC_SWRSR, 1); } -#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1) -#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0) -static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable) -{ - rsnd_mod_write(mod, DVC_DVUIR, enable); -} +#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val) +#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13)) -static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, - struct rsnd_mod *mod) +static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); u32 val[RSND_DVC_CHANNELS]; - u32 dvucr = 0; - u32 mute = 0; int i; - for (i = 0; i < dvc->mute.cfg.size; i++) - mute |= (!!dvc->mute.cfg.val[i]) << i; + /* Enable Ramp */ + if (dvc->ren.val) + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.cfg.max; + else + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.val[i]; - /* Disable DVC Register access */ - rsnd_mod_write(mod, DVC_DVUER, 0); + /* Enable Digital Volume */ + rsnd_mod_write(mod, DVC_VOL0R, val[0]); + rsnd_mod_write(mod, DVC_VOL1R, val[1]); +} + +static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) +{ + struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 dvucr = 0; + u32 vrctr = 0; + u32 vrpdr = 0; + u32 vrdbr = 0; + + /* Enable Digital Volume, Zero Cross Mute Mode */ + dvucr |= 0x101; /* Enable Ramp */ if (dvc->ren.val) { dvucr |= 0x10; - /* Digital Volume Max */ - for (i = 0; i < RSND_DVC_CHANNELS; i++) - val[i] = dvc->volume.cfg.max; - - rsnd_mod_write(mod, DVC_VRCTR, 0xff); - rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 | - dvc->rdown.val); /* * FIXME !! * use scale-downed Digital Volume * as Volume Ramp * 7F FFFF -> 3FF */ - rsnd_mod_write(mod, DVC_VRDBR, - 0x3ff - (dvc->volume.val[0] >> 13)); - - } else { - for (i = 0; i < RSND_DVC_CHANNELS; i++) - val[i] = dvc->volume.val[i]; + vrctr = 0xff; + vrpdr = rsnd_dvc_get_vrpdr(dvc); + vrdbr = rsnd_dvc_get_vrdbr(dvc); } - /* Enable Digital Volume */ - dvucr |= 0x100; - rsnd_mod_write(mod, DVC_VOL0R, val[0]); - rsnd_mod_write(mod, DVC_VOL1R, val[1]); + /* Initialize operation */ + rsnd_mod_write(mod, DVC_DVUIR, 1); + + /* General Information */ + rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); + rsnd_mod_write(mod, DVC_DVUCR, dvucr); + + /* Volume Ramp Parameter */ + rsnd_mod_write(mod, DVC_VRCTR, vrctr); + rsnd_mod_write(mod, DVC_VRPDR, vrpdr); + rsnd_mod_write(mod, DVC_VRDBR, vrdbr); + + /* Digital Volume Function Parameter */ + rsnd_dvc_volume_parameter(io, mod); + + /* cancel operation */ + rsnd_mod_write(mod, DVC_DVUIR, 0); +} + +static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) +{ + struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 zcmcr = 0; + u32 vrpdr = 0; + u32 vrdbr = 0; + int i; + + for (i = 0; i < dvc->mute.cfg.size; i++) + zcmcr |= (!!dvc->mute.cfg.val[i]) << i; - /* Enable Mute */ - if (mute) { - dvucr |= 0x1; - rsnd_mod_write(mod, DVC_ZCMCR, mute); + if (dvc->ren.val) { + vrpdr = rsnd_dvc_get_vrpdr(dvc); + vrdbr = rsnd_dvc_get_vrdbr(dvc); } - rsnd_mod_write(mod, DVC_DVUCR, dvucr); + /* Disable DVC Register access */ + rsnd_mod_write(mod, DVC_DVUER, 0); + + /* Zero Cross Mute Function */ + rsnd_mod_write(mod, DVC_ZCMCR, zcmcr); + + /* Volume Ramp Function */ + rsnd_mod_write(mod, DVC_VRPDR, vrpdr); + rsnd_mod_write(mod, DVC_VRDBR, vrdbr); + /* add DVC_VRWTR here */ + + /* Digital Volume Function Parameter */ + rsnd_dvc_volume_parameter(io, mod); /* Enable DVC Register access */ rsnd_mod_write(mod, DVC_DVUER, 1); @@ -164,15 +204,10 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, rsnd_dvc_soft_reset(mod); - rsnd_dvc_initialize_lock(mod); + rsnd_dvc_volume_init(io, mod); - rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); - - /* ch0/ch1 Volume */ rsnd_dvc_volume_update(io, mod); - rsnd_dvc_initialize_unlock(mod); - return 0; } -- cgit v1.2.3 From 13e0d17d08d1d651aa119c286f74cf366caf09dd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 4 Nov 2015 08:44:32 +0000 Subject: ASoC: rsnd: MIX settings matches to datasheet Current MIX settings order was rough. This patch makes it match to datasheet. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/mix.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index bcbd821981a9..2baa2d79bfc0 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -31,24 +31,41 @@ static void rsnd_mix_soft_reset(struct rsnd_mod *mod) rsnd_mod_write(mod, MIX_SWRSR, 1); } -#define rsnd_mix_initialize_lock(mod) __rsnd_mix_initialize_lock(mod, 1) -#define rsnd_mix_initialize_unlock(mod) __rsnd_mix_initialize_lock(mod, 0) -static void __rsnd_mix_initialize_lock(struct rsnd_mod *mod, u32 enable) +static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) { - rsnd_mod_write(mod, MIX_MIXIR, enable); + rsnd_mod_write(mod, MIX_MDBAR, 0); + rsnd_mod_write(mod, MIX_MDBBR, 0); + rsnd_mod_write(mod, MIX_MDBCR, 0); + rsnd_mod_write(mod, MIX_MDBDR, 0); +} + +static void rsnd_mix_volume_init(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) +{ + rsnd_mod_write(mod, MIX_MIXIR, 1); + + /* General Information */ + rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io)); + + /* volume step */ + rsnd_mod_write(mod, MIX_MIXMR, 0); + rsnd_mod_write(mod, MIX_MVPDR, 0); + + /* common volume parameter */ + rsnd_mix_volume_parameter(io, mod); + + rsnd_mod_write(mod, MIX_MIXIR, 0); } static void rsnd_mix_volume_update(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { - /* Disable MIX dB setting */ rsnd_mod_write(mod, MIX_MDBER, 0); - rsnd_mod_write(mod, MIX_MDBAR, 0); - rsnd_mod_write(mod, MIX_MDBBR, 0); - rsnd_mod_write(mod, MIX_MDBCR, 0); - rsnd_mod_write(mod, MIX_MDBDR, 0); + /* common volume parameter */ + rsnd_mix_volume_parameter(io, mod); /* Enable MIX dB setting */ rsnd_mod_write(mod, MIX_MDBER, 1); @@ -69,18 +86,10 @@ static int rsnd_mix_init(struct rsnd_mod *mod, rsnd_mix_soft_reset(mod); - rsnd_mix_initialize_lock(mod); - - rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io)); - - /* volume step */ - rsnd_mod_write(mod, MIX_MIXMR, 0); - rsnd_mod_write(mod, MIX_MVPDR, 0); + rsnd_mix_volume_init(io, mod); rsnd_mix_volume_update(io, mod); - rsnd_mix_initialize_unlock(mod); - return 0; } -- cgit v1.2.3 From 81ad174db5ca8f372da6dc31a4ca25d52f9bec5f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 5 Nov 2015 08:50:10 +0000 Subject: ASoC: rsnd: tidyup comment position of rsnd_mod_xxx f1df12290("ASoC: rsnd: add common mod confirm method") added rsnd_mod_make_sure(), but rsnd_mod_xxx() comment position was wrong. This patch tidyup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5586b888db56..1363966fa957 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -127,6 +127,9 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); #define rsnd_info_id(priv, io, name) \ ((io)->info->name - priv->info->name##_info) +/* + * rsnd_mod functions + */ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) { if (mod->type != type) { @@ -138,9 +141,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) } } -/* - * rsnd_mod functions - */ char *rsnd_mod_name(struct rsnd_mod *mod) { if (!mod || !mod->ops) -- cgit v1.2.3 From 68a550248e295ba548e30c876ccdec351e286eee Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 5 Nov 2015 08:51:15 +0000 Subject: ASoC: rsnd: call clk_prepare()/clk_enable() for AUDIO_CLKx ADG can output AUDIO_CLKOUTx, and these are generated from AUDIO_CLKx. Thus we need to call clk_prepare()/clk_enable() for AUDIO_CLKx. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 21 +++++++++++++++++++-- sound/soc/sh/rcar/core.c | 1 + sound/soc/sh/rcar/rsnd.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index b123734f9fbd..1946ce8baf2e 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -418,15 +418,20 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv, [CLKC] = "clk_c", [CLKI] = "clk_i", }; - int i; + int i, ret; for (i = 0; i < CLKMAX; i++) { clk = devm_clk_get(dev, clk_name[i]); adg->clk[i] = IS_ERR(clk) ? NULL : clk; } - for_each_rsnd_clk(clk, adg, i) + for_each_rsnd_clk(clk, adg, i) { + ret = clk_prepare_enable(clk); + if (ret < 0) + dev_warn(dev, "can't use clk %d\n", i); + dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); + } } static void rsnd_adg_get_clkout(struct rsnd_priv *priv, @@ -600,3 +605,15 @@ int rsnd_adg_probe(struct platform_device *pdev, return 0; } + +void rsnd_adg_remove(struct platform_device *pdev, + struct rsnd_priv *priv) +{ + struct rsnd_adg *adg = rsnd_priv_to_adg(priv); + struct clk *clk; + int i; + + for_each_rsnd_clk(clk, adg, i) { + clk_disable_unprepare(clk); + } +} diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1363966fa957..81250cf6788d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1227,6 +1227,7 @@ static int rsnd_remove(struct platform_device *pdev) rsnd_mix_remove, rsnd_dvc_remove, rsnd_cmd_remove, + rsnd_adg_remove, }; int ret = 0, i; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 599dfb69555a..8efa19fa2b6e 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -405,6 +405,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); +void rsnd_adg_remove(struct platform_device *pdev, + struct rsnd_priv *priv); int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, struct rsnd_mod *mod, unsigned int src_rate, -- cgit v1.2.3 From f46a93b820eb3707faf238cd769a004e2504515f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 17 Nov 2015 08:28:11 +0000 Subject: ASoC: rsnd: ssi: 24bit data needs right-aligned settings Data left/right aligned is controlled by PDTA bit on SSICR. But default is left-aligned. Thus 24bit sound will be very small sound without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 3e814711f301..60ef074082e8 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -39,6 +39,7 @@ #define SCKP (1 << 13) /* Serial Bit Clock Polarity */ #define SWSP (1 << 12) /* Serial WS Polarity */ #define SDTA (1 << 10) /* Serial Data Alignment */ +#define PDTA (1 << 9) /* Parallel Data Alignment */ #define DEL (1 << 8) /* Serial Data Delay */ #define CKDV(v) (v << 4) /* Serial Clock Division Ratio */ #define TRMD (1 << 1) /* Transmit/Receive Mode Select */ @@ -274,7 +275,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (rsnd_ssi_is_parent(mod, io)) return 0; - cr = FORCE; + cr = FORCE | PDTA; /* * always use 32bit system word for easy clock calculation. -- cgit v1.2.3 From e8e7b7bdc65c19f8d84c25f7e0d21176d598c870 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:09:52 +0000 Subject: ASoC: rsnd: remove Gen1 support from SRC This patch removes SRC Gen1 support which has no user on upstream. Historically, SRC Gen1 was created as prepare for SRC Gen2 support. It works well for Gen2 support, but Gen1 is not same as Gen2. So now, Gen1 support is no longer needed. Thanks Gen1 and Bye-bye. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 62 --------------- sound/soc/sh/rcar/gen.c | 38 +-------- sound/soc/sh/rcar/rsnd.h | 15 ---- sound/soc/sh/rcar/src.c | 199 ++--------------------------------------------- 4 files changed, 7 insertions(+), 307 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 1946ce8baf2e..1dffde3218be 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -242,68 +242,6 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod, return rsnd_adg_set_src_timsel_gen2(src_mod, io, val); } -int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, - struct rsnd_mod *mod, - unsigned int src_rate, - unsigned int dst_rate) -{ - struct rsnd_adg *adg = rsnd_priv_to_adg(priv); - struct rsnd_mod *adg_mod = rsnd_mod_get(adg); - struct device *dev = rsnd_priv_to_dev(priv); - int idx, sel, div, shift; - u32 mask, val; - int id = rsnd_mod_id(mod); - unsigned int sel_rate [] = { - clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */ - clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ - clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ - 0, /* 011: MLBCLK (not used) */ - adg->rbga_rate_for_441khz, /* 100: RBGA */ - adg->rbgb_rate_for_48khz, /* 101: RBGB */ - }; - - /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ - for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) { - for (div = 128, idx = 0; - div <= 2048; - div *= 2, idx++) { - if (src_rate == sel_rate[sel] / div) { - val = (idx << 4) | sel; - goto find_rate; - } - } - } - dev_err(dev, "can't find convert src clk\n"); - return -EINVAL; - -find_rate: - shift = (id % 4) * 8; - mask = 0xFF << shift; - val = val << shift; - - dev_dbg(dev, "adg convert src clk = %02x\n", val); - - switch (id / 4) { - case 0: - rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val); - break; - case 1: - rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val); - break; - case 2: - rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val); - break; - } - - /* - * Gen1 doesn't need dst_rate settings, - * since it uses SSI WS pin. - * see also rsnd_src_set_route_if_gen1() - */ - - return 0; -} - static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val) { struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 76da7620904c..1808fc64646c 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -320,43 +320,12 @@ static int rsnd_gen2_probe(struct platform_device *pdev, static int rsnd_gen1_probe(struct platform_device *pdev, struct rsnd_priv *priv) { - struct rsnd_regmap_field_conf conf_sru[] = { - RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), - RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), - RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c), - RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10), - RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0), - RSND_GEN_S_REG(SSI_MODE0, 0xD0), - RSND_GEN_S_REG(SSI_MODE1, 0xD4), - RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4), - RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8), - RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), - RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), - RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), - RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), - RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), - RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), - RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), - /* - * ADD US - * - * SRC_STATUS - * SRC_INT_EN - * SCU_SYS_STATUS0 - * SCU_SYS_STATUS1 - * SCU_SYS_INT_EN0 - * SCU_SYS_INT_EN1 - */ - }; struct rsnd_regmap_field_conf conf_adg[] = { RSND_GEN_S_REG(BRRA, 0x00), RSND_GEN_S_REG(BRRB, 0x04), RSND_GEN_S_REG(SSICKR, 0x08), RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), - RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18), - RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c), - RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20), }; struct rsnd_regmap_field_conf conf_ssi[] = { RSND_GEN_M_REG(SSICR, 0x00, 0x40), @@ -365,17 +334,14 @@ static int rsnd_gen1_probe(struct platform_device *pdev, RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), }; - int ret_sru; int ret_adg; int ret_ssi; - ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru); ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); - if (ret_sru < 0 || - ret_adg < 0 || + if (ret_adg < 0 || ret_ssi < 0) - return ret_sru | ret_adg | ret_ssi; + return ret_adg | ret_ssi; return 0; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 8efa19fa2b6e..da671869f12a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -117,17 +117,6 @@ enum rsnd_reg { RSND_REG_MAX, }; -/* Gen1 only */ -#define RSND_REG_SRC_ROUTE_SEL RSND_REG_SHARE01 -#define RSND_REG_SRC_TMG_SEL0 RSND_REG_SHARE02 -#define RSND_REG_SRC_TMG_SEL1 RSND_REG_SHARE03 -#define RSND_REG_SRC_TMG_SEL2 RSND_REG_SHARE04 -#define RSND_REG_SRC_ROUTE_CTRL RSND_REG_SHARE05 -#define RSND_REG_SRC_MNFSR RSND_REG_SHARE06 -#define RSND_REG_AUDIO_CLK_SEL3 RSND_REG_SHARE07 -#define RSND_REG_AUDIO_CLK_SEL4 RSND_REG_SHARE08 -#define RSND_REG_AUDIO_CLK_SEL5 RSND_REG_SHARE09 - /* Gen2 only */ #define RSND_REG_SRC_CTRL RSND_REG_SHARE01 #define RSND_REG_SSI_CTRL RSND_REG_SHARE02 @@ -407,10 +396,6 @@ int rsnd_adg_probe(struct platform_device *pdev, struct rsnd_priv *priv); void rsnd_adg_remove(struct platform_device *pdev, struct rsnd_priv *priv); -int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, - struct rsnd_mod *mod, - unsigned int src_rate, - unsigned int dst_rate); int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, unsigned int src_rate, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 776b0efec4d6..0978221b2fe1 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -309,187 +309,6 @@ static int rsnd_src_stop(struct rsnd_mod *mod) return 0; } -/* - * Gen1 functions - */ -static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, - struct rsnd_mod *mod) -{ - struct src_route_config { - u32 mask; - int shift; - } routes[] = { - { 0xF, 0, }, /* 0 */ - { 0xF, 4, }, /* 1 */ - { 0xF, 8, }, /* 2 */ - { 0x7, 12, }, /* 3 */ - { 0x7, 16, }, /* 4 */ - { 0x7, 20, }, /* 5 */ - { 0x7, 24, }, /* 6 */ - { 0x3, 28, }, /* 7 */ - { 0x3, 30, }, /* 8 */ - }; - u32 mask; - u32 val; - int id; - - id = rsnd_mod_id(mod); - if (id < 0 || id >= ARRAY_SIZE(routes)) - return -EIO; - - /* - * SRC_ROUTE_SELECT - */ - val = rsnd_io_is_play(io) ? 0x1 : 0x2; - val = val << routes[id].shift; - mask = routes[id].mask << routes[id].shift; - - rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val); - - return 0; -} - -static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io, - struct rsnd_mod *mod) -{ - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_src *src = rsnd_mod_to_src(mod); - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - u32 convert_rate = rsnd_src_convert_rate(io, src); - u32 mask; - u32 val; - int shift; - int id = rsnd_mod_id(mod); - int ret; - - /* - * SRC_TIMING_SELECT - */ - shift = (id % 4) * 8; - mask = 0x1F << shift; - - /* - * ADG is used as source clock if SRC was used, - * then, SSI WS is used as destination clock. - * SSI WS is used as source clock if SRC is not used - * (when playback, source/destination become reverse when capture) - */ - ret = 0; - if (convert_rate) { - /* use ADG */ - val = 0; - ret = rsnd_adg_set_convert_clk_gen1(priv, mod, - runtime->rate, - convert_rate); - } else if (8 == id) { - /* use SSI WS, but SRU8 is special */ - val = id << shift; - } else { - /* use SSI WS */ - val = (id + 1) << shift; - } - - if (ret < 0) - return ret; - - switch (id / 4) { - case 0: - rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); - break; - case 1: - rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); - break; - case 2: - rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); - break; - } - - return 0; -} - -static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) -{ - struct rsnd_src *src = rsnd_mod_to_src(mod); - int ret; - - ret = rsnd_src_set_convert_rate(mod, io); - if (ret < 0) - return ret; - - /* Select SRC mode (fixed value) */ - rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); - - /* Set the restriction value of the FS ratio (98%) */ - rsnd_mod_write(mod, SRC_MNFSR, - rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); - - /* Gen1/Gen2 are not compatible */ - if (rsnd_src_convert_rate(io, src)) - rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); - - /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ - - return 0; -} - -static int rsnd_src_init_gen1(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - int ret; - - ret = rsnd_src_init(mod, priv); - if (ret < 0) - return ret; - - ret = rsnd_src_set_route_gen1(io, mod); - if (ret < 0) - return ret; - - ret = rsnd_src_set_convert_rate_gen1(mod, io); - if (ret < 0) - return ret; - - ret = rsnd_src_set_convert_timing_gen1(io, mod); - if (ret < 0) - return ret; - - return 0; -} - -static int rsnd_src_start_gen1(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - int id = rsnd_mod_id(mod); - - rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); - - return rsnd_src_start(mod); -} - -static int rsnd_src_stop_gen1(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - int id = rsnd_mod_id(mod); - - rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); - - return rsnd_src_stop(mod); -} - -static struct rsnd_mod_ops rsnd_src_gen1_ops = { - .name = SRC_NAME, - .dma_req = rsnd_src_dma_req, - .init = rsnd_src_init_gen1, - .quit = rsnd_src_quit, - .start = rsnd_src_start_gen1, - .stop = rsnd_src_stop_gen1, - .hw_params = rsnd_src_hw_params, -}; - /* * Gen2 functions */ @@ -927,22 +746,13 @@ int rsnd_src_probe(struct platform_device *pdev, struct rcar_snd_info *info = rsnd_priv_to_info(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_src *src; - struct rsnd_mod_ops *ops; struct clk *clk; char name[RSND_SRC_NAME_SIZE]; int i, nr, ret; - ops = NULL; - if (rsnd_is_gen1(priv)) { - ops = &rsnd_src_gen1_ops; - dev_warn(dev, "Gen1 support will be removed soon\n"); - } - if (rsnd_is_gen2(priv)) - ops = &rsnd_src_gen2_ops; - if (!ops) { - dev_err(dev, "unknown Generation\n"); - return -EIO; - } + /* This driver doesn't support Gen1 at this point */ + if (rsnd_is_gen1(priv)) + return 0; rsnd_of_parse_src(pdev, of_data, priv); @@ -970,7 +780,8 @@ int rsnd_src_probe(struct platform_device *pdev, src->info = &info->src_info[i]; - ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i); + ret = rsnd_mod_init(priv, rsnd_mod_get(src), + &rsnd_src_gen2_ops, clk, RSND_MOD_SRC, i); if (ret) return ret; } -- cgit v1.2.3 From d444080ef824bf45ead732f2c68cfeb5885bc53a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:10:18 +0000 Subject: ASoC: rsnd: cleanup RSND_REG_xxx SRC Gen1 support was removed. Current rsnd driver is sharing Gen1/Gen2 register index to reduce memory, but there is no effect anymore. Let's remove share definition and merge RSND_REG_xxx Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsnd.h | 93 ++++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 63 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index da671869f12a..a3e42a4f4b19 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -34,9 +34,14 @@ * see gen1/gen2 for detail */ enum rsnd_reg { - /* SRU/SCU/SSIU */ + /* SCU (SRC/SSIU/MIX/CTU/DVC) */ RSND_REG_SSI_MODE0, RSND_REG_SSI_MODE1, + RSND_REG_SSI_CTRL, /* Gen2 only */ + RSND_REG_SSI_BUSIF_MODE, /* Gen2 only */ + RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */ + RSND_REG_SSI_BUSIF_DALIGN, /* Gen2 only */ + RSND_REG_SSI_INT_ENABLE, /* Gen2 only */ RSND_REG_SRC_BUSIF_MODE, RSND_REG_SRC_ROUTE_MODE0, RSND_REG_SRC_SWRSR, @@ -45,9 +50,28 @@ enum rsnd_reg { RSND_REG_SRC_IFSCR, RSND_REG_SRC_IFSVR, RSND_REG_SRC_SRCCR, + RSND_REG_SRC_CTRL, /* Gen2 only */ + RSND_REG_SRC_BSDSR, /* Gen2 only */ + RSND_REG_SRC_BSISR, /* Gen2 only */ + RSND_REG_SRC_INT_ENABLE0, /* Gen2 only */ + RSND_REG_SRC_BUSIF_DALIGN, /* Gen2 only */ + RSND_REG_SRCIN_TIMSEL0, /* Gen2 only */ + RSND_REG_SRCIN_TIMSEL1, /* Gen2 only */ + RSND_REG_SRCIN_TIMSEL2, /* Gen2 only */ + RSND_REG_SRCIN_TIMSEL3, /* Gen2 only */ + RSND_REG_SRCIN_TIMSEL4, /* Gen2 only */ + RSND_REG_SRCOUT_TIMSEL0, /* Gen2 only */ + RSND_REG_SRCOUT_TIMSEL1, /* Gen2 only */ + RSND_REG_SRCOUT_TIMSEL2, /* Gen2 only */ + RSND_REG_SRCOUT_TIMSEL3, /* Gen2 only */ + RSND_REG_SRCOUT_TIMSEL4, /* Gen2 only */ RSND_REG_SCU_SYS_STATUS0, + RSND_REG_SCU_SYS_STATUS1, /* Gen2 only */ RSND_REG_SCU_SYS_INT_EN0, + RSND_REG_SCU_SYS_INT_EN1, /* Gen2 only */ + RSND_REG_CMD_CTRL, /* Gen2 only */ RSND_REG_CMD_ROUTE_SLCT, + RSND_REG_CMDOUT_TIMSEL, /* Gen2 only */ RSND_REG_CTU_CTUIR, RSND_REG_CTU_ADINR, RSND_REG_MIX_SWRSR, @@ -68,13 +92,18 @@ enum rsnd_reg { RSND_REG_DVC_VOL0R, RSND_REG_DVC_VOL1R, RSND_REG_DVC_DVUER, + RSND_REG_DVC_VRCTR, /* Gen2 only */ + RSND_REG_DVC_VRPDR, /* Gen2 only */ + RSND_REG_DVC_VRDBR, /* Gen2 only */ /* ADG */ RSND_REG_BRRA, RSND_REG_BRRB, RSND_REG_SSICKR, + RSND_REG_DIV_EN, /* Gen2 only */ RSND_REG_AUDIO_CLK_SEL0, RSND_REG_AUDIO_CLK_SEL1, + RSND_REG_AUDIO_CLK_SEL2, /* Gen2 only */ /* SSI */ RSND_REG_SSICR, @@ -83,71 +112,9 @@ enum rsnd_reg { RSND_REG_SSIRDR, RSND_REG_SSIWSR, - /* SHARE see below */ - RSND_REG_SHARE01, - RSND_REG_SHARE02, - RSND_REG_SHARE03, - RSND_REG_SHARE04, - RSND_REG_SHARE05, - RSND_REG_SHARE06, - RSND_REG_SHARE07, - RSND_REG_SHARE08, - RSND_REG_SHARE09, - RSND_REG_SHARE10, - RSND_REG_SHARE11, - RSND_REG_SHARE12, - RSND_REG_SHARE13, - RSND_REG_SHARE14, - RSND_REG_SHARE15, - RSND_REG_SHARE16, - RSND_REG_SHARE17, - RSND_REG_SHARE18, - RSND_REG_SHARE19, - RSND_REG_SHARE20, - RSND_REG_SHARE21, - RSND_REG_SHARE22, - RSND_REG_SHARE23, - RSND_REG_SHARE24, - RSND_REG_SHARE25, - RSND_REG_SHARE26, - RSND_REG_SHARE27, - RSND_REG_SHARE28, - RSND_REG_SHARE29, - RSND_REG_MAX, }; -/* Gen2 only */ -#define RSND_REG_SRC_CTRL RSND_REG_SHARE01 -#define RSND_REG_SSI_CTRL RSND_REG_SHARE02 -#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03 -#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04 -#define RSND_REG_SSI_INT_ENABLE RSND_REG_SHARE05 -#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06 -#define RSND_REG_SRC_BSISR RSND_REG_SHARE07 -#define RSND_REG_DIV_EN RSND_REG_SHARE08 -#define RSND_REG_SRCIN_TIMSEL0 RSND_REG_SHARE09 -#define RSND_REG_SRCIN_TIMSEL1 RSND_REG_SHARE10 -#define RSND_REG_SRCIN_TIMSEL2 RSND_REG_SHARE11 -#define RSND_REG_SRCIN_TIMSEL3 RSND_REG_SHARE12 -#define RSND_REG_SRCIN_TIMSEL4 RSND_REG_SHARE13 -#define RSND_REG_SRCOUT_TIMSEL0 RSND_REG_SHARE14 -#define RSND_REG_SRCOUT_TIMSEL1 RSND_REG_SHARE15 -#define RSND_REG_SRCOUT_TIMSEL2 RSND_REG_SHARE16 -#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17 -#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 -#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 -#define RSND_REG_CMD_CTRL RSND_REG_SHARE20 -#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 -#define RSND_REG_SSI_BUSIF_DALIGN RSND_REG_SHARE22 -#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 -#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 -#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 -#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26 -#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27 -#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28 -#define RSND_REG_SRC_BUSIF_DALIGN RSND_REG_SHARE29 - struct rsnd_of_data; struct rsnd_priv; struct rsnd_mod; -- cgit v1.2.3 From 75916f6524f055bca134f50901f926d5b0693db5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:10:48 +0000 Subject: ASoC: rsnd: SRC settings matches to datasheet Current SRC settings order was rough. Now, Gen1 support was removed. This patch makes it cleanup and match to datasheet. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 424 +++++++++++++++++++----------------------------- 1 file changed, 166 insertions(+), 258 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 0978221b2fe1..d081a652f917 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -117,23 +117,12 @@ struct rsnd_src { * */ -/* - * Gen1/Gen2 common functions - */ static void rsnd_src_soft_reset(struct rsnd_mod *mod) { rsnd_mod_write(mod, SRC_SWRSR, 0); rsnd_mod_write(mod, SRC_SWRSR, 1); } - -#define rsnd_src_initialize_lock(mod) __rsnd_src_initialize_lock(mod, 1) -#define rsnd_src_initialize_unlock(mod) __rsnd_src_initialize_lock(mod, 0) -static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable) -{ - rsnd_mod_write(mod, SRC_SRCIR, enable); -} - static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { @@ -192,34 +181,6 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, return rate; } -static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) -{ - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - struct rsnd_src *src = rsnd_mod_to_src(mod); - u32 convert_rate = rsnd_src_convert_rate(io, src); - u32 fsrate = 0; - - if (convert_rate) - fsrate = 0x0400000 / convert_rate * runtime->rate; - - /* Set channel number and output bit length */ - rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io)); - - /* Enable the initial value of IFS */ - if (fsrate) { - rsnd_mod_write(mod, SRC_IFSCR, 1); - - /* Set initial value of IFS */ - rsnd_mod_write(mod, SRC_IFSVR, fsrate); - } - - /* use DMA transfer */ - rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); - - return 0; -} - static int rsnd_src_hw_params(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_pcm_substream *substream, @@ -256,65 +217,106 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod, return 0; } -static int rsnd_src_init(struct rsnd_mod *mod, - struct rsnd_priv *priv) +static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, + struct rsnd_mod *mod) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct rsnd_src *src = rsnd_mod_to_src(mod); + u32 convert_rate = rsnd_src_convert_rate(io, src); + u32 ifscr, fsrate, adinr; + u32 cr, route; + u32 bsdsr, bsisr; + uint ratio; - rsnd_mod_power_on(mod); - - rsnd_src_soft_reset(mod); - - rsnd_src_initialize_lock(mod); - - src->err = 0; - - /* reset sync convert_rate */ - src->sync.val = 0; + if (!runtime) + return; - return 0; -} + /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ + if (!convert_rate) + ratio = 0; + else if (convert_rate > runtime->rate) + ratio = 100 * convert_rate / runtime->rate; + else + ratio = 100 * runtime->rate / convert_rate; -static int rsnd_src_quit(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_src *src = rsnd_mod_to_src(mod); - struct device *dev = rsnd_priv_to_dev(priv); + if (ratio > 600) { + dev_err(dev, "FSO/FSI ratio error\n"); + return; + } - rsnd_mod_power_off(mod); + /* + * SRC_ADINR + */ + adinr = rsnd_get_adinr_bit(mod, io); - if (src->err) - dev_warn(dev, "%s[%d] under/over flow err = %d\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); + /* + * SRC_IFSCR / SRC_IFSVR + */ + ifscr = 0; + fsrate = 0; + if (convert_rate) { + ifscr = 1; + fsrate = 0x0400000 / convert_rate * runtime->rate; + } - src->convert_rate = 0; + /* + * SRC_SRCCR / SRC_ROUTE_MODE0 + */ + cr = 0x00011110; + route = 0x0; + if (convert_rate) { + route = 0x1; - /* reset sync convert_rate */ - src->sync.val = 0; + if (rsnd_enable_sync_convert(src)) { + cr |= 0x1; + route |= rsnd_io_is_play(io) ? + (0x1 << 24) : (0x1 << 25); + } + } - return 0; -} + /* + * SRC_BSDSR / SRC_BSISR + */ + switch (rsnd_mod_id(mod)) { + case 5: + case 6: + case 7: + case 8: + bsdsr = 0x02400000; /* 6 - 1/6 */ + bsisr = 0x00100060; /* 6 - 1/6 */ + break; + default: + bsdsr = 0x01800000; /* 6 - 1/6 */ + bsisr = 0x00100060 ;/* 6 - 1/6 */ + break; + } -static int rsnd_src_start(struct rsnd_mod *mod) -{ - rsnd_src_initialize_unlock(mod); + rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ + rsnd_mod_write(mod, SRC_ADINR, adinr); + rsnd_mod_write(mod, SRC_IFSCR, ifscr); + rsnd_mod_write(mod, SRC_IFSVR, fsrate); + rsnd_mod_write(mod, SRC_SRCCR, cr); + rsnd_mod_write(mod, SRC_BSDSR, bsdsr); + rsnd_mod_write(mod, SRC_BSISR, bsisr); + rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ - return 0; -} + rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); + rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); + rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); -static int rsnd_src_stop(struct rsnd_mod *mod) -{ - /* nothing to do */ - return 0; + if (convert_rate) + rsnd_adg_set_convert_clk_gen2(mod, io, + runtime->rate, + convert_rate); + else + rsnd_adg_set_convert_timing_gen2(mod, io); } -/* - * Gen2 functions - */ -#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1) -#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0) -static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) +#define rsnd_src_irq_enable(mod) rsnd_src_irq_ctrol(mod, 1) +#define rsnd_src_irq_disable(mod) rsnd_src_irq_ctrol(mod, 0) +static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 sys_int_val, int_val, sys_int_mask; @@ -328,7 +330,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) /* * IRQ is not supported on non-DT * see - * rsnd_src_probe_gen2() + * rsnd_src_probe_() */ if ((irq <= 0) || !enable) { sys_int_val = 0; @@ -348,7 +350,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); } -static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) +static void rsnd_src_error_clear(struct rsnd_mod *mod) { u32 val = OUF_SRC(rsnd_mod_id(mod)); @@ -356,7 +358,7 @@ static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); } -static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) +static bool rsnd_src_error_record(struct rsnd_mod *mod) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 val0, val1; @@ -381,22 +383,18 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) } /* clear error static */ - rsnd_src_error_clear_gen2(mod); + rsnd_src_error_clear(mod); return ret; } -static int rsnd_src_start_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_src_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 val; - val = rsnd_get_dalign(mod, io); - - rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val); - /* * WORKAROUND * @@ -407,44 +405,74 @@ static int rsnd_src_start_gen2(struct rsnd_mod *mod, rsnd_mod_write(mod, SRC_CTRL, val); - rsnd_src_error_clear_gen2(mod); - - rsnd_src_start(mod); - - rsnd_src_irq_enable_gen2(mod); - return 0; } -static int rsnd_src_stop_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_src_stop(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { - rsnd_src_irq_disable_gen2(mod); - /* * stop SRC output only - * see rsnd_src_quit_gen2 + * see rsnd_src_quit */ rsnd_mod_write(mod, SRC_CTRL, 0x01); - rsnd_src_error_record_gen2(mod); + return 0; +} + +static int rsnd_src_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_src *src = rsnd_mod_to_src(mod); - return rsnd_src_stop(mod); + rsnd_mod_power_on(mod); + + rsnd_src_soft_reset(mod); + + rsnd_src_set_convert_rate(io, mod); + + rsnd_src_error_clear(mod); + + rsnd_src_irq_enable(mod); + + src->err = 0; + + /* reset sync convert_rate */ + src->sync.val = 0; + + return 0; } -static int rsnd_src_quit_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_src_quit(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { + struct rsnd_src *src = rsnd_mod_to_src(mod); + struct device *dev = rsnd_priv_to_dev(priv); + + rsnd_src_irq_disable(mod); + /* stop both out/in */ rsnd_mod_write(mod, SRC_CTRL, 0); - return rsnd_src_quit(mod, io, priv); + rsnd_mod_power_off(mod); + + if (src->err) + dev_warn(dev, "%s[%d] under/over flow err = %d\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); + + src->convert_rate = 0; + + /* reset sync convert_rate */ + src->sync.val = 0; + + return 0; } -static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) +static void __rsnd_src_interrupt(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_src *src = rsnd_mod_to_src(mod); @@ -454,119 +482,40 @@ static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, /* ignore all cases if not working */ if (!rsnd_io_is_working(io)) - goto rsnd_src_interrupt_gen2_out; + goto rsnd_src_interrupt_out; - if (rsnd_src_error_record_gen2(mod)) { + if (rsnd_src_error_record(mod)) { dev_dbg(dev, "%s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); - rsnd_src_stop_gen2(mod, io, priv); - rsnd_src_start_gen2(mod, io, priv); + rsnd_src_stop(mod, io, priv); + rsnd_src_start(mod, io, priv); } if (src->err > 1024) { - rsnd_src_irq_disable_gen2(mod); + rsnd_src_irq_disable(mod); dev_warn(dev, "no more %s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); } -rsnd_src_interrupt_gen2_out: +rsnd_src_interrupt_out: spin_unlock(&priv->lock); } -static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) +static irqreturn_t rsnd_src_interrupt(int irq, void *data) { struct rsnd_mod *mod = data; - rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); + rsnd_mod_interrupt(mod, __rsnd_src_interrupt); return IRQ_HANDLED; } -static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io) -{ - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct device *dev = rsnd_priv_to_dev(priv); - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - struct rsnd_src *src = rsnd_mod_to_src(mod); - u32 convert_rate = rsnd_src_convert_rate(io, src); - u32 cr, route; - uint ratio; - int ret; - - /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ - if (!convert_rate) - ratio = 0; - else if (convert_rate > runtime->rate) - ratio = 100 * convert_rate / runtime->rate; - else - ratio = 100 * runtime->rate / convert_rate; - - if (ratio > 600) { - dev_err(dev, "FSO/FSI ratio error\n"); - return -EINVAL; - } - - ret = rsnd_src_set_convert_rate(mod, io); - if (ret < 0) - return ret; - - cr = 0x00011110; - route = 0x0; - if (convert_rate) { - route = 0x1; - - if (rsnd_enable_sync_convert(src)) { - cr |= 0x1; - route |= rsnd_io_is_play(io) ? - (0x1 << 24) : (0x1 << 25); - } - } - - rsnd_mod_write(mod, SRC_SRCCR, cr); - rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); - - switch (rsnd_mod_id(mod)) { - case 5: - case 6: - case 7: - case 8: - rsnd_mod_write(mod, SRC_BSDSR, 0x02400000); - break; - default: - rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); - break; - } - - rsnd_mod_write(mod, SRC_BSISR, 0x00100060); - - return 0; -} - -static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, - struct rsnd_mod *mod) -{ - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - struct rsnd_src *src = rsnd_mod_to_src(mod); - u32 convert_rate = rsnd_src_convert_rate(io, src); - int ret; - - if (convert_rate) - ret = rsnd_adg_set_convert_clk_gen2(mod, io, - runtime->rate, - convert_rate); - else - ret = rsnd_adg_set_convert_timing_gen2(mod, io); - - return ret; -} - -static int rsnd_src_probe_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) +static int rsnd_src_probe_(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) { struct rsnd_src *src = rsnd_mod_to_src(mod); struct device *dev = rsnd_priv_to_dev(priv); @@ -577,10 +526,10 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, /* * IRQ is not supported on non-DT * see - * rsnd_src_irq_enable_gen2() + * rsnd_src_irq_enable() */ ret = devm_request_irq(dev, irq, - rsnd_src_interrupt_gen2, + rsnd_src_interrupt, IRQF_SHARED, dev_name(dev), mod); if (ret) @@ -594,48 +543,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, return ret; } -static int rsnd_src_init_gen2(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - int ret; - - ret = rsnd_src_init(mod, priv); - if (ret < 0) - return ret; - - ret = rsnd_src_set_convert_rate_gen2(mod, io); - if (ret < 0) - return ret; - - ret = rsnd_src_set_convert_timing_gen2(io, mod); - if (ret < 0) - return ret; - - return 0; -} - -static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, - struct rsnd_mod *mod) -{ - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - struct rsnd_src *src = rsnd_mod_to_src(mod); - u32 convert_rate = rsnd_src_convert_rate(io, src); - u32 fsrate; - - if (!runtime) - return; - - if (!convert_rate) - convert_rate = runtime->rate; - - fsrate = 0x0400000 / convert_rate * runtime->rate; - - /* update IFS */ - rsnd_mod_write(mod, SRC_IFSVR, fsrate); -} - -static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, +static int rsnd_src_pcm_new(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd) { @@ -660,7 +568,7 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, rsnd_io_is_play(io) ? "SRC Out Rate Switch" : "SRC In Rate Switch", - rsnd_src_reconvert_update, + rsnd_src_set_convert_rate, &src->sen, 1); if (ret < 0) return ret; @@ -669,22 +577,22 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, rsnd_io_is_play(io) ? "SRC Out Rate" : "SRC In Rate", - rsnd_src_reconvert_update, + rsnd_src_set_convert_rate, &src->sync, 192000); return ret; } -static struct rsnd_mod_ops rsnd_src_gen2_ops = { +static struct rsnd_mod_ops rsnd_src_ops = { .name = SRC_NAME, .dma_req = rsnd_src_dma_req, - .probe = rsnd_src_probe_gen2, - .init = rsnd_src_init_gen2, - .quit = rsnd_src_quit_gen2, - .start = rsnd_src_start_gen2, - .stop = rsnd_src_stop_gen2, + .probe = rsnd_src_probe_, + .init = rsnd_src_init, + .quit = rsnd_src_quit, + .start = rsnd_src_start, + .stop = rsnd_src_stop, .hw_params = rsnd_src_hw_params, - .pcm_new = rsnd_src_pcm_new_gen2, + .pcm_new = rsnd_src_pcm_new, }; struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) @@ -781,7 +689,7 @@ int rsnd_src_probe(struct platform_device *pdev, src->info = &info->src_info[i]; ret = rsnd_mod_init(priv, rsnd_mod_get(src), - &rsnd_src_gen2_ops, clk, RSND_MOD_SRC, i); + &rsnd_src_ops, clk, RSND_MOD_SRC, i); if (ret) return ret; } -- cgit v1.2.3 From 94e2710cd2ce447cde879177d869b9ac231bc459 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:11:18 +0000 Subject: ASoC: rsnd: remove platform boot support from core.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from core.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 280 +++++++++++++---------------------------------- sound/soc/sh/rcar/ctu.c | 2 +- sound/soc/sh/rcar/dvc.c | 2 +- sound/soc/sh/rcar/mix.c | 2 +- sound/soc/sh/rcar/rsnd.h | 13 +++ sound/soc/sh/rcar/src.c | 2 - sound/soc/sh/rcar/ssi.c | 2 - 7 files changed, 95 insertions(+), 208 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 81250cf6788d..039d6cba8414 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -122,11 +122,6 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); (!(priv->info->func) ? 0 : \ priv->info->func(param)) -#define rsnd_is_enable_path(io, name) \ - ((io)->info ? (io)->info->name : NULL) -#define rsnd_info_id(priv, io, name) \ - ((io)->info->name - priv->info->name##_info) - /* * rsnd_mod functions */ @@ -573,140 +568,96 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .set_fmt = rsnd_soc_dai_set_fmt, }; -#define rsnd_path_add(priv, io, _type) \ -({ \ - struct rsnd_mod *mod; \ - int ret = 0; \ - int id = -1; \ - \ - if (rsnd_is_enable_path(io, _type)) { \ - id = rsnd_info_id(priv, io, _type); \ - if (id >= 0) { \ - mod = rsnd_##_type##_mod_get(priv, id); \ - ret = rsnd_dai_connect(mod, io, mod->type);\ - } \ - } \ - ret; \ -}) - -static int rsnd_path_init(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) -{ - int ret; - - /* - * Gen1 is created by SRU/SSI, and this SRU is base module of - * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU) - * - * Easy image is.. - * Gen1 SRU = Gen2 SCU + SSIU + etc - * - * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is - * using fixed path. - */ - - /* SSI */ - ret = rsnd_path_add(priv, io, ssi); - if (ret < 0) - return ret; - - /* SRC */ - ret = rsnd_path_add(priv, io, src); - if (ret < 0) - return ret; - - /* CTU */ - ret = rsnd_path_add(priv, io, ctu); - if (ret < 0) - return ret; - - /* MIX */ - ret = rsnd_path_add(priv, io, mix); - if (ret < 0) - return ret; - - /* DVC */ - ret = rsnd_path_add(priv, io, dvc); - if (ret < 0) - return ret; - - return ret; -} - -static void rsnd_of_parse_dai(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) +static int rsnd_dai_probe(struct platform_device *pdev, + const struct rsnd_of_data *of_data, + struct rsnd_priv *priv) { - struct device_node *dai_node, *dai_np; - struct device_node *ssi_node, *ssi_np; - struct device_node *src_node, *src_np; - struct device_node *ctu_node, *ctu_np; - struct device_node *mix_node, *mix_np; - struct device_node *dvc_node, *dvc_np; + struct device_node *dai_node; + struct device_node *dai_np, *np, *node; struct device_node *playback, *capture; - struct rsnd_dai_platform_info *dai_info; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); + struct rsnd_dai_stream *io_playback; + struct rsnd_dai_stream *io_capture; + struct snd_soc_dai_driver *drv; + struct rsnd_dai *rdai; struct device *dev = &pdev->dev; - int nr, i; - int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i; + int nr, dai_i, io_i, np_i; + int ret; if (!of_data) - return; - - dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai"); - if (!dai_node) - return; + return 0; + dai_node = rsnd_dai_of_node(priv); nr = of_get_child_count(dai_node); - if (!nr) - return; - - dai_info = devm_kzalloc(dev, - sizeof(struct rsnd_dai_platform_info) * nr, - GFP_KERNEL); - if (!dai_info) { - dev_err(dev, "dai info allocation error\n"); - return; + if (!nr) { + ret = -EINVAL; + goto rsnd_dai_probe_done; } - info->dai_info_nr = nr; - info->dai_info = dai_info; - - ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); - src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); - ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu"); - mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix"); - dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc"); + drv = devm_kzalloc(dev, sizeof(*drv) * nr, GFP_KERNEL); + rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL); + if (!drv || !rdai) { + ret = -ENOMEM; + goto rsnd_dai_probe_done; + } -#define mod_parse(name) \ -if (name##_node) { \ - struct rsnd_##name##_platform_info *name##_info; \ - \ - name##_i = 0; \ - for_each_child_of_node(name##_node, name##_np) { \ - name##_info = info->name##_info + name##_i; \ - \ - if (name##_np == playback) \ - dai_info->playback.name = name##_info; \ - if (name##_np == capture) \ - dai_info->capture.name = name##_info; \ - \ - name##_i++; \ - } \ -} + priv->rdai_nr = nr; + priv->daidrv = drv; + priv->rdai = rdai; /* * parse all dai */ dai_i = 0; for_each_child_of_node(dai_node, dai_np) { - dai_info = info->dai_info + dai_i; + rdai = rsnd_rdai_get(priv, dai_i); + drv = drv + dai_i; + io_playback = &rdai->playback; + io_capture = &rdai->capture; + + snprintf(rdai->name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", dai_i); + + rdai->priv = priv; + drv->name = rdai->name; + drv->ops = &rsnd_soc_dai_ops; + + snprintf(rdai->playback.name, RSND_DAI_NAME_SIZE, + "DAI%d Playback", dai_i); + drv->playback.rates = RSND_RATES; + drv->playback.formats = RSND_FMTS; + drv->playback.channels_min = 2; + drv->playback.channels_max = 2; + drv->playback.stream_name = rdai->playback.name; + + snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, + "DAI%d Capture", dai_i); + drv->capture.rates = RSND_RATES; + drv->capture.formats = RSND_FMTS; + drv->capture.channels_min = 2; + drv->capture.channels_max = 2; + drv->capture.stream_name = rdai->capture.name; + + rdai->playback.rdai = rdai; + rdai->capture.rdai = rdai; - for (i = 0;; i++) { +#define mod_parse(name) \ +node = rsnd_##name##_of_node(priv); \ +if (node) { \ + struct rsnd_mod *mod; \ + np_i = 0; \ + for_each_child_of_node(node, np) { \ + mod = rsnd_##name##_mod_get(priv, np_i); \ + if (np == playback) \ + rsnd_dai_connect(mod, io_playback, mod->type); \ + if (np == capture) \ + rsnd_dai_connect(mod, io_capture, mod->type); \ + np_i++; \ + } \ + of_node_put(node); \ +} - playback = of_parse_phandle(dai_np, "playback", i); - capture = of_parse_phandle(dai_np, "capture", i); + for (io_i = 0;; io_i++) { + playback = of_parse_phandle(dai_np, "playback", io_i); + capture = of_parse_phandle(dai_np, "capture", io_i); if (!playback && !capture) break; @@ -722,91 +673,18 @@ if (name##_node) { \ } dai_i++; - } -} - -static int rsnd_dai_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct snd_soc_dai_driver *drv; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct rsnd_dai *rdai; - struct rsnd_ssi_platform_info *pmod, *cmod; - struct device *dev = rsnd_priv_to_dev(priv); - int dai_nr; - int i; - - rsnd_of_parse_dai(pdev, of_data, priv); - dai_nr = info->dai_info_nr; - if (!dai_nr) { - dev_err(dev, "no dai\n"); - return -EIO; - } - - drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); - rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL); - if (!drv || !rdai) { - dev_err(dev, "dai allocate failed\n"); - return -ENOMEM; + dev_dbg(dev, "%s (%s/%s)\n", rdai->name, + rsnd_io_to_mod_ssi(io_playback) ? "play" : " -- ", + rsnd_io_to_mod_ssi(io_capture) ? "capture" : " -- "); } - priv->rdai_nr = dai_nr; - priv->daidrv = drv; - priv->rdai = rdai; - - for (i = 0; i < dai_nr; i++) { - - pmod = info->dai_info[i].playback.ssi; - cmod = info->dai_info[i].capture.ssi; - - /* - * init rsnd_dai - */ - snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); - rdai[i].priv = priv; - - /* - * init snd_soc_dai_driver - */ - drv[i].name = rdai[i].name; - drv[i].ops = &rsnd_soc_dai_ops; - if (pmod) { - snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE, - "DAI%d Playback", i); - - drv[i].playback.rates = RSND_RATES; - drv[i].playback.formats = RSND_FMTS; - drv[i].playback.channels_min = 2; - drv[i].playback.channels_max = 2; - drv[i].playback.stream_name = rdai[i].playback.name; - - rdai[i].playback.info = &info->dai_info[i].playback; - rdai[i].playback.rdai = rdai + i; - rsnd_path_init(priv, &rdai[i], &rdai[i].playback); - } - if (cmod) { - snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE, - "DAI%d Capture", i); - - drv[i].capture.rates = RSND_RATES; - drv[i].capture.formats = RSND_FMTS; - drv[i].capture.channels_min = 2; - drv[i].capture.channels_max = 2; - drv[i].capture.stream_name = rdai[i].capture.name; - - rdai[i].capture.info = &info->dai_info[i].capture; - rdai[i].capture.rdai = rdai + i; - rsnd_path_init(priv, &rdai[i], &rdai[i].capture); - } + ret = 0; - dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name, - pmod ? "play" : " -- ", - cmod ? "capture" : " -- "); - } +rsnd_dai_probe_done: + of_node_put(dai_node); - return 0; + return ret; } /* diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 6b76ae6cf549..daa1017c8890 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -90,7 +90,7 @@ static void rsnd_of_parse_ctu(struct platform_device *pdev, if (!of_data) return; - node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu"); + node = rsnd_ctu_of_node(priv); if (!node) return; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 0dc8a2a99fa4..d2bd4804db0d 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -317,7 +317,7 @@ static void rsnd_of_parse_dvc(struct platform_device *pdev, if (!of_data) return; - node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc"); + node = rsnd_dvc_of_node(priv); if (!node) return; diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 2baa2d79bfc0..195bc748a32f 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -130,7 +130,7 @@ static void rsnd_of_parse_mix(struct platform_device *pdev, if (!of_data) return; - node = of_get_child_by_name(dev->of_node, "rcar_sound,mix"); + node = rsnd_mix_of_node(priv); if (!node) return; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index a3e42a4f4b19..23507c8d79c2 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -338,6 +338,8 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); int rsnd_dai_connect(struct rsnd_mod *mod, struct rsnd_dai_stream *io, enum rsnd_mod_type type); +#define rsnd_dai_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dai") /* * R-Car Gen1/Gen2 @@ -524,6 +526,9 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); +#define rsnd_ssi_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") + /* * R-Car SSIU */ @@ -547,6 +552,8 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, struct snd_pcm_runtime *runtime); +#define rsnd_src_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") /* * R-Car CTU @@ -558,6 +565,8 @@ int rsnd_ctu_probe(struct platform_device *pdev, void rsnd_ctu_remove(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); +#define rsnd_ctu_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu") /* * R-Car MIX @@ -569,6 +578,8 @@ int rsnd_mix_probe(struct platform_device *pdev, void rsnd_mix_remove(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); +#define rsnd_mix_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix") /* * R-Car DVC @@ -579,6 +590,8 @@ int rsnd_dvc_probe(struct platform_device *pdev, void rsnd_dvc_remove(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); +#define rsnd_dvc_of_node(priv) \ + of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") /* * R-Car CMD diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index d081a652f917..230db9f81377 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -34,8 +34,6 @@ struct rsnd_src { #define rsnd_src_to_dma(src) ((src)->dma) #define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_enable_sync_convert(src) ((src)->sen.val) -#define rsnd_src_of_node(priv) \ - of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") #define rsnd_mod_to_src(_mod) \ container_of((_mod), struct rsnd_src, mod) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 60ef074082e8..61957f609e79 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -88,8 +88,6 @@ struct rsnd_ssi { #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) -#define rsnd_ssi_of_node(priv) \ - of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) { -- cgit v1.2.3 From 02534f2f80224531ab19bf5027224ed775fe2b39 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:11:35 +0000 Subject: ASoC: rsnd: remove platform boot support from ssi.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from ssi.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rcar_snd.h | 2 - sound/soc/sh/rcar/ssi.c | 145 +++++++++++++++++-------------------------- 2 files changed, 57 insertions(+), 90 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h index d8e33d38da43..18b27e6aecbc 100644 --- a/sound/soc/sh/rcar/rcar_snd.h +++ b/sound/soc/sh/rcar/rcar_snd.h @@ -32,8 +32,6 @@ * A : clock sharing settings * B : SSI direction */ -#define RSND_SSI_CLK_PIN_SHARE (1 << 31) -#define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */ #define RSND_SSI(_dma_id, _irq, _flags) \ { .dma_id = _dma_id, .irq = _irq, .flags = _flags } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 61957f609e79..1f1ecedabb5d 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -61,32 +61,36 @@ #define SSI_NAME "ssi" struct rsnd_ssi { - struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ struct rsnd_ssi *parent; struct rsnd_mod mod; struct rsnd_mod *dma; + u32 flags; u32 cr_own; u32 cr_clk; u32 cr_mode; int chan; int rate; int err; + int irq; unsigned int usrcnt; }; +/* flags */ +#define RSND_SSI_CLK_PIN_SHARE (1 << 0) +#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ + #define for_each_rsnd_ssi(pos, priv, i) \ for (i = 0; \ (i < rsnd_ssi_nr(priv)) && \ ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \ i++) +#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id) #define rsnd_ssi_to_dma(mod) ((ssi)->dma) #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) -#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) -#define rsnd_ssi_mode_flags(p) ((p)->info->flags) -#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) +#define rsnd_ssi_mode_flags(p) ((p)->flags) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) @@ -587,7 +591,7 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, if (ret < 0) return ret; - ret = devm_request_irq(dev, ssi->info->irq, + ret = devm_request_irq(dev, ssi->irq, rsnd_ssi_interrupt, IRQF_SHARED, dev_name(dev), mod); @@ -610,7 +614,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - int dma_id = ssi->info->dma_id; + int dma_id = 0; /* not needed */ int ret; ret = rsnd_ssi_common_probe(mod, io, priv); @@ -630,7 +634,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct device *dev = rsnd_priv_to_dev(priv); - int irq = ssi->info->irq; + int irq = ssi->irq; /* PIO will request IRQ again */ devm_free_irq(dev, irq, mod); @@ -709,7 +713,7 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) id = 0; - return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id); + return rsnd_mod_get(rsnd_ssi_get(priv, id)); } int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) @@ -719,73 +723,12 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); } -static void rsnd_of_parse_ssi(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct device_node *node; - struct device_node *np; - struct rsnd_ssi_platform_info *ssi_info; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct device *dev = &pdev->dev; - int nr, i; - - node = rsnd_ssi_of_node(priv); - if (!node) - return; - - nr = of_get_child_count(node); - if (!nr) - goto rsnd_of_parse_ssi_end; - - ssi_info = devm_kzalloc(dev, - sizeof(struct rsnd_ssi_platform_info) * nr, - GFP_KERNEL); - if (!ssi_info) { - dev_err(dev, "ssi info allocation error\n"); - goto rsnd_of_parse_ssi_end; - } - - info->ssi_info = ssi_info; - info->ssi_info_nr = nr; - - i = -1; - for_each_child_of_node(node, np) { - i++; - - ssi_info = info->ssi_info + i; - - /* - * pin settings - */ - if (of_get_property(np, "shared-pin", NULL)) - ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE; - - /* - * irq - */ - ssi_info->irq = irq_of_parse_and_map(np, 0); - - /* - * DMA - */ - 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: - of_node_put(node); -} - int rsnd_ssi_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct rsnd_ssi_platform_info *pinfo; + struct device_node *node; + struct device_node *np; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_mod_ops *ops; struct clk *clk; @@ -793,44 +736,70 @@ int rsnd_ssi_probe(struct platform_device *pdev, char name[RSND_SSI_NAME_SIZE]; int i, nr, ret; - rsnd_of_parse_ssi(pdev, of_data, priv); + node = rsnd_ssi_of_node(priv); + if (!node) + return -EINVAL; + + nr = of_get_child_count(node); + if (!nr) { + ret = -EINVAL; + goto rsnd_ssi_probe_done; + } - /* - * init SSI - */ - nr = info->ssi_info_nr; ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL); - if (!ssi) - return -ENOMEM; + if (!ssi) { + ret = -ENOMEM; + goto rsnd_ssi_probe_done; + } priv->ssi = ssi; priv->ssi_nr = nr; - for_each_rsnd_ssi(ssi, priv, i) { - pinfo = &info->ssi_info[i]; + i = 0; + for_each_child_of_node(node, np) { + ssi = rsnd_ssi_get(priv, i); snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d", SSI_NAME, i); clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) - return PTR_ERR(clk); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto rsnd_ssi_probe_done; + } - ssi->info = pinfo; + if (of_get_property(np, "shared-pin", NULL)) + ssi->flags |= RSND_SSI_CLK_PIN_SHARE; + + if (of_get_property(np, "no-busif", NULL)) + ssi->flags |= RSND_SSI_NO_BUSIF; + + ssi->irq = irq_of_parse_and_map(np, 0); + if (!ssi->irq) { + ret = -EINVAL; + goto rsnd_ssi_probe_done; + } ops = &rsnd_ssi_non_ops; - if (pinfo->dma_id > 0) - ops = &rsnd_ssi_dma_ops; - else if (rsnd_ssi_pio_available(ssi)) + if (of_get_property(np, "pio-transfer", NULL)) ops = &rsnd_ssi_pio_ops; + else + ops = &rsnd_ssi_dma_ops; ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, RSND_MOD_SSI, i); if (ret) - return ret; + goto rsnd_ssi_probe_done; + + i++; } - return 0; + ret = 0; + +rsnd_ssi_probe_done: + of_node_put(node); + + return ret; } void rsnd_ssi_remove(struct platform_device *pdev, -- cgit v1.2.3 From adf6a6815952c6c6092ae15e27c1b782fd96c6a3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:11:55 +0000 Subject: ASoC: rsnd: remove platform boot support from src.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from src.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 158 +++++++++++++----------------------------------- 1 file changed, 43 insertions(+), 115 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 230db9f81377..f965fea7aa50 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -20,17 +20,18 @@ #define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) struct rsnd_src { - struct rsnd_src_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct rsnd_mod *dma; struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ struct rsnd_kctrl_cfg_s sync; /* sync convert */ u32 convert_rate; /* sampling rate convert */ int err; + int irq; }; #define RSND_SRC_NAME_SIZE 16 +#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id) #define rsnd_src_to_dma(src) ((src)->dma) #define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_enable_sync_convert(src) ((src)->sen.val) @@ -69,52 +70,6 @@ struct rsnd_src { * |-----------------| */ -/* - * How to use SRC bypass mode for debugging - * - * SRC has bypass mode, and it is useful for debugging. - * In Gen2 case, - * SRCm_MODE controls whether SRC is used or not - * SSI_MODE0 controls whether SSIU which receives SRC data - * is used or not. - * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC, - * but SRC bypass mode needs SSI_MODE0 only. - * - * This driver request - * struct rsnd_src_platform_info { - * u32 convert_rate; - * int dma_id; - * } - * - * rsnd_src_convert_rate() indicates - * above convert_rate, and it controls - * whether SRC is used or not. - * - * ex) doesn't use SRC - * static struct rsnd_dai_platform_info rsnd_dai = { - * .playback = { .ssi = &rsnd_ssi[0], }, - * }; - * - * ex) uses SRC - * static struct rsnd_src_platform_info rsnd_src[] = { - * RSND_SCU(48000, 0), - * ... - * }; - * static struct rsnd_dai_platform_info rsnd_dai = { - * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, - * }; - * - * ex) uses SRC bypass mode - * static struct rsnd_src_platform_info rsnd_src[] = { - * RSND_SCU(0, 0), - * ... - * }; - * static struct rsnd_dai_platform_info rsnd_dai = { - * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, - * }; - * - */ - static void rsnd_src_soft_reset(struct rsnd_mod *mod) { rsnd_mod_write(mod, SRC_SWRSR, 0); @@ -187,9 +142,6 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod, struct rsnd_src *src = rsnd_mod_to_src(mod); struct snd_soc_pcm_runtime *fe = substream->private_data; - /* default value (mainly for non-DT) */ - src->convert_rate = src->info->convert_rate; - /* * SRC assumes that it is used under DPCM if user want to use * sampling rate convert. Then, SRC should be FE. @@ -318,7 +270,7 @@ static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 sys_int_val, int_val, sys_int_mask; - int irq = src->info->irq; + int irq = src->irq; int id = rsnd_mod_id(mod); sys_int_val = @@ -517,7 +469,7 @@ static int rsnd_src_probe_(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); struct device *dev = rsnd_priv_to_dev(priv); - int irq = src->info->irq; + int irq = src->irq; int ret; if (irq > 0) { @@ -534,7 +486,7 @@ static int rsnd_src_probe_(struct rsnd_mod *mod, return ret; } - src->dma = rsnd_dma_attach(io, mod, src->info->dma_id); + src->dma = rsnd_dma_attach(io, mod, 0); if (IS_ERR(src->dma)) return PTR_ERR(src->dma); @@ -598,58 +550,15 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) id = 0; - return rsnd_mod_get((struct rsnd_src *)(priv->src) + id); -} - -static void rsnd_of_parse_src(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct device_node *src_node; - struct device_node *np; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct rsnd_src_platform_info *src_info; - struct device *dev = &pdev->dev; - int nr, i; - - if (!of_data) - return; - - src_node = rsnd_src_of_node(priv); - if (!src_node) - return; - - nr = of_get_child_count(src_node); - if (!nr) - goto rsnd_of_parse_src_end; - - src_info = devm_kzalloc(dev, - sizeof(struct rsnd_src_platform_info) * nr, - GFP_KERNEL); - if (!src_info) { - dev_err(dev, "src info allocation error\n"); - goto rsnd_of_parse_src_end; - } - - info->src_info = src_info; - info->src_info_nr = nr; - - i = 0; - for_each_child_of_node(src_node, np) { - src_info[i].irq = irq_of_parse_and_map(np, 0); - - i++; - } - -rsnd_of_parse_src_end: - of_node_put(src_node); + return rsnd_mod_get(rsnd_src_get(priv, id)); } int rsnd_src_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { - struct rcar_snd_info *info = rsnd_priv_to_info(priv); + struct device_node *node; + struct device_node *np; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_src *src; struct clk *clk; @@ -660,39 +569,58 @@ int rsnd_src_probe(struct platform_device *pdev, if (rsnd_is_gen1(priv)) return 0; - rsnd_of_parse_src(pdev, of_data, priv); + node = rsnd_src_of_node(priv); + if (!node) + return 0; /* not used is not error */ - /* - * init SRC - */ - nr = info->src_info_nr; - if (!nr) - return 0; + nr = of_get_child_count(node); + if (!nr) { + ret = -EINVAL; + goto rsnd_src_probe_done; + } src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); - if (!src) - return -ENOMEM; + if (!src) { + ret = -ENOMEM; + goto rsnd_src_probe_done; + } priv->src_nr = nr; priv->src = src; - for_each_rsnd_src(src, priv, i) { + i = 0; + for_each_child_of_node(node, np) { + src = rsnd_src_get(priv, i); + snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", SRC_NAME, i); - clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) - return PTR_ERR(clk); + src->irq = irq_of_parse_and_map(np, 0); + if (!src->irq) { + ret = -EINVAL; + goto rsnd_src_probe_done; + } - src->info = &info->src_info[i]; + clk = devm_clk_get(dev, name); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto rsnd_src_probe_done; + } ret = rsnd_mod_init(priv, rsnd_mod_get(src), &rsnd_src_ops, clk, RSND_MOD_SRC, i); if (ret) - return ret; + goto rsnd_src_probe_done; + + i++; } - return 0; + ret = 0; + +rsnd_src_probe_done: + of_node_put(node); + + return ret; } void rsnd_src_remove(struct platform_device *pdev, -- cgit v1.2.3 From cfe7c0390ac24c30bf8c79a6a05e637db56e3090 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:12:13 +0000 Subject: ASoC: rsnd: remove platform boot support from ctu.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from ctu.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ctu.c | 85 +++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 53 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index daa1017c8890..9506db4958bc 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -13,7 +13,6 @@ #define CTU_NAME "ctu" struct rsnd_ctu { - struct rsnd_ctu_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; }; @@ -24,6 +23,7 @@ struct rsnd_ctu { ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \ i++) +#define rsnd_ctu_get(priv, id) ((struct rsnd_ctu *)(priv->ctu) + id) #define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1) #define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0) static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable) @@ -74,51 +74,15 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) id = 0; - return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id); -} - -static void rsnd_of_parse_ctu(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct device_node *node; - struct rsnd_ctu_platform_info *ctu_info; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct device *dev = &pdev->dev; - int nr; - - if (!of_data) - return; - - node = rsnd_ctu_of_node(priv); - if (!node) - return; - - nr = of_get_child_count(node); - if (!nr) - goto rsnd_of_parse_ctu_end; - - ctu_info = devm_kzalloc(dev, - sizeof(struct rsnd_ctu_platform_info) * nr, - GFP_KERNEL); - if (!ctu_info) { - dev_err(dev, "ctu info allocation error\n"); - goto rsnd_of_parse_ctu_end; - } - - info->ctu_info = ctu_info; - info->ctu_info_nr = nr; - -rsnd_of_parse_ctu_end: - of_node_put(node); - + return rsnd_mod_get(rsnd_ctu_get(priv, id)); } int rsnd_ctu_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { - struct rcar_snd_info *info = rsnd_priv_to_info(priv); + struct device_node *node; + struct device_node *np; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ctu *ctu; struct clk *clk; @@ -129,20 +93,29 @@ int rsnd_ctu_probe(struct platform_device *pdev, if (rsnd_is_gen1(priv)) return 0; - rsnd_of_parse_ctu(pdev, of_data, priv); + node = rsnd_ctu_of_node(priv); + if (!node) + return 0; /* not used is not error */ - nr = info->ctu_info_nr; - if (!nr) - return 0; + nr = of_get_child_count(node); + if (!nr) { + ret = -EINVAL; + goto rsnd_ctu_probe_done; + } ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL); - if (!ctu) - return -ENOMEM; + if (!ctu) { + ret = -ENOMEM; + goto rsnd_ctu_probe_done; + } priv->ctu_nr = nr; priv->ctu = ctu; - for_each_rsnd_ctu(ctu, priv, i) { + i = 0; + for_each_child_of_node(node, np) { + ctu = rsnd_ctu_get(priv, i); + /* * CTU00, CTU01, CTU02, CTU03 => CTU0 * CTU10, CTU11, CTU12, CTU13 => CTU1 @@ -151,18 +124,24 @@ int rsnd_ctu_probe(struct platform_device *pdev, CTU_NAME, i / 4); clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - ctu->info = &info->ctu_info[i]; + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto rsnd_ctu_probe_done; + } ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, clk, RSND_MOD_CTU, i); if (ret) - return ret; + goto rsnd_ctu_probe_done; + + i++; } - return 0; + +rsnd_ctu_probe_done: + of_node_put(node); + + return ret; } void rsnd_ctu_remove(struct platform_device *pdev, -- cgit v1.2.3 From c7fe4be840026d7cdb0676e1d52b9f82e8b32d41 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:12:32 +0000 Subject: ASoC: rsnd: remove platform boot support from mix.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from mix.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/mix.c | 85 ++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 54 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 195bc748a32f..8b615c7aecb4 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -13,10 +13,10 @@ #define MIX_NAME "mix" struct rsnd_mix { - struct rsnd_mix_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; }; +#define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id) #define rsnd_mix_nr(priv) ((priv)->mix_nr) #define for_each_rsnd_mix(pos, priv, i) \ for ((i) = 0; \ @@ -24,7 +24,6 @@ struct rsnd_mix { ((pos) = (struct rsnd_mix *)(priv)->mix + i); \ i++) - static void rsnd_mix_soft_reset(struct rsnd_mod *mod) { rsnd_mod_write(mod, MIX_SWRSR, 0); @@ -114,51 +113,15 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) id = 0; - return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id); -} - -static void rsnd_of_parse_mix(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct device_node *node; - struct rsnd_mix_platform_info *mix_info; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct device *dev = &pdev->dev; - int nr; - - if (!of_data) - return; - - node = rsnd_mix_of_node(priv); - if (!node) - return; - - nr = of_get_child_count(node); - if (!nr) - goto rsnd_of_parse_mix_end; - - mix_info = devm_kzalloc(dev, - sizeof(struct rsnd_mix_platform_info) * nr, - GFP_KERNEL); - if (!mix_info) { - dev_err(dev, "mix info allocation error\n"); - goto rsnd_of_parse_mix_end; - } - - info->mix_info = mix_info; - info->mix_info_nr = nr; - -rsnd_of_parse_mix_end: - of_node_put(node); - + return rsnd_mod_get(rsnd_mix_get(priv, id)); } int rsnd_mix_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { - struct rcar_snd_info *info = rsnd_priv_to_info(priv); + struct device_node *node; + struct device_node *np; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_mix *mix; struct clk *clk; @@ -169,36 +132,50 @@ int rsnd_mix_probe(struct platform_device *pdev, if (rsnd_is_gen1(priv)) return 0; - rsnd_of_parse_mix(pdev, of_data, priv); + node = rsnd_mix_of_node(priv); + if (!node) + return 0; /* not used is not error */ - nr = info->mix_info_nr; - if (!nr) - return 0; + nr = of_get_child_count(node); + if (!nr) { + ret = -EINVAL; + goto rsnd_mix_probe_done; + } mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL); - if (!mix) - return -ENOMEM; + if (!mix) { + ret = -ENOMEM; + goto rsnd_mix_probe_done; + } priv->mix_nr = nr; priv->mix = mix; - for_each_rsnd_mix(mix, priv, i) { + i = 0; + for_each_child_of_node(node, np) { + mix = rsnd_mix_get(priv, i); + snprintf(name, MIX_NAME_SIZE, "%s.%d", MIX_NAME, i); clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - mix->info = &info->mix_info[i]; + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto rsnd_mix_probe_done; + } ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, clk, RSND_MOD_MIX, i); if (ret) - return ret; + goto rsnd_mix_probe_done; + + i++; } - return 0; +rsnd_mix_probe_done: + of_node_put(node); + + return ret; } void rsnd_mix_remove(struct platform_device *pdev, -- cgit v1.2.3 From 9eaa1a6f7e31ead7e2b8eb762455e77376bd87cc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:12:50 +0000 Subject: ASoC: rsnd: remove platform boot support from dvc.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from dvc.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 83 ++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 52 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index d2bd4804db0d..a550b75ff9ac 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -15,7 +15,6 @@ #define DVC_NAME "dvc" struct rsnd_dvc { - struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct rsnd_kctrl_cfg_m volume; struct rsnd_kctrl_cfg_m mute; @@ -24,6 +23,7 @@ struct rsnd_dvc { struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ }; +#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id) #define rsnd_dvc_nr(priv) ((priv)->dvc_nr) #define rsnd_dvc_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") @@ -301,50 +301,15 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) id = 0; - return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id); -} - -static void rsnd_of_parse_dvc(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct device_node *node; - struct rsnd_dvc_platform_info *dvc_info; - struct rcar_snd_info *info = rsnd_priv_to_info(priv); - struct device *dev = &pdev->dev; - int nr; - - if (!of_data) - return; - - node = rsnd_dvc_of_node(priv); - if (!node) - return; - - nr = of_get_child_count(node); - if (!nr) - goto rsnd_of_parse_dvc_end; - - dvc_info = devm_kzalloc(dev, - sizeof(struct rsnd_dvc_platform_info) * nr, - GFP_KERNEL); - if (!dvc_info) { - dev_err(dev, "dvc info allocation error\n"); - goto rsnd_of_parse_dvc_end; - } - - info->dvc_info = dvc_info; - info->dvc_info_nr = nr; - -rsnd_of_parse_dvc_end: - of_node_put(node); + return rsnd_mod_get(rsnd_dvc_get(priv, id)); } int rsnd_dvc_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { - struct rcar_snd_info *info = rsnd_priv_to_info(priv); + struct device_node *node; + struct device_node *np; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_dvc *dvc; struct clk *clk; @@ -355,36 +320,50 @@ int rsnd_dvc_probe(struct platform_device *pdev, if (rsnd_is_gen1(priv)) return 0; - rsnd_of_parse_dvc(pdev, of_data, priv); + node = rsnd_dvc_of_node(priv); + if (!node) + return 0; /* not used is not error */ - nr = info->dvc_info_nr; - if (!nr) - return 0; + nr = of_get_child_count(node); + if (!nr) { + ret = -EINVAL; + goto rsnd_dvc_probe_done; + } dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); - if (!dvc) - return -ENOMEM; + if (!dvc) { + ret = -ENOMEM; + goto rsnd_dvc_probe_done; + } priv->dvc_nr = nr; priv->dvc = dvc; - for_each_rsnd_dvc(dvc, priv, i) { + i = 0; + for_each_child_of_node(node, np) { + dvc = rsnd_dvc_get(priv, i); + snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d", DVC_NAME, i); clk = devm_clk_get(dev, name); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - dvc->info = &info->dvc_info[i]; + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto rsnd_dvc_probe_done; + } ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, clk, RSND_MOD_DVC, i); if (ret) - return ret; + goto rsnd_dvc_probe_done; + + i++; } - return 0; +rsnd_dvc_probe_done: + of_node_put(node); + + return ret; } void rsnd_dvc_remove(struct platform_device *pdev, -- cgit v1.2.3 From 348d592c719da61a7dab289c7ce36e73c7caf063 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:13:12 +0000 Subject: ASoC: rsnd: remove platform boot support from gen.c No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. This patch removes platform boot support from gen.c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 1 + sound/soc/sh/rcar/gen.c | 14 -------------- sound/soc/sh/rcar/rsnd.h | 7 ++++--- 3 files changed, 5 insertions(+), 17 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 039d6cba8414..6043c71d10c9 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1037,6 +1037,7 @@ static int rsnd_probe(struct platform_device *pdev) priv->pdev = pdev; priv->info = info; + priv->flags = of_data->flags; spin_lock_init(&priv->lock); /* diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 1808fc64646c..099a1cd2d245 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -349,18 +349,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev, /* * Gen */ -static void rsnd_of_parse_gen(struct platform_device *pdev, - const struct rsnd_of_data *of_data, - struct rsnd_priv *priv) -{ - struct rcar_snd_info *info = priv->info; - - if (!of_data) - return; - - info->flags = of_data->flags; -} - int rsnd_gen_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) @@ -369,8 +357,6 @@ int rsnd_gen_probe(struct platform_device *pdev, struct rsnd_gen *gen; int ret; - rsnd_of_parse_gen(pdev, of_data, priv); - gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); if (!gen) { dev_err(dev, "GEN allocate failed\n"); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 23507c8d79c2..c1cf16db6405 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -352,9 +352,6 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, enum rsnd_reg reg); phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); -#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) -#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) - /* * R-Car ADG */ @@ -386,6 +383,7 @@ struct rsnd_priv { struct platform_device *pdev; struct rcar_snd_info *info; spinlock_t lock; + u32 flags; /* * below value will be filled on rsnd_gen_probe() @@ -456,6 +454,9 @@ struct rsnd_priv { #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) #define rsnd_priv_to_info(priv) ((priv)->info) +#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) +#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) + /* * rsnd_kctrl */ -- cgit v1.2.3 From e797f58ead6069478e535ae62b180da87b28a84f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:13:33 +0000 Subject: ASoC: rsnd: remove struct rsnd_of_data No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. Now, platform boot style was removed from driver. This is cleanup patch, and remove pointless struct rsnd_of_data Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 1 - sound/soc/sh/rcar/cmd.c | 1 - sound/soc/sh/rcar/core.c | 25 +++++-------------------- sound/soc/sh/rcar/ctu.c | 1 - sound/soc/sh/rcar/dma.c | 1 - sound/soc/sh/rcar/dvc.c | 1 - sound/soc/sh/rcar/gen.c | 1 - sound/soc/sh/rcar/mix.c | 1 - sound/soc/sh/rcar/rsnd.h | 15 --------------- sound/soc/sh/rcar/src.c | 1 - sound/soc/sh/rcar/ssi.c | 1 - sound/soc/sh/rcar/ssiu.c | 1 - 12 files changed, 5 insertions(+), 45 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 1dffde3218be..ba80961a8fa8 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -516,7 +516,6 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, } int rsnd_adg_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct rsnd_adg *adg; diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index 47ef47c22217..2294c5c7a25a 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c @@ -128,7 +128,6 @@ struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id) } int rsnd_cmd_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 6043c71d10c9..8b9d721acb41 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -99,18 +99,10 @@ #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) -static const struct rsnd_of_data rsnd_of_data_gen1 = { - .flags = RSND_GEN1, -}; - -static const struct rsnd_of_data rsnd_of_data_gen2 = { - .flags = RSND_GEN2, -}; - static const struct of_device_id rsnd_of_match[] = { - { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, - { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, - { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */ + { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, + { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, + { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */ {}, }; MODULE_DEVICE_TABLE(of, rsnd_of_match); @@ -569,7 +561,6 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { }; static int rsnd_dai_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *dai_node; @@ -583,9 +574,6 @@ static int rsnd_dai_probe(struct platform_device *pdev, int nr, dai_i, io_i, np_i; int ret; - if (!of_data) - return 0; - dai_node = rsnd_dai_of_node(priv); nr = of_get_child_count(dai_node); if (!nr) { @@ -1002,9 +990,7 @@ static int rsnd_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rsnd_dai *rdai; const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); - const struct rsnd_of_data *of_data; int (*probe_func[])(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) = { rsnd_gen_probe, rsnd_dma_probe, @@ -1024,7 +1010,6 @@ static int rsnd_probe(struct platform_device *pdev) GFP_KERNEL); if (!info) return -ENOMEM; - of_data = of_id->data; /* * init priv data @@ -1037,14 +1022,14 @@ static int rsnd_probe(struct platform_device *pdev) priv->pdev = pdev; priv->info = info; - priv->flags = of_data->flags; + priv->flags = (u32)of_id->data; spin_lock_init(&priv->lock); /* * init each module */ for (i = 0; i < ARRAY_SIZE(probe_func); i++) { - ret = probe_func[i](pdev, of_data, priv); + ret = probe_func[i](pdev, priv); if (ret) return ret; } diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 9506db4958bc..3e36a5325ce4 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -78,7 +78,6 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) } int rsnd_ctu_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *node; diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 9917b985c403..e5f435361d96 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -702,7 +702,6 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, } int rsnd_dma_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index a550b75ff9ac..d2c03bd94fcb 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -305,7 +305,6 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) } int rsnd_dvc_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *node; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 099a1cd2d245..ced8acb7a7ec 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -350,7 +350,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev, * Gen */ int rsnd_gen_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 8b615c7aecb4..897e4f3d4c24 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -117,7 +117,6 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) } int rsnd_mix_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *node; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index c1cf16db6405..0ad3d0d20a81 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -115,7 +115,6 @@ enum rsnd_reg { RSND_REG_MAX, }; -struct rsnd_of_data; struct rsnd_priv; struct rsnd_mod; struct rsnd_dai; @@ -150,7 +149,6 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); int rsnd_dma_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, struct rsnd_mod *mod, char *name); @@ -345,7 +343,6 @@ int rsnd_dai_connect(struct rsnd_mod *mod, * R-Car Gen1/Gen2 */ int rsnd_gen_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, @@ -358,7 +355,6 @@ phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_adg_remove(struct platform_device *pdev, struct rsnd_priv *priv); @@ -374,10 +370,6 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, /* * R-Car sound priv */ -struct rsnd_of_data { - u32 flags; -}; - struct rsnd_priv { struct platform_device *pdev; @@ -515,7 +507,6 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, * R-Car SSI */ int rsnd_ssi_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_ssi_remove(struct platform_device *pdev, struct rsnd_priv *priv); @@ -536,7 +527,6 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); int rsnd_ssiu_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod); int rsnd_ssiu_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_ssiu_remove(struct platform_device *pdev, struct rsnd_priv *priv); @@ -545,7 +535,6 @@ void rsnd_ssiu_remove(struct platform_device *pdev, * R-Car SRC */ int rsnd_src_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_src_remove(struct platform_device *pdev, struct rsnd_priv *priv); @@ -560,7 +549,6 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, * R-Car CTU */ int rsnd_ctu_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_ctu_remove(struct platform_device *pdev, @@ -573,7 +561,6 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); * R-Car MIX */ int rsnd_mix_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_mix_remove(struct platform_device *pdev, @@ -586,7 +573,6 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); * R-Car DVC */ int rsnd_dvc_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_dvc_remove(struct platform_device *pdev, struct rsnd_priv *priv); @@ -598,7 +584,6 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); * R-Car CMD */ int rsnd_cmd_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv); void rsnd_cmd_remove(struct platform_device *pdev, struct rsnd_priv *priv); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index f965fea7aa50..c0f7e2a4b688 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -554,7 +554,6 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) } int rsnd_src_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *node; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 1f1ecedabb5d..848c06436226 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -724,7 +724,6 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) } int rsnd_ssi_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *node; diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index fc5ec17fe37e..89b1bc77cb8a 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -137,7 +137,6 @@ int rsnd_ssiu_attach(struct rsnd_dai_stream *io, } int rsnd_ssiu_probe(struct platform_device *pdev, - const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); -- cgit v1.2.3 From 2ea2cc86db7c73dc4e3a9fc3232cb04fe1b1ab91 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:13:53 +0000 Subject: ASoC: rsnd: remove struct rcar_snd_info No board is using Renesas sound driver via platform boot now. This means all user is using DT boot. Platform boot support is no longer needed. But, it strongly depends on platform boot style. Now, platform boot style was removed from driver. This is cleanup patch, and remove pointless struct rcar_snd_info Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 21 -------- sound/soc/sh/rcar/rcar_snd.h | 115 ------------------------------------------- sound/soc/sh/rcar/rsnd.h | 16 ++++-- 3 files changed, 13 insertions(+), 139 deletions(-) delete mode 100644 sound/soc/sh/rcar/rcar_snd.h (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8b9d721acb41..8af166809629 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -107,13 +107,6 @@ static const struct of_device_id rsnd_of_match[] = { }; MODULE_DEVICE_TABLE(of, rsnd_of_match); -/* - * rsnd_platform functions - */ -#define rsnd_platform_call(priv, dai, func, param...) \ - (!(priv->info->func) ? 0 : \ - priv->info->func(param)) - /* * rsnd_mod functions */ @@ -457,7 +450,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct rsnd_priv *priv = rsnd_dai_to_priv(dai); struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); - int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io)); int ret; unsigned long flags; @@ -467,10 +459,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: rsnd_dai_stream_init(io, substream); - ret = rsnd_platform_call(priv, dai, start, ssi_id); - if (ret < 0) - goto dai_trigger_end; - ret = rsnd_dai_call(init, io, priv); if (ret < 0) goto dai_trigger_end; @@ -484,8 +472,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, ret |= rsnd_dai_call(quit, io, priv); - ret |= rsnd_platform_call(priv, dai, stop, ssi_id); - rsnd_dai_stream_quit(io); break; default: @@ -985,7 +971,6 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, */ static int rsnd_probe(struct platform_device *pdev) { - struct rcar_snd_info *info; struct rsnd_priv *priv; struct device *dev = &pdev->dev; struct rsnd_dai *rdai; @@ -1006,11 +991,6 @@ static int rsnd_probe(struct platform_device *pdev) }; int ret, i; - info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info), - GFP_KERNEL); - if (!info) - return -ENOMEM; - /* * init priv data */ @@ -1021,7 +1001,6 @@ static int rsnd_probe(struct platform_device *pdev) } priv->pdev = pdev; - priv->info = info; priv->flags = (u32)of_id->data; spin_lock_init(&priv->lock); diff --git a/sound/soc/sh/rcar/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h deleted file mode 100644 index 18b27e6aecbc..000000000000 --- a/sound/soc/sh/rcar/rcar_snd.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Renesas R-Car SRU/SCU/SSIU/SSI support - * - * Copyright (C) 2013 Renesas Solutions Corp. - * Kuninori Morimoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef RCAR_SND_H -#define RCAR_SND_H - - -#define RSND_GEN1_SRU 0 -#define RSND_GEN1_ADG 1 -#define RSND_GEN1_SSI 2 - -#define RSND_GEN2_SCU 0 -#define RSND_GEN2_ADG 1 -#define RSND_GEN2_SSIU 2 -#define RSND_GEN2_SSI 3 - -#define RSND_BASE_MAX 4 - -/* - * flags - * - * 0xAB000000 - * - * A : clock sharing settings - * B : SSI direction - */ - -#define RSND_SSI(_dma_id, _irq, _flags) \ -{ .dma_id = _dma_id, .irq = _irq, .flags = _flags } -#define RSND_SSI_UNUSED \ -{ .dma_id = -1, .irq = -1, .flags = 0 } - -struct rsnd_ssi_platform_info { - int dma_id; - int irq; - u32 flags; -}; - -#define RSND_SRC(rate, _dma_id) \ -{ .convert_rate = rate, .dma_id = _dma_id, } -#define RSND_SRC_UNUSED \ -{ .convert_rate = 0, .dma_id = -1, } - -struct rsnd_src_platform_info { - u32 convert_rate; /* sampling rate convert */ - int dma_id; /* for Gen2 SCU */ - int irq; -}; - -/* - * flags - */ -struct rsnd_ctu_platform_info { - u32 flags; -}; - -struct rsnd_mix_platform_info { - u32 flags; -}; - -struct rsnd_dvc_platform_info { - u32 flags; -}; - -struct rsnd_dai_path_info { - struct rsnd_ssi_platform_info *ssi; - struct rsnd_src_platform_info *src; - struct rsnd_ctu_platform_info *ctu; - struct rsnd_mix_platform_info *mix; - struct rsnd_dvc_platform_info *dvc; -}; - -struct rsnd_dai_platform_info { - struct rsnd_dai_path_info playback; - struct rsnd_dai_path_info capture; -}; - -/* - * flags - * - * 0x0000000A - * - * A : generation - */ -#define RSND_GEN_MASK (0xF << 0) -#define RSND_GEN1 (1 << 0) /* fixme */ -#define RSND_GEN2 (2 << 0) /* fixme */ - -struct rcar_snd_info { - u32 flags; - struct rsnd_ssi_platform_info *ssi_info; - int ssi_info_nr; - struct rsnd_src_platform_info *src_info; - int src_info_nr; - struct rsnd_ctu_platform_info *ctu_info; - int ctu_info_nr; - struct rsnd_mix_platform_info *mix_info; - int mix_info_nr; - struct rsnd_dvc_platform_info *dvc_info; - int dvc_info_nr; - struct rsnd_dai_platform_info *dai_info; - int dai_info_nr; - int (*start)(int id); - int (*stop)(int id); -}; - -#endif diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 0ad3d0d20a81..e6efac29113d 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -24,7 +24,16 @@ #include #include -#include "rcar_snd.h" +#define RSND_GEN1_SRU 0 +#define RSND_GEN1_ADG 1 +#define RSND_GEN1_SSI 2 + +#define RSND_GEN2_SCU 0 +#define RSND_GEN2_ADG 1 +#define RSND_GEN2_SSIU 2 +#define RSND_GEN2_SSI 3 + +#define RSND_BASE_MAX 4 /* * pseudo register @@ -373,9 +382,11 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, struct rsnd_priv { struct platform_device *pdev; - struct rcar_snd_info *info; spinlock_t lock; u32 flags; +#define RSND_GEN_MASK (0xF << 0) +#define RSND_GEN1 (1 << 0) +#define RSND_GEN2 (2 << 0) /* * below value will be filled on rsnd_gen_probe() @@ -444,7 +455,6 @@ struct rsnd_priv { #define rsnd_priv_to_pdev(priv) ((priv)->pdev) #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) -#define rsnd_priv_to_info(priv) ((priv)->info) #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) -- cgit v1.2.3 From 2ea6b0749c366787dbf6e87c7642e23b448ca63b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Nov 2015 05:14:12 +0000 Subject: ASoC: rsnd: remove struct platform_device from probe/remove parameter Current Renesas sound driver requests struct platform_device on probe/remove for each modules. But driver can get it by rsnd_priv_to_pdev(). This patch removes unnecessary parameter Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 6 ++---- sound/soc/sh/rcar/cmd.c | 6 ++---- sound/soc/sh/rcar/core.c | 15 ++++++------- sound/soc/sh/rcar/ctu.c | 6 ++---- sound/soc/sh/rcar/dma.c | 4 ++-- sound/soc/sh/rcar/dvc.c | 6 ++---- sound/soc/sh/rcar/gen.c | 13 +++++------ sound/soc/sh/rcar/mix.c | 6 ++---- sound/soc/sh/rcar/rsnd.h | 56 ++++++++++++++++-------------------------------- sound/soc/sh/rcar/src.c | 6 ++---- sound/soc/sh/rcar/ssi.c | 6 ++---- sound/soc/sh/rcar/ssiu.c | 6 ++---- 12 files changed, 47 insertions(+), 89 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index ba80961a8fa8..448f082ab56d 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -515,8 +515,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, ckr, rbga, rbgb); } -int rsnd_adg_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_adg_probe(struct rsnd_priv *priv) { struct rsnd_adg *adg; struct device *dev = rsnd_priv_to_dev(priv); @@ -543,8 +542,7 @@ int rsnd_adg_probe(struct platform_device *pdev, return 0; } -void rsnd_adg_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_adg_remove(struct rsnd_priv *priv) { struct rsnd_adg *adg = rsnd_priv_to_adg(priv); struct clk *clk; diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index 2294c5c7a25a..ab904c3f20b5 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c @@ -127,8 +127,7 @@ struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id) return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id); } -int rsnd_cmd_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_cmd_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_cmd *cmd; @@ -160,8 +159,7 @@ int rsnd_cmd_probe(struct platform_device *pdev, return 0; } -void rsnd_cmd_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_cmd_remove(struct rsnd_priv *priv) { struct rsnd_cmd *cmd; int i; diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8af166809629..8dceae4b731a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -546,8 +546,7 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .set_fmt = rsnd_soc_dai_set_fmt, }; -static int rsnd_dai_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +static int rsnd_dai_probe(struct rsnd_priv *priv) { struct device_node *dai_node; struct device_node *dai_np, *np, *node; @@ -556,7 +555,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, struct rsnd_dai_stream *io_capture; struct snd_soc_dai_driver *drv; struct rsnd_dai *rdai; - struct device *dev = &pdev->dev; + struct device *dev = rsnd_priv_to_dev(priv); int nr, dai_i, io_i, np_i; int ret; @@ -975,8 +974,7 @@ static int rsnd_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rsnd_dai *rdai; const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); - int (*probe_func[])(struct platform_device *pdev, - struct rsnd_priv *priv) = { + int (*probe_func[])(struct rsnd_priv *priv) = { rsnd_gen_probe, rsnd_dma_probe, rsnd_ssi_probe, @@ -1008,7 +1006,7 @@ static int rsnd_probe(struct platform_device *pdev) * init each module */ for (i = 0; i < ARRAY_SIZE(probe_func); i++) { - ret = probe_func[i](pdev, priv); + ret = probe_func[i](priv); if (ret) return ret; } @@ -1061,8 +1059,7 @@ static int rsnd_remove(struct platform_device *pdev) { struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); struct rsnd_dai *rdai; - void (*remove_func[])(struct platform_device *pdev, - struct rsnd_priv *priv) = { + void (*remove_func[])(struct rsnd_priv *priv) = { rsnd_ssi_remove, rsnd_ssiu_remove, rsnd_src_remove, @@ -1082,7 +1079,7 @@ static int rsnd_remove(struct platform_device *pdev) } for (i = 0; i < ARRAY_SIZE(remove_func); i++) - remove_func[i](pdev, priv); + remove_func[i](priv); snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 3e36a5325ce4..7c1e190cd389 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -77,8 +77,7 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) return rsnd_mod_get(rsnd_ctu_get(priv, id)); } -int rsnd_ctu_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_ctu_probe(struct rsnd_priv *priv) { struct device_node *node; struct device_node *np; @@ -143,8 +142,7 @@ rsnd_ctu_probe_done: return ret; } -void rsnd_ctu_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_ctu_remove(struct rsnd_priv *priv) { struct rsnd_ctu *ctu; int i; diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index e5f435361d96..33eb37331498 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -701,9 +701,9 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, return rsnd_mod_get(dma); } -int rsnd_dma_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_dma_probe(struct rsnd_priv *priv) { + struct platform_device *pdev = rsnd_priv_to_pdev(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_dma_ctrl *dmac; struct resource *res; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index d2c03bd94fcb..0f61e1344431 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -304,8 +304,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) return rsnd_mod_get(rsnd_dvc_get(priv, id)); } -int rsnd_dvc_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_dvc_probe(struct rsnd_priv *priv) { struct device_node *node; struct device_node *np; @@ -365,8 +364,7 @@ rsnd_dvc_probe_done: return ret; } -void rsnd_dvc_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_dvc_remove(struct rsnd_priv *priv) { struct rsnd_dvc *dvc; int i; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index ced8acb7a7ec..84f8bb223439 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -211,8 +211,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, /* * Gen2 */ -static int rsnd_gen2_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +static int rsnd_gen2_probe(struct rsnd_priv *priv) { struct rsnd_regmap_field_conf conf_ssiu[] = { RSND_GEN_S_REG(SSI_MODE0, 0x800), @@ -317,8 +316,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev, * Gen1 */ -static int rsnd_gen1_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +static int rsnd_gen1_probe(struct rsnd_priv *priv) { struct rsnd_regmap_field_conf conf_adg[] = { RSND_GEN_S_REG(BRRA, 0x00), @@ -349,8 +347,7 @@ static int rsnd_gen1_probe(struct platform_device *pdev, /* * Gen */ -int rsnd_gen_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_gen_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_gen *gen; @@ -366,9 +363,9 @@ int rsnd_gen_probe(struct platform_device *pdev, ret = -ENODEV; if (rsnd_is_gen1(priv)) - ret = rsnd_gen1_probe(pdev, priv); + ret = rsnd_gen1_probe(priv); else if (rsnd_is_gen2(priv)) - ret = rsnd_gen2_probe(pdev, priv); + ret = rsnd_gen2_probe(priv); if (ret < 0) dev_err(dev, "unknown generation R-Car sound device\n"); diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 897e4f3d4c24..57ac453adcef 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -116,8 +116,7 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) return rsnd_mod_get(rsnd_mix_get(priv, id)); } -int rsnd_mix_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_mix_probe(struct rsnd_priv *priv) { struct device_node *node; struct device_node *np; @@ -177,8 +176,7 @@ rsnd_mix_probe_done: return ret; } -void rsnd_mix_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_mix_remove(struct rsnd_priv *priv) { struct rsnd_mix *mix; int i; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index e6efac29113d..ae69670c5c0c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -157,8 +157,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); */ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int id); -int rsnd_dma_probe(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_dma_probe(struct rsnd_priv *priv); struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, struct rsnd_mod *mod, char *name); @@ -351,8 +350,7 @@ int rsnd_dai_connect(struct rsnd_mod *mod, /* * R-Car Gen1/Gen2 */ -int rsnd_gen_probe(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_gen_probe(struct rsnd_priv *priv); void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); @@ -363,10 +361,8 @@ phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); */ int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); -int rsnd_adg_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_adg_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_adg_probe(struct rsnd_priv *priv); +void rsnd_adg_remove(struct rsnd_priv *priv); int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, unsigned int src_rate, @@ -516,10 +512,8 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, /* * R-Car SSI */ -int rsnd_ssi_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_ssi_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_ssi_probe(struct rsnd_priv *priv); +void rsnd_ssi_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); @@ -536,18 +530,14 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); */ int rsnd_ssiu_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod); -int rsnd_ssiu_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_ssiu_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_ssiu_probe(struct rsnd_priv *priv); +void rsnd_ssiu_remove(struct rsnd_priv *priv); /* * R-Car SRC */ -int rsnd_src_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_src_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_src_probe(struct rsnd_priv *priv); +void rsnd_src_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, @@ -558,11 +548,8 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, /* * R-Car CTU */ -int rsnd_ctu_probe(struct platform_device *pdev, - struct rsnd_priv *priv); - -void rsnd_ctu_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_ctu_probe(struct rsnd_priv *priv); +void rsnd_ctu_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); #define rsnd_ctu_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu") @@ -570,11 +557,8 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); /* * R-Car MIX */ -int rsnd_mix_probe(struct platform_device *pdev, - struct rsnd_priv *priv); - -void rsnd_mix_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_mix_probe(struct rsnd_priv *priv); +void rsnd_mix_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); #define rsnd_mix_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix") @@ -582,10 +566,8 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); /* * R-Car DVC */ -int rsnd_dvc_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_dvc_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_dvc_probe(struct rsnd_priv *priv); +void rsnd_dvc_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); #define rsnd_dvc_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") @@ -593,10 +575,8 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); /* * R-Car CMD */ -int rsnd_cmd_probe(struct platform_device *pdev, - struct rsnd_priv *priv); -void rsnd_cmd_remove(struct platform_device *pdev, - struct rsnd_priv *priv); +int rsnd_cmd_probe(struct rsnd_priv *priv); +void rsnd_cmd_remove(struct rsnd_priv *priv); int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index c0f7e2a4b688..c103aa775e96 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -553,8 +553,7 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) return rsnd_mod_get(rsnd_src_get(priv, id)); } -int rsnd_src_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_src_probe(struct rsnd_priv *priv) { struct device_node *node; struct device_node *np; @@ -622,8 +621,7 @@ rsnd_src_probe_done: return ret; } -void rsnd_src_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_src_remove(struct rsnd_priv *priv) { struct rsnd_src *src; int i; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 848c06436226..0fe5e3068b6b 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -723,8 +723,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); } -int rsnd_ssi_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_ssi_probe(struct rsnd_priv *priv) { struct device_node *node; struct device_node *np; @@ -801,8 +800,7 @@ rsnd_ssi_probe_done: return ret; } -void rsnd_ssi_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_ssi_remove(struct rsnd_priv *priv) { struct rsnd_ssi *ssi; int i; diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 89b1bc77cb8a..bc245047e904 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -136,8 +136,7 @@ int rsnd_ssiu_attach(struct rsnd_dai_stream *io, return rsnd_dai_connect(mod, io, mod->type); } -int rsnd_ssiu_probe(struct platform_device *pdev, - struct rsnd_priv *priv) +int rsnd_ssiu_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssiu *ssiu; @@ -168,8 +167,7 @@ int rsnd_ssiu_probe(struct platform_device *pdev, return 0; } -void rsnd_ssiu_remove(struct platform_device *pdev, - struct rsnd_priv *priv) +void rsnd_ssiu_remove(struct rsnd_priv *priv) { struct rsnd_ssiu *ssiu; int i; -- cgit v1.2.3 From c51eb1c66e55bf23af4a10dd6e71c5a82c0e6d81 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 19 Nov 2015 04:22:56 +0000 Subject: ASoC: rsnd: tidyup void* cast for 64bit compiler 64bit compiler indicates this without this patch linux/sound/soc/sh/rcar/core.c: In function 'rsnd_probe': linux/sound/soc/sh/rcar/core.c:1002:16: warning: cast from pointer to\ integer of different size [-Wpointer-to-int-cast] Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 2 +- sound/soc/sh/rcar/rsnd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 8dceae4b731a..81a6bdb6848c 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -999,7 +999,7 @@ static int rsnd_probe(struct platform_device *pdev) } priv->pdev = pdev; - priv->flags = (u32)of_id->data; + priv->flags = (unsigned long)of_id->data; spin_lock_init(&priv->lock); /* diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index ae69670c5c0c..42d2ac5cb0d1 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -379,7 +379,7 @@ struct rsnd_priv { struct platform_device *pdev; spinlock_t lock; - u32 flags; + unsigned long flags; #define RSND_GEN_MASK (0xF << 0) #define RSND_GEN1 (1 << 0) #define RSND_GEN2 (2 << 0) -- cgit v1.2.3 From 0719ecf7cb86cb7b6012baa0b329063d67dca670 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 26 Nov 2015 08:43:59 +0000 Subject: ASoC: rsnd: indicate register name for debug Current rsnd driver is indicating how to use regmap debug method on gen.c comment area. regmap debug method indicates address and value, but rsnd driver is using too many IPs (SSI/SSIU/SRC/CTU/MIX/DVC/CMD), and address. Thus, we would like to know more useful information for debugging. This patch indicates address name for debugging. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/gen.c | 52 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 84f8bb223439..15d770662482 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -31,29 +31,33 @@ struct rsnd_gen { /* RSND_REG_MAX base */ struct regmap_field *regs[RSND_REG_MAX]; + const char *reg_name[RSND_REG_MAX]; }; #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) +#define rsnd_reg_name(gen, id) ((gen)->reg_name[id]) struct rsnd_regmap_field_conf { int idx; unsigned int reg_offset; unsigned int id_offset; + const char *reg_name; }; -#define RSND_REG_SET(id, offset, _id_offset) \ +#define RSND_REG_SET(id, offset, _id_offset, n) \ { \ .idx = id, \ .reg_offset = offset, \ .id_offset = _id_offset, \ + .reg_name = n, \ } /* single address mapping */ #define RSND_GEN_S_REG(id, offset) \ - RSND_REG_SET(RSND_REG_##id, offset, 0) + RSND_REG_SET(RSND_REG_##id, offset, 0, #id) /* multi address mapping */ #define RSND_GEN_M_REG(id, offset, _id_offset) \ - RSND_REG_SET(RSND_REG_##id, offset, _id_offset) + RSND_REG_SET(RSND_REG_##id, offset, _id_offset, #id) /* * basic function @@ -83,8 +87,9 @@ u32 rsnd_read(struct rsnd_priv *priv, regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); - dev_dbg(dev, "r %s[%d] - %4d : %08x\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); + dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), + rsnd_reg_name(gen, reg), reg, val); return val; } @@ -99,10 +104,11 @@ void rsnd_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "w %s[%d] - %4d : %08x\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); - regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); + + dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), + rsnd_reg_name(gen, reg), reg, data); } void rsnd_force_write(struct rsnd_priv *priv, @@ -115,10 +121,11 @@ void rsnd_force_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "w %s[%d] - %4d : %08x\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); - regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data); + + dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), + rsnd_reg_name(gen, reg), reg, data); } void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, @@ -130,11 +137,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); - regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), mask, data); + + dev_dbg(dev, "b %s[%d] - %-18s (%4d) : %08x/%08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), + rsnd_reg_name(gen, reg), reg, data, mask); + } phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id) @@ -150,7 +159,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, int id_size, int reg_id, const char *name, - struct rsnd_regmap_field_conf *conf, + const struct rsnd_regmap_field_conf *conf, int conf_size) { struct platform_device *pdev = rsnd_priv_to_pdev(priv); @@ -203,6 +212,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, /* RSND_REG_MAX base */ gen->regs[conf[i].idx] = regs; + gen->reg_name[conf[i].idx] = conf[i].reg_name; } return 0; @@ -213,7 +223,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, */ static int rsnd_gen2_probe(struct rsnd_priv *priv) { - struct rsnd_regmap_field_conf conf_ssiu[] = { + const static struct rsnd_regmap_field_conf conf_ssiu[] = { RSND_GEN_S_REG(SSI_MODE0, 0x800), RSND_GEN_S_REG(SSI_MODE1, 0x804), /* FIXME: it needs SSI_MODE2/3 in the future */ @@ -223,7 +233,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), }; - struct rsnd_regmap_field_conf conf_scu[] = { + const static struct rsnd_regmap_field_conf conf_scu[] = { RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), @@ -267,7 +277,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), }; - struct rsnd_regmap_field_conf conf_adg[] = { + const static struct rsnd_regmap_field_conf conf_adg[] = { RSND_GEN_S_REG(BRRA, 0x00), RSND_GEN_S_REG(BRRB, 0x04), RSND_GEN_S_REG(SSICKR, 0x08), @@ -287,7 +297,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), }; - struct rsnd_regmap_field_conf conf_ssi[] = { + const static struct rsnd_regmap_field_conf conf_ssi[] = { RSND_GEN_M_REG(SSICR, 0x00, 0x40), RSND_GEN_M_REG(SSISR, 0x04, 0x40), RSND_GEN_M_REG(SSITDR, 0x08, 0x40), @@ -318,14 +328,14 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) static int rsnd_gen1_probe(struct rsnd_priv *priv) { - struct rsnd_regmap_field_conf conf_adg[] = { + const static struct rsnd_regmap_field_conf conf_adg[] = { RSND_GEN_S_REG(BRRA, 0x00), RSND_GEN_S_REG(BRRB, 0x04), RSND_GEN_S_REG(SSICKR, 0x08), RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), }; - struct rsnd_regmap_field_conf conf_ssi[] = { + const static struct rsnd_regmap_field_conf conf_ssi[] = { RSND_GEN_M_REG(SSICR, 0x00, 0x40), RSND_GEN_M_REG(SSISR, 0x04, 0x40), RSND_GEN_M_REG(SSITDR, 0x08, 0x40), -- cgit v1.2.3 From 8cc225f713a42eab098d51a4353998db979f0f8a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 26 Nov 2015 11:11:03 +0000 Subject: ASoC: rsnd: tidyup semantics of rsnd_src_record_error() rsnd_src_error_record() should recorde error, but it clears error too. this patch fixes up semantic of rsnd_src_error_record that it records error but doesn't clear error. And this patch renames rsnd_src_error_clear() to rsnd_src_status_clear() rsnd_src_error_record() to rsnd_src_record_error() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index c103aa775e96..6d93c4ed8275 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -300,7 +300,7 @@ static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable) rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); } -static void rsnd_src_error_clear(struct rsnd_mod *mod) +static void rsnd_src_status_clear(struct rsnd_mod *mod) { u32 val = OUF_SRC(rsnd_mod_id(mod)); @@ -308,7 +308,7 @@ static void rsnd_src_error_clear(struct rsnd_mod *mod) rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); } -static bool rsnd_src_error_record(struct rsnd_mod *mod) +static bool rsnd_src_record_error(struct rsnd_mod *mod) { struct rsnd_src *src = rsnd_mod_to_src(mod); u32 val0, val1; @@ -332,9 +332,6 @@ static bool rsnd_src_error_record(struct rsnd_mod *mod) ret = true; } - /* clear error static */ - rsnd_src_error_clear(mod); - return ret; } @@ -383,7 +380,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, rsnd_src_set_convert_rate(io, mod); - rsnd_src_error_clear(mod); + rsnd_src_status_clear(mod); rsnd_src_irq_enable(mod); @@ -434,7 +431,7 @@ static void __rsnd_src_interrupt(struct rsnd_mod *mod, if (!rsnd_io_is_working(io)) goto rsnd_src_interrupt_out; - if (rsnd_src_error_record(mod)) { + if (rsnd_src_record_error(mod)) { dev_dbg(dev, "%s[%d] restart\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); @@ -450,7 +447,9 @@ static void __rsnd_src_interrupt(struct rsnd_mod *mod, rsnd_mod_name(mod), rsnd_mod_id(mod)); } + rsnd_src_status_clear(mod); rsnd_src_interrupt_out: + spin_unlock(&priv->lock); } -- cgit v1.2.3 From 5342dff23263933060d0485cece864f36c0b5d32 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 26 Nov 2015 11:13:40 +0000 Subject: ASoC: rsnd: tidyup semantics of rsnd_ssi_record_error() rsnd_ssi_record_error() should recorde error, but it clears error too. this patch fixes up semantic of rsnd_ssi_record_error that it records error but doesn't clear error. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 0fe5e3068b6b..40d5b587cbe9 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -396,13 +396,9 @@ static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi) u32 status = rsnd_ssi_status_get(mod); /* under/over flow error */ - if (status & (UIRQ | OIRQ)) { + if (status & (UIRQ | OIRQ)) ssi->err++; - /* clear error status */ - rsnd_ssi_status_clear(mod); - } - return status; } @@ -537,6 +533,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, rsnd_mod_name(mod), rsnd_mod_id(mod)); } + rsnd_ssi_status_clear(mod); rsnd_ssi_interrupt_out: spin_unlock(&priv->lock); -- cgit v1.2.3 From 94458364304161551906d276f0164efd3dc30576 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:49:15 +0000 Subject: ASoC: rsnd: don't use normal *mod in adg.c adg.c is used from ssi/src/cmd. Thus don't use confusable *mod here. This patch rename it to ssi_mod/src_mod/cmd_mod Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 448f082ab56d..6d3ef366d536 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -68,8 +68,8 @@ static u32 rsnd_adg_calculate_rbgx(unsigned long div) static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) { - struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); - int id = rsnd_mod_id(mod); + struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io); + int id = rsnd_mod_id(ssi_mod); int ws = id; if (rsnd_ssi_is_pin_sharing(io)) { @@ -90,13 +90,13 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) return (0x6 + ws) << 8; } -int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, +int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod, struct rsnd_dai_stream *io) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_priv *priv = rsnd_mod_to_priv(cmd_mod); struct rsnd_adg *adg = rsnd_priv_to_adg(priv); struct rsnd_mod *adg_mod = rsnd_mod_get(adg); - int id = rsnd_mod_id(mod); + int id = rsnd_mod_id(cmd_mod); int shift = (id % 2) ? 16 : 0; u32 mask, val; @@ -275,20 +275,16 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val) } } -int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) +int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod) { - /* - * "mod" = "ssi" here. - * we can get "ssi id" from mod - */ - rsnd_adg_set_ssi_clk(mod, 0); + rsnd_adg_set_ssi_clk(ssi_mod, 0); return 0; } -int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) +int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); struct rsnd_adg *adg = rsnd_priv_to_adg(priv); struct device *dev = rsnd_priv_to_dev(priv); struct clk *clk; @@ -332,14 +328,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) found_clock: - /* - * This "mod" = "ssi" here. - * we can get "ssi id" from mod - */ - rsnd_adg_set_ssi_clk(mod, data); + rsnd_adg_set_ssi_clk(ssi_mod, data); dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), + rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod), data, rate); return 0; -- cgit v1.2.3 From c45f7263a805e1c5d8579569884d32141330589f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:49:33 +0000 Subject: ASoC: rsnd: add missing ADINR::CHNUM on DVC/SRC/SSIU DVC/SRC/SSIU needs ADINR::CHNUM settings too. This patch adds these missing value. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 6 +++++- sound/soc/sh/rcar/src.c | 3 ++- sound/soc/sh/rcar/ssiu.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 0f61e1344431..c622dec24362 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -97,11 +97,15 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 adinr = 0; u32 dvucr = 0; u32 vrctr = 0; u32 vrpdr = 0; u32 vrdbr = 0; + adinr = rsnd_get_adinr_bit(mod, io) | + rsnd_get_adinr_chan(mod, io); + /* Enable Digital Volume, Zero Cross Mute Mode */ dvucr |= 0x101; @@ -124,7 +128,7 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, rsnd_mod_write(mod, DVC_DVUIR, 1); /* General Information */ - rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); + rsnd_mod_write(mod, DVC_ADINR, adinr); rsnd_mod_write(mod, DVC_DVUCR, dvucr); /* Volume Ramp Parameter */ diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 6d93c4ed8275..30cad79deab0 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -199,7 +199,8 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, /* * SRC_ADINR */ - adinr = rsnd_get_adinr_bit(mod, io); + adinr = rsnd_get_adinr_bit(mod, io) | + rsnd_get_adinr_chan(mod, io); /* * SRC_IFSCR / SRC_IFSVR diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index bc245047e904..6120b0a66958 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -82,7 +82,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, u32 val = rsnd_get_dalign(mod, io); rsnd_mod_write(mod, SSI_BUSIF_ADINR, - rsnd_get_adinr_bit(mod, io)); + rsnd_get_adinr_bit(mod, io) | + rsnd_get_adinr_chan(mod, io)); rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); rsnd_mod_write(mod, SSI_BUSIF_DALIGN, val); } -- cgit v1.2.3 From bf4e8d7c371ae0d7acc1872a153c2f980f5523fe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:50:08 +0000 Subject: ASoC: rsnd: add missing SRC_O_BUSIF_MODE register SRC_BUSIF_MODE has both IN/OUT register. Current src driver sets IN register only. This patch sets missing OUT register. IN/OUT register are using default setting, so, there is no HW effect. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/gen.c | 4 +++- sound/soc/sh/rcar/rsnd.h | 3 ++- sound/soc/sh/rcar/src.c | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 15d770662482..364708c73418 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -233,8 +233,10 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), }; + const static struct rsnd_regmap_field_conf conf_scu[] = { - RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), + RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20), + RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20), RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 42d2ac5cb0d1..bb2c29cdc892 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -51,7 +51,8 @@ enum rsnd_reg { RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */ RSND_REG_SSI_BUSIF_DALIGN, /* Gen2 only */ RSND_REG_SSI_INT_ENABLE, /* Gen2 only */ - RSND_REG_SRC_BUSIF_MODE, + RSND_REG_SRC_I_BUSIF_MODE, + RSND_REG_SRC_O_BUSIF_MODE, RSND_REG_SRC_ROUTE_MODE0, RSND_REG_SRC_SWRSR, RSND_REG_SRC_SRCIR, diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 30cad79deab0..27b3ffe8c9a0 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -254,7 +254,8 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); - rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); + rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1); + rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1); rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); if (convert_rate) -- cgit v1.2.3 From 98efeeaeeb5f2a66603ba7c9cb9b4f7a02dd3c01 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:50:32 +0000 Subject: ASoC: rsnd: src: rename rsnd_src_soft_reset() to rsnd_src_activation() Based on datasheet naming Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 27b3ffe8c9a0..5239c3d7a3d0 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -70,7 +70,7 @@ struct rsnd_src { * |-----------------| */ -static void rsnd_src_soft_reset(struct rsnd_mod *mod) +static void rsnd_src_activation(struct rsnd_mod *mod) { rsnd_mod_write(mod, SRC_SWRSR, 0); rsnd_mod_write(mod, SRC_SWRSR, 1); @@ -378,7 +378,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, rsnd_mod_power_on(mod); - rsnd_src_soft_reset(mod); + rsnd_src_activation(mod); rsnd_src_set_convert_rate(io, mod); -- cgit v1.2.3 From 4fe32521d706e3541095ef173669e46666df2865 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:50:51 +0000 Subject: ASoC: rsnd: mix: rename rsnd_mix_soft_reset() to rsnd_mix_activation() Based on datasheet naming Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/mix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 57ac453adcef..b2f22bd7e3a9 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -24,7 +24,7 @@ struct rsnd_mix { ((pos) = (struct rsnd_mix *)(priv)->mix + i); \ i++) -static void rsnd_mix_soft_reset(struct rsnd_mod *mod) +static void rsnd_mix_activation(struct rsnd_mod *mod) { rsnd_mod_write(mod, MIX_SWRSR, 0); rsnd_mod_write(mod, MIX_SWRSR, 1); @@ -83,7 +83,7 @@ static int rsnd_mix_init(struct rsnd_mod *mod, { rsnd_mod_power_on(mod); - rsnd_mix_soft_reset(mod); + rsnd_mix_activation(mod); rsnd_mix_volume_init(io, mod); -- cgit v1.2.3 From 87a6c5a815f5da390ea74187344342df03205358 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:51:15 +0000 Subject: ASoC: rsnd: dvc: rename rsnd_dvc_soft_reset() to rsnd_dvc_activation() Based on datasheet naming Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index c622dec24362..b69a6e5cafef 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -64,7 +64,7 @@ static const char * const dvc_ramp_rate[] = { "0.125 dB/8192 steps", /* 10111 */ }; -static void rsnd_dvc_soft_reset(struct rsnd_mod *mod) +static void rsnd_dvc_activation(struct rsnd_mod *mod) { rsnd_mod_write(mod, DVC_SWRSR, 0); rsnd_mod_write(mod, DVC_SWRSR, 1); @@ -206,7 +206,7 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, { rsnd_mod_power_on(mod); - rsnd_dvc_soft_reset(mod); + rsnd_dvc_activation(mod); rsnd_dvc_volume_init(io, mod); -- cgit v1.2.3 From 475a361a6f2c7c690fd59a8f5224615e781cc3bd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:51:35 +0000 Subject: ASoC: rsnd: src: add rsnd_src_halt() Based on datasheet process Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 5239c3d7a3d0..b438538a0a69 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -76,6 +76,12 @@ static void rsnd_src_activation(struct rsnd_mod *mod) rsnd_mod_write(mod, SRC_SWRSR, 1); } +static void rsnd_src_halt(struct rsnd_mod *mod) +{ + rsnd_mod_write(mod, SRC_SRCIR, 1); + rsnd_mod_write(mod, SRC_SWRSR, 0); +} + static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { @@ -406,6 +412,8 @@ static int rsnd_src_quit(struct rsnd_mod *mod, /* stop both out/in */ rsnd_mod_write(mod, SRC_CTRL, 0); + rsnd_src_halt(mod); + rsnd_mod_power_off(mod); if (src->err) -- cgit v1.2.3 From 95e6b0ddb002e0dc89fef99b31685197da2eca9e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:51:52 +0000 Subject: ASoC: rsnd: mix: add rsnd_mix_halt() Based on datasheet process Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/mix.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index b2f22bd7e3a9..b34957ab75b9 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -30,6 +30,12 @@ static void rsnd_mix_activation(struct rsnd_mod *mod) rsnd_mod_write(mod, MIX_SWRSR, 1); } +static void rsnd_mix_halt(struct rsnd_mod *mod) +{ + rsnd_mod_write(mod, MIX_MIXIR, 1); + rsnd_mod_write(mod, MIX_SWRSR, 0); +} + static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io, struct rsnd_mod *mod) { @@ -96,6 +102,8 @@ static int rsnd_mix_quit(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { + rsnd_mix_halt(mod); + rsnd_mod_power_off(mod); return 0; -- cgit v1.2.3 From f13edb8b281cf7fa762b14323238d6884df38792 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:52:21 +0000 Subject: ASoC: rsnd: dvc: add rsnd_dvc_halt() Based on datasheet process Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index b69a6e5cafef..91c86ee1fecb 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -70,6 +70,12 @@ static void rsnd_dvc_activation(struct rsnd_mod *mod) rsnd_mod_write(mod, DVC_SWRSR, 1); } +static void rsnd_dvc_halt(struct rsnd_mod *mod) +{ + rsnd_mod_write(mod, DVC_DVUIR, 1); + rsnd_mod_write(mod, DVC_SWRSR, 0); +} + #define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val) #define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13)) @@ -219,6 +225,8 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { + rsnd_dvc_halt(mod); + rsnd_mod_power_off(mod); return 0; -- cgit v1.2.3 From 840ada3b04275d47a24f35a8c559bc584962f315 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:52:38 +0000 Subject: ASoC: rsnd: add rsnd_ssi_config_init() In order to enhance code readability, this patch adds rsnd_ssi_config_init() and moves SSICR register settings to it. This is prepare patch for TDM support Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 98 ++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 46 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 40d5b587cbe9..31e26bd481cf 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -253,6 +253,55 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi, rsnd_adg_ssi_clk_stop(mod); } +static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, + struct rsnd_dai_stream *io) +{ + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + u32 cr_own; + u32 cr_mode; + + /* + * always use 32bit system word. + * see also rsnd_ssi_master_clk_enable() + */ + cr_own = FORCE | SWL_32 | PDTA; + + if (rdai->bit_clk_inv) + cr_own |= SCKP; + if (rdai->frm_clk_inv) + cr_own |= SWSP; + if (rdai->data_alignment) + cr_own |= SDTA; + if (rdai->sys_delay) + cr_own |= DEL; + if (rsnd_io_is_play(io)) + cr_own |= TRMD; + + switch (runtime->sample_bits) { + case 16: + cr_own |= DWL_16; + break; + case 32: + cr_own |= DWL_24; + break; + default: + return -EINVAL; + } + + if (rsnd_ssi_is_dma_mode(rsnd_mod_get(ssi))) { + cr_mode = UIEN | OIEN | /* over/under run */ + DMEN; /* DMA : enable DMA */ + } else { + cr_mode = DIEN; /* PIO : enable Data interrupt */ + } + + ssi->cr_own = cr_own; + ssi->cr_mode = cr_mode; + + return 0; +} + /* * SSI mod common functions */ @@ -261,9 +310,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - u32 cr; int ret; ssi->usrcnt++; @@ -277,49 +323,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (rsnd_ssi_is_parent(mod, io)) return 0; - cr = FORCE | PDTA; - - /* - * always use 32bit system word for easy clock calculation. - * see also rsnd_ssi_master_clk_enable() - */ - cr |= SWL_32; - - /* - * init clock settings for SSICR - */ - switch (runtime->sample_bits) { - case 16: - cr |= DWL_16; - break; - case 32: - cr |= DWL_24; - break; - default: - return -EIO; - } - - if (rdai->bit_clk_inv) - cr |= SCKP; - if (rdai->frm_clk_inv) - cr |= SWSP; - if (rdai->data_alignment) - cr |= SDTA; - if (rdai->sys_delay) - cr |= DEL; - if (rsnd_io_is_play(io)) - cr |= TRMD; - - ssi->cr_own = cr; - - if (rsnd_ssi_is_dma_mode(mod)) { - cr = UIEN | OIEN | /* over/under run */ - DMEN; /* DMA : enable DMA */ - } else { - cr = DIEN; /* PIO : enable Data interrupt */ - } - - ssi->cr_mode = cr; + ret = rsnd_ssi_config_init(ssi, io); + if (ret < 0) + return ret; ssi->err = -1; /* ignore 1st error */ -- cgit v1.2.3 From 08bada26fe8089f908484a3a4580f38e78502ac7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:53:04 +0000 Subject: ASoC: rsnd: set SSIWSR setting on rsnd_ssi_config_init() It will have TDM settings on SSIWSR. Actually, we would like to set it on rsnd_ssi_config_init(), but we can't. Because SSI might be used as clock master (It doesn't need to call rsnd_ssi_config_init() when clock master mode). This patch adds new ssi->wsr and set it on rsnd_ssi_start(). Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 31e26bd481cf..d97f365f1b41 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -69,6 +69,7 @@ struct rsnd_ssi { u32 cr_own; u32 cr_clk; u32 cr_mode; + u32 wsr; int chan; int rate; int err; @@ -214,11 +215,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, if (0 == ret) { ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(j); + ssi->wsr = CONT; ssi->rate = rate; - rsnd_mod_write(mod, SSIWSR, CONT); - dev_dbg(dev, "%s[%d] outputs %u Hz\n", rsnd_mod_name(mod), rsnd_mod_id(mod), rate); @@ -421,6 +421,7 @@ static int __rsnd_ssi_start(struct rsnd_mod *mod, EN; rsnd_mod_write(mod, SSICR, cr); + rsnd_mod_write(mod, SSIWSR, ssi->wsr); return 0; } -- cgit v1.2.3 From 8ec85e7f7e9a2f9c36a92596db53c30b1ca45f17 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:53:27 +0000 Subject: ASoC: rsnd: ssi enables non-stereo sound Current SSI is assuming that the sound is always stereo. But, SSI needs to calculate its frequency when master mode. Then This frequency depends on each SSI's slots, and TDM mode (= TDM Extend Mode, TDM split Mode, TDM Multichannel Mode). This patch enables to use non-stereo sound. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 29 +++++++++++++++++++++++++++++ sound/soc/sh/rcar/rsnd.h | 6 ++++++ sound/soc/sh/rcar/ssi.c | 5 +++-- 3 files changed, 38 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 81a6bdb6848c..f990b4cb7192 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -191,6 +191,34 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io) return !!io->substream; } +int rsnd_get_slot_rdai(struct rsnd_dai *rdai) +{ + return rdai->slots; +} + +int rsnd_get_slot_runtime(struct rsnd_dai_stream *io) +{ + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + int chan = rsnd_get_slot_rdai(rdai); + + if (runtime->channels < chan) + chan = runtime->channels; + + return chan; +} + +int rsnd_get_slot_extend(struct rsnd_dai_stream *io) +{ + int chan = rsnd_get_slot_runtime(io); + + /* TDM Extend Mode needs 8ch */ + if (chan == 6) + chan = 8; + + return chan; +} + /* * ADINR function */ @@ -611,6 +639,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) rdai->playback.rdai = rdai; rdai->capture.rdai = rdai; + rdai->slots = 2; /* default */ #define mod_parse(name) \ node = rsnd_##name##_of_node(priv); \ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index bb2c29cdc892..38fd212ffe5a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -285,6 +285,10 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod, void (*callback)(struct rsnd_mod *mod, struct rsnd_dai_stream *io)); +int rsnd_get_slot_rdai(struct rsnd_dai *rdai); +int rsnd_get_slot_runtime(struct rsnd_dai_stream *io); +int rsnd_get_slot_extend(struct rsnd_dai_stream *io); + /* * R-Car sound DAI */ @@ -321,6 +325,8 @@ struct rsnd_dai { struct rsnd_dai_stream capture; struct rsnd_priv *priv; + int slots; + unsigned int clk_master:1; unsigned int bit_clk_inv:1; unsigned int frm_clk_inv:1; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index d97f365f1b41..44e914132b02 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -177,6 +177,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_mod *mod = rsnd_mod_get(ssi); struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); + int slots = rsnd_get_slot_extend(io); int j, ret; int ssi_clk_mul_table[] = { 1, 2, 4, 8, 16, 6, 12, @@ -206,10 +207,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, /* * this driver is assuming that - * system word is 64fs (= 2 x 32bit) + * system word is 32bit x slots * see rsnd_ssi_init() */ - main_rate = rate * 32 * 2 * ssi_clk_mul_table[j]; + main_rate = rate * 32 * slots * ssi_clk_mul_table[j]; ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); if (0 == ret) { -- cgit v1.2.3 From 42ab9a791bd1fb6ad5a47ad66727dcd66093b1ae Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:53:44 +0000 Subject: ASoC: rsnd: dvc enables non-stereo sound Current DVC is assuming that the sound is always stereo. This patch makes it more flexible Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 6 +++++- sound/soc/sh/rcar/dvc.c | 14 ++++++++++++-- sound/soc/sh/rcar/gen.c | 6 ++++++ sound/soc/sh/rcar/rsnd.h | 9 ++++++++- 4 files changed, 31 insertions(+), 4 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index f990b4cb7192..7d364d7505a1 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -871,10 +871,14 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod, void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod), struct rsnd_kctrl_cfg_m *_cfg, + int ch_size, u32 max) { + if (ch_size > RSND_DVC_CHANNELS) + return -EINVAL; + _cfg->cfg.max = max; - _cfg->cfg.size = RSND_DVC_CHANNELS; + _cfg->cfg.size = ch_size; _cfg->cfg.val = _cfg->val; return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); } diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 91c86ee1fecb..66aeea8e0069 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -97,6 +97,12 @@ static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io, /* Enable Digital Volume */ rsnd_mod_write(mod, DVC_VOL0R, val[0]); rsnd_mod_write(mod, DVC_VOL1R, val[1]); + rsnd_mod_write(mod, DVC_VOL2R, val[2]); + rsnd_mod_write(mod, DVC_VOL3R, val[3]); + rsnd_mod_write(mod, DVC_VOL4R, val[4]); + rsnd_mod_write(mod, DVC_VOL5R, val[5]); + rsnd_mod_write(mod, DVC_VOL6R, val[6]); + rsnd_mod_write(mod, DVC_VOL7R, val[7]); } static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, @@ -236,8 +242,10 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd) { + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); int is_play = rsnd_io_is_play(io); + int slots = rsnd_get_slot_rdai(rdai); int ret; /* Volume */ @@ -245,7 +253,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, is_play ? "DVC Out Playback Volume" : "DVC In Capture Volume", rsnd_dvc_volume_update, - &dvc->volume, 0x00800000 - 1); + &dvc->volume, slots, + 0x00800000 - 1); if (ret < 0) return ret; @@ -254,7 +263,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, is_play ? "DVC Out Mute Switch" : "DVC In Mute Switch", rsnd_dvc_volume_update, - &dvc->mute, 1); + &dvc->mute, slots, + 1); if (ret < 0) return ret; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 364708c73418..2151aa5e161b 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -277,6 +277,12 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), + RSND_GEN_M_REG(DVC_VOL2R, 0xe30, 0x100), + RSND_GEN_M_REG(DVC_VOL3R, 0xe34, 0x100), + RSND_GEN_M_REG(DVC_VOL4R, 0xe38, 0x100), + RSND_GEN_M_REG(DVC_VOL5R, 0xe3c, 0x100), + RSND_GEN_M_REG(DVC_VOL6R, 0xe40, 0x100), + RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), }; const static struct rsnd_regmap_field_conf conf_adg[] = { diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 38fd212ffe5a..2111bf32e789 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -101,6 +101,12 @@ enum rsnd_reg { RSND_REG_DVC_ZCMCR, RSND_REG_DVC_VOL0R, RSND_REG_DVC_VOL1R, + RSND_REG_DVC_VOL2R, + RSND_REG_DVC_VOL3R, + RSND_REG_DVC_VOL4R, + RSND_REG_DVC_VOL5R, + RSND_REG_DVC_VOL6R, + RSND_REG_DVC_VOL7R, RSND_REG_DVC_DVUER, RSND_REG_DVC_VRCTR, /* Gen2 only */ RSND_REG_DVC_VRPDR, /* Gen2 only */ @@ -476,7 +482,7 @@ struct rsnd_kctrl_cfg { struct snd_kcontrol *kctrl; }; -#define RSND_DVC_CHANNELS 2 +#define RSND_DVC_CHANNELS 8 struct rsnd_kctrl_cfg_m { struct rsnd_kctrl_cfg cfg; u32 val[RSND_DVC_CHANNELS]; @@ -497,6 +503,7 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod, void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod), struct rsnd_kctrl_cfg_m *_cfg, + int ch_size, u32 max); int rsnd_kctrl_new_s(struct rsnd_mod *mod, struct rsnd_dai_stream *io, -- cgit v1.2.3 From 186fadc132f0d634c7b43202a240fbd3654b6623 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 Nov 2015 08:54:03 +0000 Subject: ASoC: rsnd: add TDM Extend Mode support Renesas R-Car can out TDM by 1) 6ch x 1 DAI as TDM Extend Mode 2) 2ch x 4 x 1 DAI as TDM split Mode 3) 2ch x 3 DAI or 2ch x 4 DAI as TDM Multichannel Mode This patch adds 1) TDM Extend Mode. Because of HW design, this 6ch data will be outputed via 8ch data width. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 30 ++++++++++++++++++++++++++---- sound/soc/sh/rcar/gen.c | 1 + sound/soc/sh/rcar/rsnd.h | 1 + sound/soc/sh/rcar/ssi.c | 18 +++++++++++++++++- sound/soc/sh/rcar/ssiu.c | 9 +++++++++ 5 files changed, 54 insertions(+), 5 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7d364d7505a1..b187a8927e29 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -247,9 +247,9 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io) u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); - u32 chan = runtime->channels; + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + u32 chan = rsnd_get_slot_rdai(rdai); switch (chan) { case 1: @@ -569,9 +569,31 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } +static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, + u32 tx_mask, u32 rx_mask, + int slots, int slot_width) +{ + struct rsnd_priv *priv = rsnd_dai_to_priv(dai); + struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); + struct device *dev = rsnd_priv_to_dev(priv); + + switch (slots) { + case 6: + /* TDM Extend Mode */ + rdai->slots = slots; + break; + default: + dev_err(dev, "unsupported TDM slots (%d)\n", slots); + return -EINVAL; + } + + return 0; +} + static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .trigger = rsnd_soc_dai_trigger, .set_fmt = rsnd_soc_dai_set_fmt, + .set_tdm_slot = rsnd_soc_set_dai_tdm_slot, }; static int rsnd_dai_probe(struct rsnd_priv *priv) @@ -626,7 +648,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) drv->playback.rates = RSND_RATES; drv->playback.formats = RSND_FMTS; drv->playback.channels_min = 2; - drv->playback.channels_max = 2; + drv->playback.channels_max = 6; drv->playback.stream_name = rdai->playback.name; snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, @@ -634,7 +656,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) drv->capture.rates = RSND_RATES; drv->capture.formats = RSND_FMTS; drv->capture.channels_min = 2; - drv->capture.channels_max = 2; + drv->capture.channels_max = 6; drv->capture.stream_name = rdai->capture.name; rdai->playback.rdai = rdai; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 2151aa5e161b..50fc73042b7e 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -230,6 +230,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80), + RSND_GEN_M_REG(SSI_MODE, 0xc, 0x80), RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), }; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 2111bf32e789..970e1301f7c6 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -44,6 +44,7 @@ */ enum rsnd_reg { /* SCU (SRC/SSIU/MIX/CTU/DVC) */ + RSND_REG_SSI_MODE, /* Gen2 only */ RSND_REG_SSI_MODE0, RSND_REG_SSI_MODE1, RSND_REG_SSI_CTRL, /* Gen2 only */ diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 44e914132b02..628739f13f99 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -24,7 +24,9 @@ #define OIEN (1 << 26) /* Overflow Interrupt Enable */ #define IIEN (1 << 25) /* Idle Mode Interrupt Enable */ #define DIEN (1 << 24) /* Data Interrupt Enable */ - +#define CHNL_4 (1 << 22) /* Channels */ +#define CHNL_6 (2 << 22) /* Channels */ +#define CHNL_8 (3 << 22) /* Channels */ #define DWL_8 (0 << 19) /* Data Word Length */ #define DWL_16 (1 << 19) /* Data Word Length */ #define DWL_18 (2 << 19) /* Data Word Length */ @@ -57,6 +59,7 @@ * SSIWSR */ #define CONT (1 << 8) /* WS Continue Function */ +#define WS_MODE (1 << 0) /* WS Mode */ #define SSI_NAME "ssi" @@ -261,6 +264,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); u32 cr_own; u32 cr_mode; + u32 wsr; /* * always use 32bit system word. @@ -297,8 +301,20 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, cr_mode = DIEN; /* PIO : enable Data interrupt */ } + /* + * TDM Extend Mode + * see + * rsnd_ssiu_init_gen2() + */ + wsr = ssi->wsr; + if (rsnd_get_slot_runtime(io) >= 6) { + wsr |= WS_MODE; + cr_own |= CHNL_8; + } + ssi->cr_own = cr_own; ssi->cr_mode = cr_mode; + ssi->wsr = wsr; return 0; } diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 6120b0a66958..326550114299 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -78,6 +78,15 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, if (ret < 0) return ret; + if (rsnd_get_slot_runtime(io) >= 6) { + /* + * TDM Extend Mode + * see + * rsnd_ssi_config_init() + */ + rsnd_mod_write(mod, SSI_MODE, 0x1); + } + if (rsnd_ssi_use_busif(io)) { u32 val = rsnd_get_dalign(mod, io); -- cgit v1.2.3 From 2ff2ecca06d5302782c73626b841a509a9b01ef6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 1 Dec 2015 08:31:38 +0000 Subject: ASoC: rsnd: fixup wrong snd_soc_dai_driver pointer access drv pointer should be "base + offset" instead of "current + offset". This patch fixup this issue, otherwise third and subsequent pointer will be broken Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index b187a8927e29..f1d7af114a31 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -603,7 +603,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) struct device_node *playback, *capture; struct rsnd_dai_stream *io_playback; struct rsnd_dai_stream *io_capture; - struct snd_soc_dai_driver *drv; + struct snd_soc_dai_driver *rdrv, *drv; struct rsnd_dai *rdai; struct device *dev = rsnd_priv_to_dev(priv); int nr, dai_i, io_i, np_i; @@ -616,15 +616,15 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) goto rsnd_dai_probe_done; } - drv = devm_kzalloc(dev, sizeof(*drv) * nr, GFP_KERNEL); + rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL); rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL); - if (!drv || !rdai) { + if (!rdrv || !rdai) { ret = -ENOMEM; goto rsnd_dai_probe_done; } priv->rdai_nr = nr; - priv->daidrv = drv; + priv->daidrv = rdrv; priv->rdai = rdai; /* @@ -633,7 +633,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) dai_i = 0; for_each_child_of_node(dai_node, dai_np) { rdai = rsnd_rdai_get(priv, dai_i); - drv = drv + dai_i; + drv = rdrv + dai_i; io_playback = &rdai->playback; io_capture = &rdai->capture; -- cgit v1.2.3 From 575f1f929f5a2ed80130c294aa7b2dc40dba74f2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 1 Dec 2015 08:33:23 +0000 Subject: ASoC: rsnd: rsrc-card: check return value of snd_soc_of_get_dai_name() This patch adds missing check of snd_soc_of_get_dai_name(). It might not be able to use sound card, because it might returns -EPROBE_DEFER. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsrc-card.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index d61db9c385ea..a3ec13f6271e 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -208,7 +208,9 @@ static int rsrc_card_parse_links(struct device_node *np, dai_link->dynamic = 1; dai_link->dpcm_merged_format = 1; dai_link->cpu_of_node = args.np; - snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); + ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); + if (ret < 0) + return ret; /* set dai_name */ snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", @@ -240,7 +242,9 @@ static int rsrc_card_parse_links(struct device_node *np, dai_link->no_pcm = 1; dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; dai_link->codec_of_node = args.np; - snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); + ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); + if (ret < 0) + return ret; /* additional name prefix */ if (of_data) { -- cgit v1.2.3 From f98ed119a7c5feacb1fc1c8d7f6c68934cd27384 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 2 Dec 2015 07:34:28 +0000 Subject: ASoC: rsnd: care SWSP bit for TDM/non-TDM SSICR::SWSP bit controls WS signal low/high, but in case of TDM it is inverted. This patch solves this issue. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 628739f13f99..79c3211a1e7f 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -265,6 +265,9 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, u32 cr_own; u32 cr_mode; u32 wsr; + int is_tdm; + + is_tdm = (rsnd_get_slot_runtime(io) >= 6) ? 1 : 0; /* * always use 32bit system word. @@ -274,7 +277,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, if (rdai->bit_clk_inv) cr_own |= SCKP; - if (rdai->frm_clk_inv) + if (rdai->frm_clk_inv ^ is_tdm) cr_own |= SWSP; if (rdai->data_alignment) cr_own |= SDTA; @@ -307,7 +310,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, * rsnd_ssiu_init_gen2() */ wsr = ssi->wsr; - if (rsnd_get_slot_runtime(io) >= 6) { + if (is_tdm) { wsr |= WS_MODE; cr_own |= CHNL_8; } -- cgit v1.2.3 From a504b1ee417ffd1e3c272b4594213edf14af3ef1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Dec 2015 05:38:23 +0000 Subject: ASoC: rsnd: tidyup data align position for capture L/R channel data has been treated as inverted on R-Car sound 16bit mode, Thus, 4689032b1("ASoC: rsnd: tidyup data align position") tidyuped data align position. But it couldn't care about capture case. This patch cares both playback/capture Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/cmd.c | 1 + sound/soc/sh/rcar/core.c | 13 +++++++++++-- sound/soc/sh/rcar/gen.c | 1 + sound/soc/sh/rcar/rsnd.h | 2 ++ 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index ab904c3f20b5..cd1f064e63c4 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c @@ -80,6 +80,7 @@ static int rsnd_cmd_init(struct rsnd_mod *mod, dev_dbg(dev, "ctu/mix path = 0x%08x", data); rsnd_mod_write(mod, CMD_ROUTE_SLCT, data); + rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); rsnd_adg_set_cmd_timsel_gen2(mod, io); diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index f1d7af114a31..849c1ad93df2 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -272,13 +272,22 @@ u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) */ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { - struct rsnd_mod *src = rsnd_io_to_mod_src(io); struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); - struct rsnd_mod *target = src ? src : ssi; + struct rsnd_mod *target; struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); u32 val = 0x76543210; u32 mask = ~0; + if (rsnd_io_is_play(io)) { + struct rsnd_mod *src = rsnd_io_to_mod_src(io); + + target = src ? src : ssi; + } else { + struct rsnd_mod *cmd = rsnd_io_to_mod_cmd(io); + + target = cmd ? cmd : ssi; + } + mask <<= runtime->channels * 4; val = val & mask; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 50fc73042b7e..7c5485e46fd7 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -242,6 +242,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), + RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20), RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 970e1301f7c6..ad854d6719ea 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -81,6 +81,7 @@ enum rsnd_reg { RSND_REG_SCU_SYS_INT_EN0, RSND_REG_SCU_SYS_INT_EN1, /* Gen2 only */ RSND_REG_CMD_CTRL, /* Gen2 only */ + RSND_REG_CMD_BUSIF_DALIGN, /* Gen2 only */ RSND_REG_CMD_ROUTE_SLCT, RSND_REG_CMDOUT_TIMSEL, /* Gen2 only */ RSND_REG_CTU_CTUIR, @@ -319,6 +320,7 @@ struct rsnd_dai_stream { #define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) #define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) #define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC) +#define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD) #define rsnd_io_to_rdai(io) ((io)->rdai) #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) -- cgit v1.2.3 From 76ca9970322118610681af5f929aba62f346082b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 14 Dec 2015 12:04:54 +0000 Subject: rcar: ctu: Avoid use of ret uninitialised We use ret as the return value from the rsnd_ctu_probe() but if there are no child nodes and no errors then we will never initialize ret leading to build warnings. Ensure ret is initialized before we iterate over the child nodes to avoid this. Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ctu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 7c1e190cd389..d53a225d19e9 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -111,6 +111,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) priv->ctu = ctu; i = 0; + ret = 0; for_each_child_of_node(node, np) { ctu = rsnd_ctu_get(priv, i); -- cgit v1.2.3 From 2e4118dac3d6765186dd1faf1fd3cede37b74e73 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 14 Dec 2015 12:05:17 +0000 Subject: rcar: dvc: Avoid use of ret uninitialised We use ret as the return value from the rsnd_dvc_probe() but if there are no child nodes and no errors then we will never initialize ret leading to build warnings. Ensure ret is initialized before we iterate over the child nodes to avoid this. Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 66aeea8e0069..42e6a230a3d1 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -360,6 +360,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) priv->dvc = dvc; i = 0; + ret = 0; for_each_child_of_node(node, np) { dvc = rsnd_dvc_get(priv, i); -- cgit v1.2.3 From 2b235a3da5560d65df6865ea436389e55a0f41ad Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 14 Dec 2015 12:05:28 +0000 Subject: rcar: mux: Avoid use of ret uninitialised We use ret as the return value from the rsnd_mix_probe() but if there are no child nodes and no errors then we will never initialize ret leading to build warnings. Ensure ret is initialized before we iterate over the child nodes to avoid this. Signed-off-by: Mark Brown --- sound/soc/sh/rcar/mix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index b34957ab75b9..65542b6a89e9 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -158,6 +158,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv) priv->mix = mix; i = 0; + ret = 0; for_each_child_of_node(node, np) { mix = rsnd_mix_get(priv, i); -- cgit v1.2.3 From 6dad9758a5e3e75de91871a636572d64806b240f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:48:23 +0000 Subject: ASoC: rsrc-card: enable to use tdm_slot on DT Renesas sound driver will use tdm slot on TDM Multi Mode support. This patch enables tdm slot on rsrc card driver on DT. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsrc-card.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index a3ec13f6271e..3c308e2d696e 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -50,6 +50,10 @@ MODULE_DEVICE_TABLE(of, rsrc_card_of_match); struct rsrc_card_dai { unsigned int fmt; unsigned int sysclk; + unsigned int tx_slot_mask; + unsigned int rx_slot_mask; + int slots; + int slot_width; struct clk *clk; char dai_name[DAI_NAME_NUM]; }; @@ -126,6 +130,18 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) } } + if (dai_props->slots) { + ret = snd_soc_dai_set_tdm_slot(dai, + dai_props->tx_slot_mask, + dai_props->rx_slot_mask, + dai_props->slots, + dai_props->slot_width); + if (ret && ret != -ENOTSUPP) { + dev_err(dai->dev, "set_tdm_slot error\n"); + goto err; + } + } + ret = 0; err: @@ -198,6 +214,15 @@ static int rsrc_card_parse_links(struct device_node *np, if (ret) return ret; + /* Parse TDM slot */ + ret = snd_soc_of_parse_tdm_slot(np, + &dai_props->tx_slot_mask, + &dai_props->rx_slot_mask, + &dai_props->slots, + &dai_props->slot_width); + if (ret) + return ret; + if (is_fe) { /* BE is dummy */ dai_link->codec_of_node = NULL; -- cgit v1.2.3 From ae638b725ee00afe3253e30df617a5531ea30ea2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:48:58 +0000 Subject: ASoC: rsrc-card: Remove support for setting differing DAI formats 1efb53a220 ("ASoC: simple-card: Remove support for setting differing DAI formats") removed set_fmt support from simple-card. rsrc-card follows same style, because it is based on simple-card. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsrc-card.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index 3c308e2d696e..9f522ba881fa 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -48,7 +48,6 @@ MODULE_DEVICE_TABLE(of, rsrc_card_of_match); #define DAI_NAME_NUM 32 struct rsrc_card_dai { - unsigned int fmt; unsigned int sysclk; unsigned int tx_slot_mask; unsigned int rx_slot_mask; @@ -114,14 +113,6 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) rtd->cpu_dai : rtd->codec_dai; - if (dai_props->fmt) { - ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); - if (ret && ret != -ENOTSUPP) { - dev_err(dai->dev, "set_fmt error\n"); - goto err; - } - } - if (dai_props->sysclk) { ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); if (ret && ret != -ENOTSUPP) { @@ -168,7 +159,7 @@ static int rsrc_card_parse_daifmt(struct device_node *node, struct rsrc_card_priv *priv, int idx, bool is_fe) { - struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); + struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct device_node *bitclkmaster = NULL; struct device_node *framemaster = NULL; struct device_node *codec = is_fe ? NULL : np; @@ -188,7 +179,7 @@ static int rsrc_card_parse_daifmt(struct device_node *node, daifmt |= (codec == framemaster) ? SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; - dai_props->fmt = daifmt; + dai_link->dai_fmt = daifmt; of_node_put(bitclkmaster); of_node_put(framemaster); @@ -340,6 +331,7 @@ static int rsrc_card_dai_link_of(struct device_node *node, int idx) { struct device *dev = rsrc_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); bool is_fe = false; int ret; @@ -361,7 +353,7 @@ static int rsrc_card_dai_link_of(struct device_node *node, dev_dbg(dev, "\t%s / %04x / %d\n", dai_props->dai_name, - dai_props->fmt, + dai_link->dai_fmt, dai_props->sysclk); return ret; -- cgit v1.2.3 From af998f853124231ef3bff05621f157a19af05d20 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:49:43 +0000 Subject: ASoC: rsrc-card: tidyup dai format for DPCM rsrc-card is DPCM supported version of simple-card. Thus it has similar DT format. OTOH, snd_soc_dai_link requests cpu/codec, but one of them will be snd-soc-dummy in DPCM case, and DPCM requests frontend/backend dai_link. This means it might have multi backend/codec. And, SND_SOC_DAIFMT_xxx is based on "codec". Because of these difference, current rsrc card can't detect correct dai_fmt. This patch detect correct dai fmt from 1st "codec". Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsrc-card.c | 82 +++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 27 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index 9f522ba881fa..5fe0b51cdb44 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -155,14 +155,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, } static int rsrc_card_parse_daifmt(struct device_node *node, - struct device_node *np, + struct device_node *codec, struct rsrc_card_priv *priv, - int idx, bool is_fe) + struct snd_soc_dai_link *dai_link, + unsigned int *retfmt) { - struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct device_node *bitclkmaster = NULL; struct device_node *framemaster = NULL; - struct device_node *codec = is_fe ? NULL : np; unsigned int daifmt; daifmt = snd_soc_of_parse_daifmt(node, NULL, @@ -179,11 +178,11 @@ static int rsrc_card_parse_daifmt(struct device_node *node, daifmt |= (codec == framemaster) ? SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; - dai_link->dai_fmt = daifmt; - of_node_put(bitclkmaster); of_node_put(framemaster); + *retfmt = daifmt; + return 0; } @@ -325,24 +324,16 @@ static int rsrc_card_parse_clk(struct device_node *np, return 0; } -static int rsrc_card_dai_link_of(struct device_node *node, - struct device_node *np, - struct rsrc_card_priv *priv, - int idx) +static int rsrc_card_dai_sub_link_of(struct device_node *node, + struct device_node *np, + struct rsrc_card_priv *priv, + int idx, bool is_fe) { struct device *dev = rsrc_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); - bool is_fe = false; int ret; - if (0 == strcmp(np->name, "cpu")) - is_fe = true; - - ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe); - if (ret < 0) - return ret; - ret = rsrc_card_parse_links(np, priv, idx, is_fe); if (ret < 0) return ret; @@ -359,6 +350,48 @@ static int rsrc_card_dai_link_of(struct device_node *node, return ret; } +static int rsrc_card_dai_link_of(struct device_node *node, + struct rsrc_card_priv *priv) +{ + struct snd_soc_dai_link *dai_link; + struct device_node *np; + unsigned int daifmt = 0; + int ret, i; + bool is_fe; + + /* find 1st codec */ + i = 0; + for_each_child_of_node(node, np) { + dai_link = rsrc_priv_to_link(priv, i); + + if (strcmp(np->name, "codec") == 0) { + ret = rsrc_card_parse_daifmt(node, np, priv, + dai_link, &daifmt); + if (ret < 0) + return ret; + break; + } + i++; + } + + i = 0; + for_each_child_of_node(node, np) { + dai_link = rsrc_priv_to_link(priv, i); + dai_link->dai_fmt = daifmt; + + is_fe = false; + if (strcmp(np->name, "cpu") == 0) + is_fe = true; + + ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe); + if (ret < 0) + return ret; + i++; + } + + return 0; +} + static int rsrc_card_parse_of(struct device_node *node, struct rsrc_card_priv *priv, struct device *dev) @@ -366,9 +399,8 @@ static int rsrc_card_parse_of(struct device_node *node, const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); struct rsrc_card_dai *props; struct snd_soc_dai_link *links; - struct device_node *np; int ret; - int i, num; + int num; if (!node) return -EINVAL; @@ -409,13 +441,9 @@ static int rsrc_card_parse_of(struct device_node *node, priv->snd_card.name ? priv->snd_card.name : "", priv->convert_rate); - i = 0; - for_each_child_of_node(node, np) { - ret = rsrc_card_dai_link_of(node, np, priv, i); - if (ret < 0) - return ret; - i++; - } + ret = rsrc_card_dai_link_of(node, priv); + if (ret < 0) + return ret; if (!priv->snd_card.name) priv->snd_card.name = priv->snd_card.dai_link->name; -- cgit v1.2.3 From cdf310ce119989353bb6848ca8327814ae1012e2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:55:25 +0000 Subject: ASoC: rsnd: fixup SSIU control timing SSIU should be controlled after SSI. This patch fix up it Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/rsnd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index ad854d6719ea..4b677e074c7a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -181,9 +181,9 @@ enum rsnd_mod_type { RSND_MOD_CTU, RSND_MOD_CMD, RSND_MOD_SRC, - RSND_MOD_SSIU, RSND_MOD_SSIP, /* SSI parent */ RSND_MOD_SSI, + RSND_MOD_SSIU, RSND_MOD_MAX, }; -- cgit v1.2.3 From 5e7b9edd928d22ffd4936fc61c80532ed6df5077 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:55:51 +0000 Subject: ASoC: rsnd: tidyup return value of rsnd_get_adinr_bit() Renesas sound driver has rsnd_get_adinr_bit/chan() functions. It is assuming _bit() returns ADINR :: OTBL, and _chan() returns ADINR :: CHNUM. Current _bit() returns both OTBL and CHNUM. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 849c1ad93df2..44f32c1db05d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -227,21 +227,17 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io) struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); - u32 adinr = runtime->channels; switch (runtime->sample_bits) { case 16: - adinr |= (8 << 16); - break; + return 8 << 16; case 32: - adinr |= (0 << 16); - break; - default: - dev_warn(dev, "not supported sample bits\n"); - return 0; + return 0 << 16; } - return adinr; + dev_warn(dev, "not supported sample bits\n"); + + return 0; } u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) -- cgit v1.2.3 From c90269c1fbfcb3082d379237f0912ea231e90a24 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:56:11 +0000 Subject: ASoC: rsnd: tidyup debug print position on rsnd_dma_attach() It can't output corrent dma name *before* rsnd_mod_init(). It goes to *after* rsnd_mod_init() by this patch Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 33eb37331498..418e6fdd06a3 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -680,16 +680,16 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, dma_mod = rsnd_mod_get(dma); - dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", - rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod), - rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), - rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); - ret = rsnd_mod_init(priv, dma_mod, ops, NULL, type, dma_id); if (ret < 0) return ERR_PTR(ret); + dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", + rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod), + rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), + rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); + ret = attach(io, dma, id, mod_from, mod_to); if (ret < 0) return ERR_PTR(ret); -- cgit v1.2.3 From 52dc68524327ed7bedfc2856bca4fa634f11141a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:56:31 +0000 Subject: ASoC: rsnd: rsnd_dai_connect() returns error if it connect to existing mod Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 44f32c1db05d..e59dc8a461bb 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -354,6 +354,9 @@ int rsnd_dai_connect(struct rsnd_mod *mod, if (!mod) return -EIO; + if (io->mod[type]) + return -EINVAL; + priv = rsnd_mod_to_priv(mod); dev = rsnd_priv_to_dev(priv); -- cgit v1.2.3 From 49ee73b441f5734c3da254c60e134f343b89911a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:56:50 +0000 Subject: ASoC: rsnd: SSI/SSIU use rsnd_get_slot_extend() to check TDM Current SSI/SSIU are using rsnd_get_slot_runtime() to check TDM, but using rsnd_get_slot_extend() is more sane. This patch fix it up Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 2 +- sound/soc/sh/rcar/ssiu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 79c3211a1e7f..7481bc3e0dff 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -267,7 +267,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, u32 wsr; int is_tdm; - is_tdm = (rsnd_get_slot_runtime(io) >= 6) ? 1 : 0; + is_tdm = (rsnd_get_slot_extend(io) >= 6) ? 1 : 0; /* * always use 32bit system word. diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 326550114299..c7f89beff44f 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -78,7 +78,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, if (ret < 0) return ret; - if (rsnd_get_slot_runtime(io) >= 6) { + if (rsnd_get_slot_extend(io) >= 6) { /* * TDM Extend Mode * see -- cgit v1.2.3 From 5858a7d17e266945b9860768d0549aeb6a52d31f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:57:07 +0000 Subject: ASoC: rsnd: remove rsnd_get_slot_runtime() Current Renesas sound driver is using rsnd_get_slot_runtime(), but it is same as runtime->channels. This patch removes rsnd_get_slot_runtime() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 19 ++++--------------- sound/soc/sh/rcar/rsnd.h | 1 - 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index e59dc8a461bb..7f3a7edba096 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -196,21 +196,10 @@ int rsnd_get_slot_rdai(struct rsnd_dai *rdai) return rdai->slots; } -int rsnd_get_slot_runtime(struct rsnd_dai_stream *io) -{ - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - int chan = rsnd_get_slot_rdai(rdai); - - if (runtime->channels < chan) - chan = runtime->channels; - - return chan; -} - int rsnd_get_slot_extend(struct rsnd_dai_stream *io) { - int chan = rsnd_get_slot_runtime(io); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + int chan = runtime->channels; /* TDM Extend Mode needs 8ch */ if (chan == 6) @@ -243,9 +232,9 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io) u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - u32 chan = rsnd_get_slot_rdai(rdai); + u32 chan = runtime->channels; switch (chan) { case 1: diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 4b677e074c7a..e9909a4ce754 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -294,7 +294,6 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod, struct rsnd_dai_stream *io)); int rsnd_get_slot_rdai(struct rsnd_dai *rdai); -int rsnd_get_slot_runtime(struct rsnd_dai_stream *io); int rsnd_get_slot_extend(struct rsnd_dai_stream *io); /* -- cgit v1.2.3 From c140284b8085e0fa07c24f4285db9dc107ad2ed3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:57:27 +0000 Subject: ASoC: rsnd: tidyup rsnd_get_slot_xxx() naming rsnd_get_slot_rdai() returns total slots (it returns 6 if total 6 channels) , and rsnd_get_slot_extend() returns extended SSI width (it returns 8 if total 6 channels). This will be used on SSI multi channel support too (It will return 2 if total 6 channels with 3 SSI). But, it is using confusable naming. This patch changes rsnd_get_slot_rdai() -> rsnd_get_slot(), rsnd_get_slot_extend() -> rsnd_get_slot_width() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 6 ++++-- sound/soc/sh/rcar/dvc.c | 3 +-- sound/soc/sh/rcar/rsnd.h | 4 ++-- sound/soc/sh/rcar/ssi.c | 4 ++-- sound/soc/sh/rcar/ssiu.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7f3a7edba096..76af41633f9f 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -191,12 +191,14 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io) return !!io->substream; } -int rsnd_get_slot_rdai(struct rsnd_dai *rdai) +int rsnd_get_slot(struct rsnd_dai_stream *io) { + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + return rdai->slots; } -int rsnd_get_slot_extend(struct rsnd_dai_stream *io) +int rsnd_get_slot_width(struct rsnd_dai_stream *io) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); int chan = runtime->channels; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 42e6a230a3d1..d45ffe496397 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -242,10 +242,9 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd) { - struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); int is_play = rsnd_io_is_play(io); - int slots = rsnd_get_slot_rdai(rdai); + int slots = rsnd_get_slot(io); int ret; /* Volume */ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index e9909a4ce754..804f2f5622e0 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -293,8 +293,8 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod, void (*callback)(struct rsnd_mod *mod, struct rsnd_dai_stream *io)); -int rsnd_get_slot_rdai(struct rsnd_dai *rdai); -int rsnd_get_slot_extend(struct rsnd_dai_stream *io); +int rsnd_get_slot(struct rsnd_dai_stream *io); +int rsnd_get_slot_width(struct rsnd_dai_stream *io); /* * R-Car sound DAI diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 7481bc3e0dff..0b91692c5a66 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -180,7 +180,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_mod *mod = rsnd_mod_get(ssi); struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); - int slots = rsnd_get_slot_extend(io); + int slots = rsnd_get_slot_width(io); int j, ret; int ssi_clk_mul_table[] = { 1, 2, 4, 8, 16, 6, 12, @@ -267,7 +267,7 @@ static int rsnd_ssi_config_init(struct rsnd_ssi *ssi, u32 wsr; int is_tdm; - is_tdm = (rsnd_get_slot_extend(io) >= 6) ? 1 : 0; + is_tdm = (rsnd_get_slot_width(io) >= 6) ? 1 : 0; /* * always use 32bit system word. diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index c7f89beff44f..7ae05a7621ae 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -78,7 +78,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, if (ret < 0) return ret; - if (rsnd_get_slot_extend(io) >= 6) { + if (rsnd_get_slot_width(io) >= 6) { /* * TDM Extend Mode * see -- cgit v1.2.3 From 750fd445ac53f1623cfcbf710d2bfc7aa1b7086d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:57:47 +0000 Subject: ASoC: rsnd: add rsnd_set_slot() / rsnd_get_slot_num() TDM will use 6 or 8 slots on 1 SSI, and Multi channel will use 6 or 8 slots on few SSI (each SSI uses 2 slots). Thus, this adds new slot control functions which can be prepare for Multi channel support. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 20 +++++++++++++++++--- sound/soc/sh/rcar/rsnd.h | 4 ++++ 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 76af41633f9f..528041eff704 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -191,6 +191,13 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io) return !!io->substream; } +void rsnd_set_slot(struct rsnd_dai *rdai, + int slots, int num) +{ + rdai->slots = slots; + rdai->slots_num = num; +} + int rsnd_get_slot(struct rsnd_dai_stream *io) { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); @@ -198,10 +205,17 @@ int rsnd_get_slot(struct rsnd_dai_stream *io) return rdai->slots; } +int rsnd_get_slot_num(struct rsnd_dai_stream *io) +{ + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + + return rdai->slots_num; +} + int rsnd_get_slot_width(struct rsnd_dai_stream *io) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - int chan = runtime->channels; + int chan = runtime->channels / rsnd_get_slot_num(io); /* TDM Extend Mode needs 8ch */ if (chan == 6) @@ -579,7 +593,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, switch (slots) { case 6: /* TDM Extend Mode */ - rdai->slots = slots; + rsnd_set_slot(rdai, slots, 1); break; default: dev_err(dev, "unsupported TDM slots (%d)\n", slots); @@ -660,7 +674,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) rdai->playback.rdai = rdai; rdai->capture.rdai = rdai; - rdai->slots = 2; /* default */ + rsnd_set_slot(rdai, 2, 1); /* default */ #define mod_parse(name) \ node = rsnd_##name##_of_node(priv); \ diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 804f2f5622e0..c9aef234d002 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -293,8 +293,11 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod, void (*callback)(struct rsnd_mod *mod, struct rsnd_dai_stream *io)); +void rsnd_set_slot(struct rsnd_dai *rdai, + int slots, int slots_total); int rsnd_get_slot(struct rsnd_dai_stream *io); int rsnd_get_slot_width(struct rsnd_dai_stream *io); +int rsnd_get_slot_num(struct rsnd_dai_stream *io); /* * R-Car sound DAI @@ -334,6 +337,7 @@ struct rsnd_dai { struct rsnd_priv *priv; int slots; + int slots_num; unsigned int clk_master:1; unsigned int bit_clk_inv:1; -- cgit v1.2.3 From 89b66174eca6609020cc3d1ef32df7956fd16b34 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 02:58:14 +0000 Subject: ASoC: rsnd: add rsnd_parse_connect_common() and remove complex macro Current rsnd driver is using complex macro to parse DAI connection. This patch adds new rsnd_parse_connect_common() and replace current macro to it. This is prepare for multi channel support Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 57 +++++++++++++++++++++++++++++------------------- sound/soc/sh/rcar/rsnd.h | 25 +++++++++++++++++++++ 2 files changed, 59 insertions(+), 23 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 528041eff704..7781cef634d4 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -609,17 +609,44 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .set_tdm_slot = rsnd_soc_set_dai_tdm_slot, }; +void rsnd_parse_connect_common(struct rsnd_dai *rdai, + struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), + struct device_node *node, + struct device_node *playback, + struct device_node *capture) +{ + struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device_node *np; + struct rsnd_mod *mod; + int i; + + if (!node) + return; + + i = 0; + for_each_child_of_node(node, np) { + mod = mod_get(priv, i); + if (np == playback) + rsnd_dai_connect(mod, &rdai->playback, mod->type); + if (np == capture) + rsnd_dai_connect(mod, &rdai->capture, mod->type); + i++; + } + + of_node_put(node); +} + static int rsnd_dai_probe(struct rsnd_priv *priv) { struct device_node *dai_node; - struct device_node *dai_np, *np, *node; + struct device_node *dai_np; struct device_node *playback, *capture; struct rsnd_dai_stream *io_playback; struct rsnd_dai_stream *io_capture; struct snd_soc_dai_driver *rdrv, *drv; struct rsnd_dai *rdai; struct device *dev = rsnd_priv_to_dev(priv); - int nr, dai_i, io_i, np_i; + int nr, dai_i, io_i; int ret; dai_node = rsnd_dai_of_node(priv); @@ -676,22 +703,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) rdai->capture.rdai = rdai; rsnd_set_slot(rdai, 2, 1); /* default */ -#define mod_parse(name) \ -node = rsnd_##name##_of_node(priv); \ -if (node) { \ - struct rsnd_mod *mod; \ - np_i = 0; \ - for_each_child_of_node(node, np) { \ - mod = rsnd_##name##_mod_get(priv, np_i); \ - if (np == playback) \ - rsnd_dai_connect(mod, io_playback, mod->type); \ - if (np == capture) \ - rsnd_dai_connect(mod, io_capture, mod->type); \ - np_i++; \ - } \ - of_node_put(node); \ -} - for (io_i = 0;; io_i++) { playback = of_parse_phandle(dai_np, "playback", io_i); capture = of_parse_phandle(dai_np, "capture", io_i); @@ -699,11 +710,11 @@ if (node) { \ if (!playback && !capture) break; - mod_parse(ssi); - mod_parse(src); - mod_parse(ctu); - mod_parse(mix); - mod_parse(dvc); + rsnd_parse_connect_ssi(rdai, playback, capture); + rsnd_parse_connect_src(rdai, playback, capture); + rsnd_parse_connect_ctu(rdai, playback, capture); + rsnd_parse_connect_mix(rdai, playback, capture); + rsnd_parse_connect_dvc(rdai, playback, capture); of_node_put(playback); of_node_put(capture); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index c9aef234d002..f803e140e733 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -292,6 +292,11 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, void rsnd_mod_interrupt(struct rsnd_mod *mod, void (*callback)(struct rsnd_mod *mod, struct rsnd_dai_stream *io)); +void rsnd_parse_connect_common(struct rsnd_dai *rdai, + struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), + struct device_node *node, + struct device_node *playback, + struct device_node *capture); void rsnd_set_slot(struct rsnd_dai *rdai, int slots, int slots_total); @@ -544,6 +549,10 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); #define rsnd_ssi_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") +#define rsnd_parse_connect_ssi(rdai, playback, capture) \ + rsnd_parse_connect_common(rdai, rsnd_ssi_mod_get, \ + rsnd_ssi_of_node(rsnd_rdai_to_priv(rdai)), \ + playback, capture) /* * R-Car SSIU @@ -564,6 +573,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct snd_pcm_runtime *runtime); #define rsnd_src_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") +#define rsnd_parse_connect_src(rdai, playback, capture) \ + rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \ + rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \ + playback, capture) /* * R-Car CTU @@ -573,6 +586,10 @@ void rsnd_ctu_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); #define rsnd_ctu_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu") +#define rsnd_parse_connect_ctu(rdai, playback, capture) \ + rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \ + rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \ + playback, capture) /* * R-Car MIX @@ -582,6 +599,10 @@ void rsnd_mix_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); #define rsnd_mix_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix") +#define rsnd_parse_connect_mix(rdai, playback, capture) \ + rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \ + rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \ + playback, capture) /* * R-Car DVC @@ -591,6 +612,10 @@ void rsnd_dvc_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); #define rsnd_dvc_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") +#define rsnd_parse_connect_dvc(rdai, playback, capture) \ + rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \ + rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \ + playback, capture) /* * R-Car CMD -- cgit v1.2.3 From b4c83b171557815a0b31a36805900cc9f21c9ee4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 17 Dec 2015 03:00:10 +0000 Subject: ASoC: rsnd: add Multi channel support This patch adds Multi channel support on Renesas R-Car sound. This patch is tested on Salvator-X board, but it can't use Multi channel, because supported format is different between codec chip and R-Car. Thus, it was tested on board which doesn't mount codec chip, with oscilloscope. Signed-off-by: Kuninori Morimoto Acked-by: Rob Herring Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 6 ++- sound/soc/sh/rcar/gen.c | 3 ++ sound/soc/sh/rcar/rsnd.h | 15 ++++--- sound/soc/sh/rcar/ssi.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++- sound/soc/sh/rcar/ssiu.c | 55 +++++++++++++++++++---- 5 files changed, 176 insertions(+), 17 deletions(-) (limited to 'sound/soc/sh/rcar') diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7781cef634d4..ca05a0a95a4d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -215,7 +215,11 @@ int rsnd_get_slot_num(struct rsnd_dai_stream *io) int rsnd_get_slot_width(struct rsnd_dai_stream *io) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - int chan = runtime->channels / rsnd_get_slot_num(io); + int chan = runtime->channels; + + /* Multi channel Mode */ + if (rsnd_ssi_multi_slaves(io)) + chan /= rsnd_get_slot_num(io); /* TDM Extend Mode needs 8ch */ if (chan == 6) diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 7c5485e46fd7..c7aee9e59e86 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -226,6 +226,9 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) const static struct rsnd_regmap_field_conf conf_ssiu[] = { RSND_GEN_S_REG(SSI_MODE0, 0x800), RSND_GEN_S_REG(SSI_MODE1, 0x804), + RSND_GEN_S_REG(SSI_MODE2, 0x808), + RSND_GEN_S_REG(SSI_CONTROL, 0x810), + /* FIXME: it needs SSI_MODE2/3 in the future */ RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index f803e140e733..317dd793149a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -47,6 +47,8 @@ enum rsnd_reg { RSND_REG_SSI_MODE, /* Gen2 only */ RSND_REG_SSI_MODE0, RSND_REG_SSI_MODE1, + RSND_REG_SSI_MODE2, + RSND_REG_SSI_CONTROL, RSND_REG_SSI_CTRL, /* Gen2 only */ RSND_REG_SSI_BUSIF_MODE, /* Gen2 only */ RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */ @@ -181,7 +183,10 @@ enum rsnd_mod_type { RSND_MOD_CTU, RSND_MOD_CMD, RSND_MOD_SRC, - RSND_MOD_SSIP, /* SSI parent */ + RSND_MOD_SSIM3, /* SSI multi 3 */ + RSND_MOD_SSIM2, /* SSI multi 2 */ + RSND_MOD_SSIM1, /* SSI multi 1 */ + RSND_MOD_SSIP, /* SSI parent */ RSND_MOD_SSI, RSND_MOD_SSIU, RSND_MOD_MAX, @@ -542,6 +547,7 @@ void rsnd_ssi_remove(struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); +u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io); #define rsnd_ssi_is_pin_sharing(io) \ __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) @@ -549,10 +555,9 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); #define rsnd_ssi_of_node(priv) \ of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") -#define rsnd_parse_connect_ssi(rdai, playback, capture) \ - rsnd_parse_connect_common(rdai, rsnd_ssi_mod_get, \ - rsnd_ssi_of_node(rsnd_rdai_to_priv(rdai)), \ - playback, capture) +void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, + struct device_node *playback, + struct device_node *capture); /* * R-Car SSIU diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 0b91692c5a66..7db05fdfb656 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -96,6 +96,7 @@ struct rsnd_ssi { #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_ssi_mode_flags(p) ((p)->flags) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) +#define rsnd_ssi_is_multi_slave(ssi, io) ((mod) != rsnd_io_to_mod_ssi(io)) int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) { @@ -171,6 +172,41 @@ static int rsnd_ssi_irq_disable(struct rsnd_mod *ssi_mod) return 0; } +u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io) +{ + struct rsnd_mod *mod; + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + struct rsnd_priv *priv = rsnd_io_to_priv(io); + struct device *dev = rsnd_priv_to_dev(priv); + enum rsnd_mod_type types[] = { + RSND_MOD_SSIM1, + RSND_MOD_SSIM2, + RSND_MOD_SSIM3, + }; + int i, mask; + + switch (runtime->channels) { + case 2: /* Multi channel is not needed for Stereo */ + return 0; + case 6: + break; + default: + dev_err(dev, "unsupported channel\n"); + return 0; + } + + mask = 0; + for (i = 0; i < ARRAY_SIZE(types); i++) { + mod = rsnd_io_to_mod(io, types[i]); + if (!mod) + continue; + + mask |= 1 << rsnd_mod_id(mod); + } + + return mask; +} + static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, struct rsnd_dai_stream *io) { @@ -194,6 +230,9 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) return 0; + if (rsnd_ssi_is_multi_slave(mod, io)) + return 0; + if (ssi->usrcnt > 1) { if (ssi->rate != rate) { dev_err(dev, "SSI parent/child should use same rate\n"); @@ -437,8 +476,14 @@ static int __rsnd_ssi_start(struct rsnd_mod *mod, cr = ssi->cr_own | ssi->cr_clk | - ssi->cr_mode | - EN; + ssi->cr_mode; + + /* + * EN will be set via SSIU :: SSI_CONTROL + * if Multi channel mode + */ + if (!rsnd_ssi_multi_slaves(io)) + cr |= EN; rsnd_mod_write(mod, SSICR, cr); rsnd_mod_write(mod, SSIWSR, ssi->wsr); @@ -609,6 +654,13 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); int ret; + /* + * SSIP/SSIU/IRQ are not needed on + * SSI Multi slaves + */ + if (rsnd_ssi_is_multi_slave(mod, io)) + return 0; + rsnd_ssi_parent_attach(mod, io, priv); ret = rsnd_ssiu_attach(io, mod); @@ -641,6 +693,13 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, int dma_id = 0; /* not needed */ int ret; + /* + * SSIP/SSIU/IRQ/DMA are not needed on + * SSI Multi slaves + */ + if (rsnd_ssi_is_multi_slave(mod, io)) + return 0; + ret = rsnd_ssi_common_probe(mod, io, priv); if (ret) return ret; @@ -732,6 +791,57 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = { /* * ssi mod function */ +static void rsnd_ssi_connect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) +{ + struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + enum rsnd_mod_type types[] = { + RSND_MOD_SSI, + RSND_MOD_SSIM1, + RSND_MOD_SSIM2, + RSND_MOD_SSIM3, + }; + enum rsnd_mod_type type; + int i; + + /* try SSI -> SSIM1 -> SSIM2 -> SSIM3 */ + for (i = 0; i < ARRAY_SIZE(types); i++) { + type = types[i]; + if (!rsnd_io_to_mod(io, type)) { + rsnd_dai_connect(mod, io, type); + rsnd_set_slot(rdai, 2 * (i + 1), (i + 1)); + return; + } + } +} + +void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, + struct device_node *playback, + struct device_node *capture) +{ + struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device_node *node; + struct device_node *np; + struct rsnd_mod *mod; + int i; + + node = rsnd_ssi_of_node(priv); + if (!node) + return; + + i = 0; + for_each_child_of_node(node, np) { + mod = rsnd_ssi_mod_get(priv, i); + if (np == playback) + rsnd_ssi_connect(mod, &rdai->playback); + if (np == capture) + rsnd_ssi_connect(mod, &rdai->capture); + i++; + } + + of_node_put(node); +} + struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) { if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 7ae05a7621ae..3fe9e08e81a3 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -27,8 +27,11 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); + u32 multi_ssi_slaves = rsnd_ssi_multi_slaves(io); int use_busif = rsnd_ssi_use_busif(io); int id = rsnd_mod_id(mod); + u32 mask1, val1; + u32 mask2, val2; /* * SSI_MODE0 @@ -38,6 +41,9 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, /* * SSI_MODE1 */ + mask1 = (1 << 4) | (1 << 20); /* mask sync bit */ + mask2 = (1 << 4); /* mask sync bit */ + val1 = val2 = 0; if (rsnd_ssi_is_pin_sharing(io)) { int shift = -1; @@ -51,15 +57,36 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, case 4: shift = 16; break; + default: + return -EINVAL; } - if (shift >= 0) - rsnd_mod_bset(mod, SSI_MODE1, - 0x3 << shift, - rsnd_rdai_is_clk_master(rdai) ? - 0x2 << shift : 0x1 << shift); + mask1 |= 0x3 << shift; + val1 = rsnd_rdai_is_clk_master(rdai) ? + 0x2 << shift : 0x1 << shift; + + } else if (multi_ssi_slaves) { + + mask2 |= 0x00000007; + mask1 |= 0x0000000f; + + switch (multi_ssi_slaves) { + case 0x0206: /* SSI0/1/2/9 */ + val2 = (1 << 4) | /* SSI0129 sync */ + rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1; + /* fall through */ + case 0x0006: /* SSI0/1/2 */ + val1 = rsnd_rdai_is_clk_master(rdai) ? + 0xa : 0x5; + + if (!val2) /* SSI012 sync */ + val1 |= (1 << 4); + } } + rsnd_mod_bset(mod, SSI_MODE1, mask1, val1); + rsnd_mod_bset(mod, SSI_MODE2, mask2, val2); + return 0; } @@ -104,8 +131,13 @@ static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - if (rsnd_ssi_use_busif(io)) - rsnd_mod_write(mod, SSI_CTRL, 0x1); + if (!rsnd_ssi_use_busif(io)) + return 0; + + rsnd_mod_write(mod, SSI_CTRL, 0x1); + + if (rsnd_ssi_multi_slaves(io)) + rsnd_mod_write(mod, SSI_CONTROL, 0x1); return 0; } @@ -114,8 +146,13 @@ static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - if (rsnd_ssi_use_busif(io)) - rsnd_mod_write(mod, SSI_CTRL, 0); + if (!rsnd_ssi_use_busif(io)) + return 0; + + rsnd_mod_write(mod, SSI_CTRL, 0); + + if (rsnd_ssi_multi_slaves(io)) + rsnd_mod_write(mod, SSI_CONTROL, 0); return 0; } -- cgit v1.2.3