Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp3027355pxb; Sun, 26 Sep 2021 03:15:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwc5mIr3qUZ0mZnt36v77kIOh0TfA1Wle0/icB0vdnscs/KmW4Ow8ZO1vEGH6dALPa0bEAY X-Received: by 2002:a05:6e02:1c41:: with SMTP id d1mr15060338ilg.31.1632651313776; Sun, 26 Sep 2021 03:15:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632651313; cv=none; d=google.com; s=arc-20160816; b=X4QQiWCZU1RUOvo49p2c+kyp+upcv6sI1Ls53qMp/DN+JF7bqbxITbPy+/8lYbfy/W smYnphojdX3RrzeVSe3wbMOnNz+FLyvcsHHg3vlGjRfTyIHfHLrRcYs+Ao9mWq+AIUs3 qOlLPw2PYLwR+L5lLy3S0P5oBLY5JbaMEKUUVhYDhpJvJ4sCjO5tkpaUsbHHMQyZyGxL U0v8fu9wpGUkXpLRgVaTmHNcJpW8rsC38/SeeYAYosSnGJT2UDdW2u8q3b02X45GEfL3 QK2WavjvZDo/t+xMc4QcsHL+geO0h1PvAqFcO5k79hv2sSIUlE++X2WYRLGTTP9nOPPa ujjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from; bh=wkqtVE/nYjg9Y1sZFCH62ZKjEeEEk1/6LspFPSab2q4=; b=StDaW8xhkKg4k4WirHK2vm5xdD4NPsYEZIL5/+OqzCj0tIYHpDGiKGRQbLJUoH5xCP 5c8PUJEpOG15iM4rhjXKmrHlGOIUyeJ6okXnCH7oxzW3gdAZp7CTxME65aZSZiSjsktt PDJdX7G7Fxaa1hjfugtHFuwDXjUJpiKNzBiFIq7K7hrgF1H65lMPfLZJWqt/hZP1aMbY rvD9HnPSr+R9paO1jvxh0DyYkoFlORvZynmT7Vykya+XTICym0ETp95H6gLa6k/gw+DP DVJRTfJZD2t0LFiD8dHC7F4Rc3MengWhJhMvAqVAE73CrIaYA5vNTCIK29IQp+ksHMH/ uhPQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c3si13531339ilq.163.2021.09.26.03.14.45; Sun, 26 Sep 2021 03:15:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229962AbhIZKPI (ORCPT + 99 others); Sun, 26 Sep 2021 06:15:08 -0400 Received: from inva021.nxp.com ([92.121.34.21]:60648 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229802AbhIZKPI (ORCPT ); Sun, 26 Sep 2021 06:15:08 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id E1D58200FF0; Sun, 26 Sep 2021 12:13:30 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 7E670200FCD; Sun, 26 Sep 2021 12:13:30 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 1B877183AD07; Sun, 26 Sep 2021 18:13:29 +0800 (+08) From: Shengjiu Wang To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH] ASoC: fsl_spdif: implement bypass mode from in to out Date: Sun, 26 Sep 2021 17:49:20 +0800 Message-Id: <1632649760-1651-1-git-send-email-shengjiu.wang@nxp.com> X-Mailer: git-send-email 2.7.4 X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Viorel Suman Implement SPDIF bypass mode. It implies internal SoC routing of SPDIF input signal to SPDIF output signal. The test bed requires two boards: B1 configured in bypass mode, and B2 to feed B1 SPDIF RX port and read B1 SPDIF TX port: B2 TX -> B1 RX, B2 RX <- B1 TX. The test procedure: a) Boot both boards b) B2: start "arecord -r 48kHz | aplay " c) B2: start "aplay -r 48kHz <2ch 48kHz audio file>" d) B1: enable bypass mode: amixer -cimxspdif cset numid=8,iface=PCM,name='Bypass Mode' on e) B2: check DAC audio, make sure the same sample rate is used at steps b) and c), in example above the rate is 48kHz. f) B1: try to run "aplay" or "arecord" on imxspdif card while in bypass mode - both must fail until bypass mode is disabled g) B1: disable bypass mode: amixer -cimxspdif cset numid=8,iface=PCM,name='Bypass Mode' off h) B1: check the usual playback and capture on imxspdif card. During this test try to set bypass mode - must not be allowed while playback or capture is running. Signed-off-by: Viorel Suman Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_spdif.c | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 928b59069283..d178b479c8bd 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -111,6 +111,7 @@ struct spdif_mixer_control { * @dma_params_tx: DMA parameters for transmit channel * @dma_params_rx: DMA parameters for receive channel * @regcache_srpc: regcache for SRPC + * @bypass: status of bypass input to output */ struct fsl_spdif_priv { const struct fsl_spdif_soc_data *soc; @@ -133,6 +134,7 @@ struct fsl_spdif_priv { struct snd_dmaengine_dai_dma_data dma_params_rx; /* regcache for SRPC */ u32 regcache_srpc; + bool bypass; }; static struct fsl_spdif_soc_data fsl_spdif_vf610 = { @@ -905,6 +907,69 @@ static int fsl_spdif_rx_rcm_put(struct snd_kcontrol *kcontrol, return 0; } +static int fsl_spdif_bypass_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); + struct fsl_spdif_priv *priv = snd_soc_dai_get_drvdata(dai); + + ucontrol->value.integer.value[0] = priv->bypass ? 1 : 0; + + return 0; +} + +static int fsl_spdif_bypass_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); + struct fsl_spdif_priv *priv = snd_soc_dai_get_drvdata(dai); + struct snd_soc_card *card = dai->component->card; + bool set = (ucontrol->value.integer.value[0] != 0); + struct regmap *regmap = priv->regmap; + struct snd_soc_pcm_runtime *rtd; + u32 scr, mask; + int stream; + + rtd = snd_soc_get_pcm_runtime(card, card->dai_link); + + if (priv->bypass == set) + return 0; /* nothing to do */ + + if (snd_soc_dai_active(dai)) { + dev_err(dai->dev, "Cannot change BYPASS mode while stream is running.\n"); + return -EBUSY; + } + + pm_runtime_get_sync(dai->dev); + + if (set) { + /* Disable interrupts */ + regmap_update_bits(regmap, REG_SPDIF_SIE, 0xffffff, 0); + + /* Configure BYPASS mode */ + scr = SCR_TXSEL_RX | SCR_RXFIFO_OFF; + mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK | + SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK | SCR_TXSEL_MASK; + /* Power up SPDIF module */ + mask |= SCR_LOW_POWER; + } else { + /* Power down SPDIF module, disable TX */ + scr = SCR_LOW_POWER | SCR_TXSEL_OFF; + mask = SCR_LOW_POWER | SCR_TXSEL_MASK; + } + + regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr); + + /* Disable playback & capture if BYPASS mode is enabled, enable otherwise */ + for_each_pcm_streams(stream) + rtd->pcm->streams[stream].substream_count = (set ? 0 : 1); + + priv->bypass = set; + pm_runtime_put_sync(dai->dev); + + return 0; +} + /* DPLL lock information */ static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1075,6 +1140,15 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = { .info = fsl_spdif_rxrate_info, .get = fsl_spdif_rxrate_get, }, + /* RX bypass controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Bypass Mode", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_ctl_boolean_mono_info, + .get = fsl_spdif_bypass_get, + .put = fsl_spdif_bypass_put, + }, /* User bit sync mode set/get controller */ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, -- 2.17.1