From patchwork Wed Feb 26 16:02:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Pargmann X-Patchwork-Id: 3725511 Return-Path: X-Original-To: patchwork-linux-arm@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 799B69F35F for ; Wed, 26 Feb 2014 16:09:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 98FAA20158 for ; Wed, 26 Feb 2014 16:09:12 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (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 5FA77201BA for ; Wed, 26 Feb 2014 16:09:08 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WIh0j-0005Cv-NT; Wed, 26 Feb 2014 16:07:06 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WIh0E-0004tO-Hy; Wed, 26 Feb 2014 16:06:34 +0000 Received: from metis.ext.pengutronix.de ([2001:6f8:1178:4:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WIgz0-0004fW-4n for linux-arm-kernel@lists.infradead.org; Wed, 26 Feb 2014 16:05:26 +0000 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1WIgyU-0005SJ-5D; Wed, 26 Feb 2014 17:04:46 +0100 Received: from mpa by dude.hi.pengutronix.de with local (Exim 4.82) (envelope-from ) id 1WIgyG-0004a6-2g; Wed, 26 Feb 2014 17:04:32 +0100 From: Markus Pargmann To: Mark Brown Subject: [PATCH 11/15] ASoC: fsl-ssi: Fix register values when disabling Date: Wed, 26 Feb 2014 17:02:14 +0100 Message-Id: <1393430538-32333-12-git-send-email-mpa@pengutronix.de> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1393430538-32333-1-git-send-email-mpa@pengutronix.de> References: <1393430538-32333-1-git-send-email-mpa@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: mpa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140226_110518_652140_3042CE16 X-CRM114-Status: GOOD ( 16.90 ) X-Spam-Score: -1.9 (-) Cc: Fabio Estevam , alsa-devel@alsa-project.org, Timur Tabi , kernel@pengutronix.de, Nicolin Chen , Markus Pargmann , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 X-Virus-Scanned: ClamAV using ClamSMTP The bits we have to clear when disabling are different when the other stream is still active. This patch fixes the calculation of new register values after disabling one stream. It also adds a more detailed description of the new register value calculation. Signed-off-by: Markus Pargmann --- sound/soc/fsl/fsl_ssi.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index f5e43bb..9a1980d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -324,6 +324,26 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, } /* + * Calculate the bits that have to be disabled for the current stream that is + * getting disabled. This keeps the bits enabled that are necessary for the + * second stream to work if 'stream_active' is true. + * + * Detailed calculation: + * These are the values that need to be active after disabling. For non-active + * second stream, this is 0: + * vals_stream * !!stream_active + * + * The following computes the overall differences between the setup for the + * to-disable stream and the active stream, a simple XOR: + * vals_disable ^ (vals_stream * !!(stream_active)) + * + * The full expression adds a mask on all values we care about + */ +#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \ + ((vals_disable) & \ + ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active)))) + +/* * Enable/Disable a ssi configuration. You have to pass either * ssi_private->rxtx_reg_val.rx or tx as vals parameter. */ @@ -334,10 +354,15 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, struct fsl_ssi_reg_val *avals; u32 scr_val; int nr_active_streams; + int keep_active; regmap_read(regs, CCSR_SSI_SCR, &scr_val); nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + !!(scr_val & CCSR_SSI_SCR_RE); + if (nr_active_streams - 1 > 0) + keep_active = 1; + else + keep_active = 0; /* Find the other direction values rx or tx which we do not want to * modify */ @@ -348,7 +373,8 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, /* If vals should be disabled, start with disabling the unit */ if (!enable) { - u32 scr = vals->scr & (vals->scr ^ avals->scr); + u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, + keep_active); regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0); } @@ -359,7 +385,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, */ if (fsl_ssi_offline_config(ssi_private)) { if ((enable && !nr_active_streams) || - (!enable && nr_active_streams == 1)) + (!enable && !keep_active)) fsl_ssi_rxtx_config(ssi_private, enable); goto config_done; @@ -388,9 +414,12 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, */ /* These assignments are simply vals without bits set in avals*/ - sier = vals->sier & (vals->sier ^ avals->sier); - srcr = vals->srcr & (vals->srcr ^ avals->srcr); - stcr = vals->stcr & (vals->stcr ^ avals->stcr); + sier = fsl_ssi_disable_val(vals->sier, avals->sier, + keep_active); + srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr, + keep_active); + stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, + keep_active); regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0); regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0);