Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp2478801yba; Mon, 15 Apr 2019 12:30:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqxWDTp3U3dCnluuE+VIiVr6BF1HkXOWnmQFjEH+9yIqGkk5rzEUwGzW5cwatkbxEv5Ym1gR X-Received: by 2002:a17:902:8a4:: with SMTP id 33mr78344063pll.7.1555356603311; Mon, 15 Apr 2019 12:30:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555356603; cv=none; d=google.com; s=arc-20160816; b=Skumhc1MklXwIUzjvlqM0t5UFU6XeaQM6FA/u24KsAxiP4mzin+/GQZ0y90Q6Cwxsq YDrChTwts/vssvafxsBHgP9Am24du+HLUs2GVmgxBr4qJFlzJlFaZTUDhqS0Km3blkWl 58Na5iz3djq6F4V6yzG9u6tDn9yqLZA8R+S5VBN5gt7sabStc24qgKIwWAXuB5D5Bfx/ MObniG9ZhwcRtv3NOGmvni24Up0ctwSqgzEoYW0b0B2O1n4zFUbhw3QaOTDWmIYxyvXk 0r30ytcNC5wJ1el+0lb5vnjDqksVTqNTM6SzBEZJ+D6S5Q1uRErZpvT7J1fFBhlPiWcz UylA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=KjpB/0yGFMJrzwVYenjKa/Q2TQ0hTs24vBOFWPy3q5g=; b=r7xpKuIe1/oD7ucZsfyq0QvVGEXshKKHDRVFU/qjGViRD6Dt+j7ryIED2kL3v084R/ piKFnW0m7qEVL+v971wfNW14lDfHl+yVGYfWozyloZUVuwaA3tPxFdE3hkmyUGwoEKZQ mM1rdx7Isu8GSRn7UteXoJ0G6z6+g/Up7fYfutu8LkGL+tVXGQT6f6b7Bxen1mjsnOtt 5nPS5Taa6sTljpYy+cbr+NNcQm+ANNibbQRODkcBH1r90yBnzGKWGQjZ5/d9sE3MlMpf HWfJ+UivNacnnp4WL0nnwOmBRUxNuKbgwyF7FmfSSLK725UiM+LfGzSGLb7GAi/pVoIL z+/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=hBvfC6lk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m2si45481492pll.44.2019.04.15.12.29.47; Mon, 15 Apr 2019 12:30:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=hBvfC6lk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729789AbfDOT1U (ORCPT + 99 others); Mon, 15 Apr 2019 15:27:20 -0400 Received: from mail.kernel.org ([198.145.29.99]:36368 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728596AbfDOTD6 (ORCPT ); Mon, 15 Apr 2019 15:03:58 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 124CD2087C; Mon, 15 Apr 2019 19:03:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555355037; bh=abd4mRKFVgbERGl3rqUOvXidqBQLDPQNuFiS9iNKN+s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hBvfC6lk7g4WPcAppn4cBxGlYyO0KEKexZUbavoBXWXIQIxb/Y+/Csu5eojqCqyOs DVJG30TxUF22GJOCDEZ5QD3nO4E4iQeVATjosIorowXDTLOODDmK2riWQnKCCVNPq9 jQm21SHPgTmHI1o09CZw1UPsls2e39RoNmB9/Nps= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Fabio Estevam , Nicolin Chen , Shengjiu Wang , Mark Brown Subject: [PATCH 4.14 45/69] ASoC: fsl_esai: fix channel swap issue when stream starts Date: Mon, 15 Apr 2019 20:59:03 +0200 Message-Id: <20190415183733.394496768@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190415183726.036654568@linuxfoundation.org> References: <20190415183726.036654568@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: S.j. Wang commit 0ff4e8c61b794a4bf6c854ab071a1abaaa80f358 upstream. There is very low possibility ( < 0.1% ) that channel swap happened in beginning when multi output/input pin is enabled. The issue is that hardware can't send data to correct pin in the beginning with the normal enable flow. This is hardware issue, but there is no errata, the workaround flow is that: Each time playback/recording, firstly clear the xSMA/xSMB, then enable TE/RE, then enable xSMB and xSMA (xSMB must be enabled before xSMA). Which is to use the xSMA as the trigger start register, previously the xCR_TE or xCR_RE is the bit for starting. Fixes commit 43d24e76b698 ("ASoC: fsl_esai: Add ESAI CPU DAI driver") Cc: Reviewed-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Shengjiu Wang Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/fsl/fsl_esai.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -58,6 +58,8 @@ struct fsl_esai { u32 fifo_depth; u32 slot_width; u32 slots; + u32 tx_mask; + u32 rx_mask; u32 hck_rate[2]; u32 sck_rate[2]; bool hck_dir[2]; @@ -358,21 +360,13 @@ static int fsl_esai_set_dai_tdm_slot(str regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, - ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); - regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, - ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); - esai_priv->slot_width = slot_width; esai_priv->slots = slots; + esai_priv->tx_mask = tx_mask; + esai_priv->rx_mask = rx_mask; return 0; } @@ -593,6 +587,7 @@ static int fsl_esai_trigger(struct snd_p bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u8 i, channels = substream->runtime->channels; u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); + u32 mask; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -605,15 +600,38 @@ static int fsl_esai_trigger(struct snd_p for (i = 0; tx && i < channels; i++) regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); + /* + * When set the TE/RE in the end of enablement flow, there + * will be channel swap issue for multi data line case. + * In order to workaround this issue, we switch the bit + * enablement sequence to below sequence + * 1) clear the xSMB & xSMA: which is done in probe and + * stop state. + * 2) set TE/RE + * 3) set xSMB + * 4) set xSMA: xSMA is the last one in this flow, which + * will trigger esai to start. + */ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); + mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), + ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); + break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), + ESAI_xSMA_xS_MASK, 0); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), + ESAI_xSMB_xS_MASK, 0); /* Disable and reset FIFO */ regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), @@ -903,6 +921,15 @@ static int fsl_esai_probe(struct platfor return ret; } + esai_priv->tx_mask = 0xFFFFFFFF; + esai_priv->rx_mask = 0xFFFFFFFF; + + /* Clear the TSMA, TSMB, RSMA, RSMB */ + regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0); + regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0); + regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); + regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, &fsl_esai_dai, 1); if (ret) {