From patchwork Wed Sep 18 06:46:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengjiu Wang X-Patchwork-Id: 173955 Delivered-To: patch@linaro.org Received: by 2002:ac9:19ad:0:0:0:0:0 with SMTP id d45csp6035878oce; Tue, 17 Sep 2019 23:48:54 -0700 (PDT) X-Google-Smtp-Source: APXvYqyf484KDjiDjg2qC+7EZJwHU8jWuAkno+UjVGr6J1N3BFUK/+OqWXgvgPegjtwwAn3RU0uG X-Received: by 2002:a05:6402:13c9:: with SMTP id a9mr2052246edx.25.1568789334827; Tue, 17 Sep 2019 23:48:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568789334; cv=none; d=google.com; s=arc-20160816; b=cL0cNbAfYwYOqe1mqrC1boFDBZIEZVzRcBXfwMHYpM4N8zhDMfvgHa4EZdiwsUf2B0 /3EIDqJlAPgiEoiqQBsBKbh8YGriCkNAmjSphLTiyWqfHAExrc7AP3WorP4szF613Vp4 gTQn8UfYpXTNAJdgFHHF8MfCTmJ2o+ShnR1/sBF1gqGD9Hyv1w2YMTOTJkqae3YT/3FA Dy+Rmf4mQNR7PuoXaDrXHrOWQyZD2zWtbFILKWc3YgScBI8t3f0qicG2EL21zEpLnQ9a Z3KzL2B0VrR9sJkGUBeBkpUae5qF7zU+PBlHhA6b8sqZ4NGnnEMDyez9D8vkdKCkOUvX GQwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:to:from; bh=Z20MX5J0KlSMpTGcQPsYyjm4fqfBSeUljliKUudTg/U=; b=fTZKbUdQ9qkKQuzrwUhG9n9bSA6n7jQRFLD4YEUrQUnTGYNeQ0pFeNEFbQU5tzoiho 91hYmMD6CtJSrEfIaapaN/fjZ1S5g+kDOa5hsdJOLQreOPmam4DYSPAq3EL+FfxMxJhh M4CxkYhSMEV3xweaqPADhz+DXl6ykwJN7/dTgedRo8b7mwhnbSMOXphEiJrc84/YKjm0 jbx6X/Rhw0E0OapZLIpLNyWIx4mmqe+AvzJOey6NxhB51SMubfsm/yNfmc6Cf8BsP3LB rJWy0PC+6G3HgFKA0uHoU+RVubg+7i+eumNAy5+w7CU51RElT2eBHJmHagGJQdlSHY21 N83Q== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id qo6si681498ejb.386.2019.09.17.23.48.54; Tue, 17 Sep 2019 23:48:54 -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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727536AbfIRGsq (ORCPT + 27 others); Wed, 18 Sep 2019 02:48:46 -0400 Received: from inva021.nxp.com ([92.121.34.21]:51914 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726330AbfIRGsp (ORCPT ); Wed, 18 Sep 2019 02:48:45 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id D5B4B20025F; Wed, 18 Sep 2019 08:48:43 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 609E2200231; Wed, 18 Sep 2019 08:48:36 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 664FF402D0; Wed, 18 Sep 2019 14:48:27 +0800 (SGT) From: Shengjiu Wang To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, devicetree@vger.kernel.org, lars@metafoo.de Subject: [PATCH V2 3/4] ASoC: pcm_dmaengine: Extract snd_dmaengine_pcm_set_runtime_hwparams Date: Wed, 18 Sep 2019 14:46:50 +0800 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When set the runtime hardware parameters, we may need to query the capability of DMA to complete the parameters. This patch is to Extract this operation from dmaengine_pcm_set_runtime_hwparams function to a separate function snd_dmaengine_pcm_set_runtime_hwparams, that other components which need this feature can call this function. Signed-off-by: Shengjiu Wang --- include/sound/dmaengine_pcm.h | 5 ++ sound/core/pcm_dmaengine.c | 83 +++++++++++++++++++++++++++ sound/soc/soc-generic-dmaengine-pcm.c | 62 ++------------------ 3 files changed, 92 insertions(+), 58 deletions(-) -- 2.21.0 diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index c679f6116580..1bcbc4d2bc6f 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -83,6 +83,11 @@ void snd_dmaengine_pcm_set_config_from_dai_data( const struct snd_dmaengine_dai_dma_data *dma_data, struct dma_slave_config *config); +int snd_dmaengine_pcm_set_runtime_hwparams( + struct snd_pcm_substream *substream, + struct snd_dmaengine_dai_dma_data *dma_data, + struct snd_pcm_hardware *hw, + struct dma_chan *chan); /* * Try to request the DMA channel using compat_request_channel or diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 89a05926ac73..c9d56a12164d 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -369,4 +369,87 @@ int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); +/** + * snd_dmaengine_pcm_set_runtime_hwparams - Set runtime hw params + * @substream: PCM substream + * @dma_data: DAI DMA data + * @hw: PCM hw params + * @chan: DMA channel to use for data transfers + * + * Returns 0 on success, a negative error code otherwise. + * + * This function will query DMA capability, then refine the pcm hardware + * parameters, finally set substream runtime hardware parameters. + */ +int snd_dmaengine_pcm_set_runtime_hwparams( + struct snd_pcm_substream *substream, + struct snd_dmaengine_dai_dma_data *dma_data, + struct snd_pcm_hardware *hw, + struct dma_chan *chan) +{ + struct dma_slave_caps dma_caps; + u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + snd_pcm_format_t i; + int ret; + + if (!hw || !chan || !dma_data) + return -EINVAL; + + ret = dma_get_slave_caps(chan, &dma_caps); + if (ret == 0) { + if (dma_caps.cmd_pause && dma_caps.cmd_resume) + hw->info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; + if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) + hw->info |= SNDRV_PCM_INFO_BATCH; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + addr_widths = dma_caps.dst_addr_widths; + else + addr_widths = dma_caps.src_addr_widths; + } + + /* + * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep + * hw.formats set to 0, meaning no restrictions are in place. + * In this case it's the responsibility of the DAI driver to + * provide the supported format information. + */ + if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)) + /* + * Prepare formats mask for valid/allowed sample types. If the + * dma does not have support for the given physical word size, + * it needs to be masked out so user space can not use the + * format which produces corrupted audio. + * In case the dma driver does not implement the slave_caps the + * default assumption is that it supports 1, 2 and 4 bytes + * widths. + */ + for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) { + int bits = snd_pcm_format_physical_width(i); + + /* + * Enable only samples with DMA supported physical + * widths + */ + switch (bits) { + case 8: + case 16: + case 24: + case 32: + case 64: + if (addr_widths & (1 << (bits / 8))) + hw->formats |= pcm_format_to_bits(i); + break; + default: + /* Unsupported types */ + break; + } + } + + return snd_soc_set_runtime_hwparams(substream, hw); +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_runtime_hwparams); + MODULE_LICENSE("GPL"); diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 748f5f641002..1dadba2d0cdd 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -118,13 +118,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea struct device *dma_dev = dmaengine_dma_dev(pcm, substream); struct dma_chan *chan = pcm->chan[substream->stream]; struct snd_dmaengine_dai_dma_data *dma_data; - struct dma_slave_caps dma_caps; struct snd_pcm_hardware hw; - u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - snd_pcm_format_t i; - int ret; if (pcm->config && pcm->config->pcm_hardware) return snd_soc_set_runtime_hwparams(substream, @@ -145,58 +139,10 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) hw.info |= SNDRV_PCM_INFO_BATCH; - ret = dma_get_slave_caps(chan, &dma_caps); - if (ret == 0) { - if (dma_caps.cmd_pause && dma_caps.cmd_resume) - hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; - if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) - hw.info |= SNDRV_PCM_INFO_BATCH; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - addr_widths = dma_caps.dst_addr_widths; - else - addr_widths = dma_caps.src_addr_widths; - } - - /* - * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep - * hw.formats set to 0, meaning no restrictions are in place. - * In this case it's the responsibility of the DAI driver to - * provide the supported format information. - */ - if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)) - /* - * Prepare formats mask for valid/allowed sample types. If the - * dma does not have support for the given physical word size, - * it needs to be masked out so user space can not use the - * format which produces corrupted audio. - * In case the dma driver does not implement the slave_caps the - * default assumption is that it supports 1, 2 and 4 bytes - * widths. - */ - for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) { - int bits = snd_pcm_format_physical_width(i); - - /* - * Enable only samples with DMA supported physical - * widths - */ - switch (bits) { - case 8: - case 16: - case 24: - case 32: - case 64: - if (addr_widths & (1 << (bits / 8))) - hw.formats |= pcm_format_to_bits(i); - break; - default: - /* Unsupported types */ - break; - } - } - - return snd_soc_set_runtime_hwparams(substream, &hw); + return snd_dmaengine_pcm_set_runtime_hwparams(substream, + dma_data, + &hw, + chan); } static int dmaengine_pcm_open(struct snd_pcm_substream *substream)