From patchwork Mon Aug 29 09:15:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aisheng Dong X-Patchwork-Id: 1106802 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7T918ir007214 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 29 Aug 2011 09:01:29 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QxxiB-0005t2-Mx; Mon, 29 Aug 2011 09:00:55 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QxxiB-0006cD-8c; Mon, 29 Aug 2011 09:00:55 +0000 Received: from db3ehsobe006.messaging.microsoft.com ([213.199.154.144] helo=DB3EHSOBE006.bigfish.com) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qxxi7-0006bu-D2 for linux-arm-kernel@lists.infradead.org; Mon, 29 Aug 2011 09:00:53 +0000 Received: from mail10-db3-R.bigfish.com (10.3.81.253) by DB3EHSOBE006.bigfish.com (10.3.84.26) with Microsoft SMTP Server id 14.1.225.22; Mon, 29 Aug 2011 09:00:48 +0000 Received: from mail10-db3 (localhost.localdomain [127.0.0.1]) by mail10-db3-R.bigfish.com (Postfix) with ESMTP id 4941BB7049A; Mon, 29 Aug 2011 09:00:48 +0000 (UTC) X-SpamScore: -7 X-BigFish: VS-7(zz1447Rzz1202h1082kzz8275bhz2dh2a8h668h839h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPVD:NLI; H:mail.freescale.net; RD:none; EFVD:NLI Received: from mail10-db3 (localhost.localdomain [127.0.0.1]) by mail10-db3 (MessageSwitch) id 131460844866537_7776; Mon, 29 Aug 2011 09:00:48 +0000 (UTC) Received: from DB3EHSMHS017.bigfish.com (unknown [10.3.81.245]) by mail10-db3.bigfish.com (Postfix) with ESMTP id 0A7EF125804B; Mon, 29 Aug 2011 09:00:48 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by DB3EHSMHS017.bigfish.com (10.3.87.117) with Microsoft SMTP Server (TLS) id 14.1.225.22; Mon, 29 Aug 2011 09:00:46 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-003.039d.mgd.msft.net (10.84.1.16) with Microsoft SMTP Server id 14.1.323.2; Mon, 29 Aug 2011 04:00:45 -0500 Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id p7T90eou014799; Mon, 29 Aug 2011 04:00:41 -0500 (CDT) From: Dong Aisheng To: Subject: [RFC v2 PATCH 1/1] ASoC: soc-core: symmetry checking for each DAIs separately Date: Mon, 29 Aug 2011 17:15:14 +0800 Message-ID: <1314609314-22162-1-git-send-email-b29396@freescale.com> X-Mailer: git-send-email 1.7.0.4 MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110829_050051_685393_9CDC2872 X-CRM114-Status: GOOD ( 24.83 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [213.199.154.144 listed in list.dnswl.org] Cc: lars@metafoo.de, s.hauer@pengutronix.de, broonie@opensource.wolfsonmicro.com, w.sang@pengutronix.de, lrg@ti.com, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 29 Aug 2011 09:01:29 +0000 (UTC) The orginal code does not cover the case that one DAI such as codec may be shared between other two DAIs(CPU). When do symmetry checking, altough the codec DAI requires symmetry, the two CPU DAIs may still be configured to run on different rates. We change to check each DAI's state separately instead of only checking the dai link to prevent this issue. Signed-off-by: Dong Aisheng Cc: Mark Brown Cc: Liam Girdwood Cc: Sascha Hauer Cc: Wolfram Sang Cc: Lars-Peter Clausen Acked-by: Liam Girdwood Tested-by: Wolfram Sang --- Change since v1: Address the comments from Lars-Peter Clausen. * add the dai as an parameter for soc_pcm_apply_symmetry Thanks for the suggestion. --- include/sound/soc-dai.h | 3 +++ include/sound/soc.h | 2 -- sound/soc/soc-pcm.c | 40 +++++++++++++++++++++++++--------------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 5ad5f3a..12d98b4 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -242,6 +242,9 @@ struct snd_soc_dai { void *playback_dma_data; void *capture_dma_data; + /* Symmetry data - only valid if symmetry is being enforced */ + unsigned int rate; + /* parent platform/codec */ union { struct snd_soc_platform *platform; diff --git a/include/sound/soc.h b/include/sound/soc.h index 3fe658e..5449139 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -849,8 +849,6 @@ struct snd_soc_pcm_runtime { unsigned int complete:1; unsigned int dev_registered:1; - /* Symmetry data - only valid if symmetry is being enforced */ - unsigned int rate; long pmdown_time; /* runtime devices */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1aee9fc..8eb0f07 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -27,15 +27,13 @@ #include #include -static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) +static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, + struct snd_soc_dai *soc_dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret; - if (!codec_dai->driver->symmetric_rates && - !cpu_dai->driver->symmetric_rates && + if (!soc_dai->driver->symmetric_rates && !rtd->dai_link->symmetric_rates) return 0; @@ -43,19 +41,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) * the second can need to get its constraints before the first has * picked a rate. Complain and allow the application to carry on. */ - if (!rtd->rate) { - dev_warn(&rtd->dev, + if (!soc_dai->rate) { + dev_warn(soc_dai->dev, "Not enforcing symmetric_rates due to race\n"); return 0; } - dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate); + dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, - rtd->rate, rtd->rate); + soc_dai->rate, soc_dai->rate); if (ret < 0) { - dev_err(&rtd->dev, + dev_err(soc_dai->dev, "Unable to apply rate symmetry constraint: %d\n", ret); return ret; } @@ -185,8 +183,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) } /* Symmetry only applies if we've already got an active stream. */ - if (cpu_dai->active || codec_dai->active) { - ret = soc_pcm_apply_symmetry(substream); + if (cpu_dai->active) { + ret = soc_pcm_apply_symmetry(substream, cpu_dai); + if (ret != 0) + goto config_err; + } + + if (codec_dai->active) { + ret = soc_pcm_apply_symmetry(substream, codec_dai); if (ret != 0) goto config_err; } @@ -288,8 +292,12 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) codec_dai->active--; codec->active--; - if (!cpu_dai->active && !codec_dai->active) - rtd->rate = 0; + /* clear the corresponding DAIs rate when inactive */ + if (!cpu_dai->active) + cpu_dai->rate = 0; + + if (!codec_dai->active) + codec_dai->rate = 0; /* Muting the DAC suppresses artifacts caused during digital * shutdown, for example from stopping clocks. @@ -447,7 +455,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } - rtd->rate = params_rate(params); + /* store the rate for each DAIs */ + cpu_dai->rate = params_rate(params); + codec_dai->rate = params_rate(params); out: mutex_unlock(&rtd->pcm_mutex);