From patchwork Thu Aug 28 06:52:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 4799691 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7BDBB9F375 for ; Thu, 28 Aug 2014 08:38:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3C9C820145 for ; Thu, 28 Aug 2014 08:38:47 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 036B120158 for ; Thu, 28 Aug 2014 08:38:46 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id AE6F115FB; Thu, 28 Aug 2014 07:35:31 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id A884D15F2 for ; Thu, 28 Aug 2014 07:34:51 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id EB7DC20265 for ; Thu, 28 Aug 2014 07:34:49 +0000 (UTC) Received: from ayumi.isobedori.kobe.vergenet.net (p4222-ipbfp1605kobeminato.hyogo.ocn.ne.jp [114.154.95.222]) by kirsty.vergenet.net (Postfix) with ESMTP id C7164267170; Thu, 28 Aug 2014 17:07:34 +1000 (EST) Received: by ayumi.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id 448B5EDE5DA; Thu, 28 Aug 2014 16:07:32 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Thu, 28 Aug 2014 15:52:52 +0900 Message-Id: <1409209620-24487-47-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1409209620-24487-1-git-send-email-horms+renesas@verge.net.au> References: <1409209620-24487-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org Cc: Magnus Damm Subject: [LTSI-dev] [PATCH LTSI-3.14 046/894] ASoC: rsnd: remove SSI dependent DMAEngine callback X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto Renesas Gen2 sound will use 2 DMAC which are Audio-DMAC, and Audio-DMAC-peri-peri. Current driver has callback function for each DMAC, because it assumed each DMAC needs special settings. But it became clear that these can share settings. This patch removes unnecessary callback Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown (cherry picked from commit 4686a0ad9aaee89495f181e5755d153e7fe7ffe6) Signed-off-by: Simon Horman --- sound/soc/sh/rcar/core.c | 38 +++++++++++++++++++++++++++----------- sound/soc/sh/rcar/rsnd.h | 10 +++++----- sound/soc/sh/rcar/ssi.c | 47 ++++++++--------------------------------------- 3 files changed, 40 insertions(+), 55 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 11eb0e3..b5af6f5 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma) void rsnd_dma_start(struct rsnd_dma *dma) { /* push both A and B plane*/ + dma->offset = 0; dma->submit_loop = 2; __rsnd_dma_start(dma); } @@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma) static void rsnd_dma_complete(void *data) { struct rsnd_dma *dma = (struct rsnd_dma *)data; + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma)); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); unsigned long flags; rsnd_lock(priv, flags); - dma->complete(dma); + /* + * Renesas sound Gen1 needs 1 DMAC, + * Gen2 needs 2 DMAC. + * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri. + * But, Audio-DMAC-peri-peri doesn't have interrupt, + * and this driver is assuming that here. + * + * If Audio-DMAC-peri-peri has interrpt, + * rsnd_dai_pointer_update() will be called twice, + * ant it will breaks io->byte_pos + */ + + rsnd_dai_pointer_update(io, io->byte_per_period); if (dma->submit_loop) rsnd_dma_continue(dma); @@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data) static void __rsnd_dma_start(struct rsnd_dma *dma) { - struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma)); + struct rsnd_mod *mod = rsnd_dma_to_mod(dma); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; dma_addr_t buf; - size_t len; + size_t len = io->byte_per_period; int i; for (i = 0; i < dma->submit_loop; i++) { - if (dma->inquiry(dma, &buf, &len) < 0) - return; + buf = runtime->dma_addr + + rsnd_dai_pointer_offset(io, dma->offset + len); + dma->offset = len; desc = dmaengine_prep_slave_single( dma->chan, buf, len, dma->dir, @@ -217,10 +236,7 @@ int rsnd_dma_available(struct rsnd_dma *dma) } int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, - int is_play, int id, - int (*inquiry)(struct rsnd_dma *dma, - dma_addr_t *buf, int *len), - int (*complete)(struct rsnd_dma *dma)) + int is_play, int id) { struct device *dev = rsnd_priv_to_dev(priv); struct dma_slave_config cfg; @@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, goto rsnd_dma_init_err; dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - dma->inquiry = inquiry; - dma->complete = complete; INIT_WORK(&dma->work, rsnd_dma_do_work); return 0; @@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, } list_add_tail(&mod->list, &io->head); + mod->io = io; return 0; } @@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, int rsnd_dai_disconnect(struct rsnd_mod *mod) { list_del_init(&mod->list); + mod->io = NULL; return 0; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index c397dc8..b2c717d 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -100,19 +100,16 @@ struct rsnd_dma { struct work_struct work; struct dma_chan *chan; enum dma_data_direction dir; - int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len); - int (*complete)(struct rsnd_dma *dma); int submit_loop; + int offset; /* it cares A/B plane */ }; void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma); int rsnd_dma_available(struct rsnd_dma *dma); int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, - int is_play, int id, - int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len), - int (*complete)(struct rsnd_dma *dma)); + int is_play, int id); void rsnd_dma_quit(struct rsnd_priv *priv, struct rsnd_dma *dma); @@ -137,17 +134,20 @@ struct rsnd_mod_ops { struct rsnd_dai_stream *io); }; +struct rsnd_dai_stream; struct rsnd_mod { int id; struct rsnd_priv *priv; struct rsnd_mod_ops *ops; struct list_head list; /* connect to rsnd_dai playback/capture */ struct rsnd_dma dma; + struct rsnd_dai_stream *io; }; #define rsnd_mod_to_priv(mod) ((mod)->priv) #define rsnd_mod_to_dma(mod) (&(mod)->dma) #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) +#define rsnd_mod_to_io(mod) ((mod)->io) #define rsnd_mod_id(mod) ((mod)->id) #define for_each_rsnd_mod(pos, n, io) \ list_for_each_entry_safe(pos, n, &(io)->head, list) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index b7f464e..d3371d7 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -64,12 +64,10 @@ struct rsnd_ssi { struct rsnd_mod mod; struct rsnd_dai *rdai; - struct rsnd_dai_stream *io; u32 cr_own; u32 cr_clk; u32 cr_etc; int err; - int dma_offset; unsigned int usrcnt; unsigned int rate; }; @@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, * set ssi parameter */ ssi->rdai = rdai; - ssi->io = io; ssi->cr_own = cr; ssi->err = -1; /* ignore 1st error */ @@ -305,7 +302,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); ssi->rdai = NULL; - ssi->io = NULL; ssi->cr_own = 0; ssi->err = 0; @@ -329,8 +325,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) { struct rsnd_ssi *ssi = data; - struct rsnd_dai_stream *io = ssi->io; - u32 status = rsnd_mod_read(&ssi->mod, SSISR); + struct rsnd_mod *mod = &ssi->mod; + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + u32 status = rsnd_mod_read(mod, SSISR); irqreturn_t ret = IRQ_NONE; if (io && (status & DIRQ)) { @@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) * see rsnd_ssi_init() */ if (rsnd_dai_is_play(rdai, io)) - rsnd_mod_write(&ssi->mod, SSITDR, *buf); + rsnd_mod_write(mod, SSITDR, *buf); else - *buf = rsnd_mod_read(&ssi->mod, SSIRDR); + *buf = rsnd_mod_read(mod, SSIRDR); rsnd_dai_pointer_update(io, sizeof(*buf)); @@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .stop = rsnd_ssi_pio_stop, }; -static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len) -{ - struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma); - struct rsnd_dai_stream *io = ssi->io; - struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - - *len = io->byte_per_period; - *buf = runtime->dma_addr + - rsnd_dai_pointer_offset(io, ssi->dma_offset + *len); - ssi->dma_offset = *len; /* it cares A/B plane */ - - return 0; -} - -static int rsnd_ssi_dma_complete(struct rsnd_dma *dma) -{ - struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma); - struct rsnd_dai_stream *io = ssi->io; - u32 status = rsnd_mod_read(&ssi->mod, SSISR); - - rsnd_ssi_record_error(ssi, status); - - rsnd_dai_pointer_update(ssi->io, io->byte_per_period); - - return 0; -} - static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, /* enable DMA transfer */ ssi->cr_etc = DMEN; - ssi->dma_offset = 0; rsnd_dma_start(dma); @@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, ssi->cr_etc = 0; + rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); + rsnd_ssi_hw_stop(ssi, rdai); rsnd_dma_stop(dma); @@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, ret = rsnd_dma_init( priv, rsnd_mod_to_dma(&ssi->mod), rsnd_ssi_is_play(&ssi->mod), - pinfo->dma_id, - rsnd_ssi_dma_inquiry, - rsnd_ssi_dma_complete); + pinfo->dma_id); if (ret < 0) dev_info(dev, "SSI DMA failed. try PIO transter\n"); else