mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-11 02:08:27 +07:00
ASoC: pcm_dmaengine: Extract snd_dmaengine_pcm_refine_runtime_hwparams
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_refine_runtime_hwparams, that other components which need this feature can call this function. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Reviewed-by: Nicolin Chen <nicoleotsuka@gmail.com> Link: https://lore.kernel.org/r/d728f65194e9978cbec4132b522d4fed420d704a.1569493933.git.shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
109539c986
commit
e957204e73
@ -83,6 +83,11 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
|||||||
const struct snd_dmaengine_dai_dma_data *dma_data,
|
const struct snd_dmaengine_dai_dma_data *dma_data,
|
||||||
struct dma_slave_config *config);
|
struct dma_slave_config *config);
|
||||||
|
|
||||||
|
int snd_dmaengine_pcm_refine_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
|
* Try to request the DMA channel using compat_request_channel or
|
||||||
|
@ -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);
|
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_dmaengine_pcm_refine_runtime_hwparams - Refine 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.
|
||||||
|
*/
|
||||||
|
int snd_dmaengine_pcm_refine_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 = 0;
|
||||||
|
|
||||||
|
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 ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_refine_runtime_hwparams);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -118,12 +118,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
|
|||||||
struct device *dma_dev = dmaengine_dma_dev(pcm, substream);
|
struct device *dma_dev = dmaengine_dma_dev(pcm, substream);
|
||||||
struct dma_chan *chan = pcm->chan[substream->stream];
|
struct dma_chan *chan = pcm->chan[substream->stream];
|
||||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||||
struct dma_slave_caps dma_caps;
|
|
||||||
struct snd_pcm_hardware hw;
|
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;
|
int ret;
|
||||||
|
|
||||||
if (pcm->config && pcm->config->pcm_hardware)
|
if (pcm->config && pcm->config->pcm_hardware)
|
||||||
@ -145,56 +140,12 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
|
|||||||
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
|
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
|
||||||
hw.info |= SNDRV_PCM_INFO_BATCH;
|
hw.info |= SNDRV_PCM_INFO_BATCH;
|
||||||
|
|
||||||
ret = dma_get_slave_caps(chan, &dma_caps);
|
ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream,
|
||||||
if (ret == 0) {
|
dma_data,
|
||||||
if (dma_caps.cmd_pause && dma_caps.cmd_resume)
|
&hw,
|
||||||
hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
|
chan);
|
||||||
if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
|
if (ret)
|
||||||
hw.info |= SNDRV_PCM_INFO_BATCH;
|
return ret;
|
||||||
|
|
||||||
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_soc_set_runtime_hwparams(substream, &hw);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user