From patchwork Thu Aug 28 06:52:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 4801551 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 3D1069F375 for ; Thu, 28 Aug 2014 09:01:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1F08220123 for ; Thu, 28 Aug 2014 09:01:38 +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 6B6E620117 for ; Thu, 28 Aug 2014 09:01:36 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B493517CA; Thu, 28 Aug 2014 07:38:32 +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 76FE915A2 for ; Thu, 28 Aug 2014 07:37:45 +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 21FED201B4 for ; Thu, 28 Aug 2014 07:37:44 +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 3079C26716C; Thu, 28 Aug 2014 17:07:34 +1000 (EST) Received: by ayumi.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id B45D1EDE5F6; 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:51 +0900 Message-Id: <1409209620-24487-46-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 045/894] ASoC: rsnd: extracts Gen1/Gen2 common parts 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 sound IP Gen1/Gen2 are similar, but different. This patch extracts Gen1/Gen2 common and dependency parts, and create Gen1/Gen2 ops to control it. According to this structure, SSIU setup which has been implemented on ssi.c can be moved to scu.c (SRU/SSIU/SCU should be implemented on scu.c) Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown (cherry picked from commit 1b7b08efbe7419cc3e082f2b5ec8ae89f7af43d1) Signed-off-by: Simon Horman --- sound/soc/sh/rcar/rsnd.h | 2 +- sound/soc/sh/rcar/scu.c | 336 ++++++++++++++++++++++++++++------------------- sound/soc/sh/rcar/ssi.c | 5 - 3 files changed, 205 insertions(+), 138 deletions(-) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index b1874eb..c397dc8 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -48,7 +48,7 @@ enum rsnd_reg { RSND_REG_SRC_IFSCR, RSND_REG_SRC_IFSVR, RSND_REG_SRC_SRCCR, - RSND_REG_SRC_MNFSR, + RSND_REG_SRC_MNFSR, /* for Gen1 */ /* ADG */ RSND_REG_BRRA, diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c index e2ffcc4..29d8990 100644 --- a/sound/soc/sh/rcar/scu.c +++ b/sound/soc/sh/rcar/scu.c @@ -110,6 +110,9 @@ struct rsnd_scu { * */ +/* + * Gen1/Gen2 common functions + */ static int rsnd_scu_ssi_mode_init(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -151,11 +154,145 @@ static int rsnd_scu_ssi_mode_init(struct rsnd_mod *mod, return 0; } -/* Gen1 only */ -static int rsnd_src_set_route_if_gen1( - struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv, + struct rsnd_mod *ssi_mod, + struct snd_pcm_runtime *runtime) +{ + struct rsnd_scu *scu; + unsigned int rate; + + /* this function is assuming SSI id = SCU id here */ + scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod))); + + /* + * return convert rate if SRC is used, + * otherwise, return runtime->rate as usual + */ + rate = rsnd_scu_convert_rate(scu); + if (!rate) + rate = runtime->rate; + + return rate; +} + +static int rsnd_scu_set_convert_rate(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + u32 convert_rate = rsnd_scu_convert_rate(scu); + u32 adinr = runtime->channels; + u32 fsrate = 0; + + if (convert_rate) + fsrate = 0x0400000 / convert_rate * runtime->rate; + + /* set/clear soft reset */ + rsnd_mod_write(mod, SRC_SWRSR, 0); + rsnd_mod_write(mod, SRC_SWRSR, 1); + + /* + * Initialize the operation of the SRC internal circuits + * see rsnd_scu_start() + */ + rsnd_mod_write(mod, SRC_SRCIR, 1); + + /* Set channel number and output bit length */ + switch (runtime->sample_bits) { + case 16: + adinr |= OTBL_16; + break; + case 32: + adinr |= OTBL_24; + break; + default: + return -EIO; + } + rsnd_mod_write(mod, SRC_ADINR, adinr); + + /* 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_scu_init(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + int ret; + + clk_enable(scu->clk); + + ret = rsnd_scu_ssi_mode_init(mod, rdai, io); + if (ret < 0) + return ret; + + return 0; +} + +static int rsnd_scu_quit(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + + clk_disable(scu->clk); + + return 0; +} + +static int rsnd_scu_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + + /* + * Cancel the initialization and operate the SRC function + * see rsnd_scu_set_convert_rate() + */ + rsnd_mod_write(mod, SRC_SRCIR, 0); + + if (rsnd_scu_convert_rate(scu)) + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); + + return 0; +} + + +static int rsnd_scu_stop(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + + if (rsnd_scu_convert_rate(scu)) + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0); + + return 0; +} + +static struct rsnd_mod_ops rsnd_scu_non_ops = { + .name = "scu (non)", +}; + +/* + * Gen1 functions + */ +static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { struct scu_route_config { u32 mask; @@ -171,17 +308,10 @@ static int rsnd_src_set_route_if_gen1( { 0x3, 28, }, /* 7 */ { 0x3, 30, }, /* 8 */ }; - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); u32 mask; u32 val; int id; - /* - * Gen1 only - */ - if (!rsnd_is_gen1(priv)) - return 0; - id = rsnd_mod_id(mod); if (id < 0 || id >= ARRAY_SIZE(routes)) return -EIO; @@ -257,104 +387,43 @@ static int rsnd_scu_set_convert_timing_gen1(struct rsnd_mod *mod, return 0; } -unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv, - struct rsnd_mod *ssi_mod, - struct snd_pcm_runtime *runtime) -{ - struct rsnd_scu *scu; - unsigned int rate; - - /* this function is assuming SSI id = SCU id here */ - scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod))); - - /* - * return convert rate if SRC is used, - * otherwise, return runtime->rate as usual - */ - rate = rsnd_scu_convert_rate(scu); - if (!rate) - rate = runtime->rate; - - return rate; -} - -static int rsnd_scu_set_convert_rate(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +static int rsnd_scu_set_convert_rate_gen1(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + 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 rsnd_scu *scu = rsnd_mod_to_scu(mod); - u32 convert_rate = rsnd_scu_convert_rate(scu); - u32 adinr = runtime->channels; - - /* set/clear soft reset */ - rsnd_mod_write(mod, SRC_SWRSR, 0); - rsnd_mod_write(mod, SRC_SWRSR, 1); - - /* Initialize the operation of the SRC internal circuits */ - rsnd_mod_write(mod, SRC_SRCIR, 1); - - /* Set channel number and output bit length */ - switch (runtime->sample_bits) { - case 16: - adinr |= OTBL_16; - break; - case 32: - adinr |= OTBL_24; - break; - default: - return -EIO; - } - rsnd_mod_write(mod, SRC_ADINR, adinr); - - if (convert_rate) { - u32 fsrate = 0x0400000 / convert_rate * runtime->rate; - - /* Enable the initial value of IFS */ - rsnd_mod_write(mod, SRC_IFSCR, 1); - - /* Set initial value of IFS */ - rsnd_mod_write(mod, SRC_IFSVR, fsrate); - - /* Select SRC mode (fixed value) */ - rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); + int ret; - /* Set the restriction value of the FS ratio (98%) */ - rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98); + ret = rsnd_scu_set_convert_rate(mod, rdai, io); + if (ret < 0) + return ret; - if (rsnd_is_gen1(priv)) { - /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ - } - } + /* Select SRC mode (fixed value) */ + rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); - /* Cancel the initialization and operate the SRC function */ - rsnd_mod_write(mod, SRC_SRCIR, 0); + /* Set the restriction value of the FS ratio (98%) */ + rsnd_mod_write(mod, SRC_MNFSR, + rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); - /* use DMA transfer */ - rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); + /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ return 0; } -static int rsnd_scu_init(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +static int rsnd_scu_init_gen1(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { - struct rsnd_scu *scu = rsnd_mod_to_scu(mod); int ret; - clk_enable(scu->clk); - - ret = rsnd_scu_ssi_mode_init(mod, rdai, io); + ret = rsnd_scu_init(mod, rdai, io); if (ret < 0) return ret; - ret = rsnd_src_set_route_if_gen1(mod, rdai, io); + ret = rsnd_src_set_route_gen1(mod, rdai, io); if (ret < 0) return ret; - ret = rsnd_scu_set_convert_rate(mod, rdai, io); + ret = rsnd_scu_set_convert_rate_gen1(mod, rdai, io); if (ret < 0) return ret; @@ -365,62 +434,58 @@ static int rsnd_scu_init(struct rsnd_mod *mod, return 0; } -static int rsnd_scu_quit(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +static int rsnd_scu_start_gen1(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { - struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + int id = rsnd_mod_id(mod); - clk_disable(scu->clk); + rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); - return 0; + return rsnd_scu_start(mod, rdai, io); } -static int rsnd_scu_start(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +static int rsnd_scu_stop_gen1(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_scu *scu = rsnd_mod_to_scu(mod); int id = rsnd_mod_id(mod); - if (rsnd_is_gen1(priv)) - rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); - - if (rsnd_scu_convert_rate(scu)) - rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); + rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); - return 0; + return rsnd_scu_stop(mod, rdai, io); } -static int rsnd_scu_stop(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) -{ - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - struct rsnd_scu *scu = rsnd_mod_to_scu(mod); - int id = rsnd_mod_id(mod); +static struct rsnd_mod_ops rsnd_scu_gen1_ops = { + .name = "sru (gen1)", + .init = rsnd_scu_init_gen1, + .quit = rsnd_scu_quit, + .start = rsnd_scu_start_gen1, + .stop = rsnd_scu_stop_gen1, +}; - if (rsnd_is_gen1(priv)) - rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); +static struct rsnd_mod_ops rsnd_scu_non_gen1_ops = { + .name = "non-sru (gen1)", + .init = rsnd_scu_ssi_mode_init, +}; - if (rsnd_scu_convert_rate(scu)) - rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0); +/* + * Gen2 functions + */ +static int rsnd_scu_start_non_gen2(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + /* enable PIO interrupt */ + rsnd_mod_write(mod, INT_ENABLE, 0x0f000000); return 0; } -static struct rsnd_mod_ops rsnd_scu_ops = { - .name = "scu", - .init = rsnd_scu_init, - .quit = rsnd_scu_quit, - .start = rsnd_scu_start, - .stop = rsnd_scu_stop, -}; - -static struct rsnd_mod_ops rsnd_scu_non_ops = { - .name = "scu (non)", +static struct rsnd_mod_ops rsnd_scu_non_gen2_ops = { + .name = "non-scu (gen2)", .init = rsnd_scu_ssi_mode_init, + .start = rsnd_scu_start_non_gen2, }; struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) @@ -466,8 +531,15 @@ int rsnd_scu_probe(struct platform_device *pdev, scu->clk = clk; ops = &rsnd_scu_non_ops; - if (rsnd_scu_hpbif_is_enable(scu)) - ops = &rsnd_scu_ops; + if (rsnd_scu_hpbif_is_enable(scu)) { + if (rsnd_is_gen1(priv)) + ops = &rsnd_scu_gen1_ops; + } else { + if (rsnd_is_gen1(priv)) + ops = &rsnd_scu_non_gen1_ops; + if (rsnd_is_gen2(priv)) + ops = &rsnd_scu_non_gen2_ops; + } rsnd_mod_init(priv, &scu->mod, ops, i); diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index bae309c..b7f464e 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -363,16 +363,11 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; - /* enable PIO interrupt if gen2 */ - if (rsnd_is_gen2(priv)) - rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000); - rsnd_ssi_hw_start(ssi, rdai, io); return 0;