ASoC: Intel: catpt: Optimize applying user settings

Initial user settings such as volume control need to be applied only
once after stream is allocated. As prepare() operation can be invoked
multiple times during the stream's lifetime, relocate
catpt_dai_apply_usettings() and call it directly within
catpt_dai_hw_params() rather than on every catpt_dai_prepare().

catpt_dai_apply_usettings() remains unchanged.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20201116133332.8530-4-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Cezary Rojewski 2020-11-16 14:33:30 +01:00 committed by Mark Brown
parent 1072460a1a
commit 768a3a3b32
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 71 additions and 71 deletions

View File

@ -324,73 +324,6 @@ static void catpt_dai_shutdown(struct snd_pcm_substream *substream,
snd_soc_dai_set_dma_data(dai, substream, NULL);
}
static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
struct catpt_stream_runtime *stream;
struct catpt_audio_format afmt;
struct catpt_ring_info rinfo;
struct snd_pcm_runtime *rtm = substream->runtime;
struct snd_dma_buffer *dmab;
int ret;
stream = snd_soc_dai_get_dma_data(dai, substream);
if (stream->allocated)
return 0;
memset(&afmt, 0, sizeof(afmt));
afmt.sample_rate = params_rate(params);
afmt.bit_depth = params_physical_width(params);
afmt.valid_bit_depth = params_width(params);
afmt.num_channels = params_channels(params);
afmt.channel_config = catpt_get_channel_config(afmt.num_channels);
afmt.channel_map = catpt_get_channel_map(afmt.channel_config);
afmt.interleaving = CATPT_INTERLEAVING_PER_CHANNEL;
dmab = snd_pcm_get_dma_buf(substream);
catpt_arrange_page_table(substream, &stream->pgtbl);
memset(&rinfo, 0, sizeof(rinfo));
rinfo.page_table_addr = stream->pgtbl.addr;
rinfo.num_pages = DIV_ROUND_UP(rtm->dma_bytes, PAGE_SIZE);
rinfo.size = rtm->dma_bytes;
rinfo.offset = 0;
rinfo.ring_first_page_pfn = PFN_DOWN(snd_sgbuf_get_addr(dmab, 0));
ret = catpt_ipc_alloc_stream(cdev, stream->template->path_id,
stream->template->type,
&afmt, &rinfo,
stream->template->num_entries,
stream->template->entries,
stream->persistent,
cdev->scratch,
&stream->info);
if (ret)
return CATPT_IPC_ERROR(ret);
stream->allocated = true;
return 0;
}
static int catpt_dai_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
struct catpt_stream_runtime *stream;
stream = snd_soc_dai_get_dma_data(dai, substream);
if (!stream->allocated)
return 0;
catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id);
catpt_ipc_free_stream(cdev, stream->info.stream_hw_id);
stream->allocated = false;
return 0;
}
static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol);
static int catpt_dai_apply_usettings(struct snd_soc_dai *dai,
@ -439,6 +372,77 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai,
return 0;
}
static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
struct catpt_stream_runtime *stream;
struct catpt_audio_format afmt;
struct catpt_ring_info rinfo;
struct snd_pcm_runtime *rtm = substream->runtime;
struct snd_dma_buffer *dmab;
int ret;
stream = snd_soc_dai_get_dma_data(dai, substream);
if (stream->allocated)
return 0;
memset(&afmt, 0, sizeof(afmt));
afmt.sample_rate = params_rate(params);
afmt.bit_depth = params_physical_width(params);
afmt.valid_bit_depth = params_width(params);
afmt.num_channels = params_channels(params);
afmt.channel_config = catpt_get_channel_config(afmt.num_channels);
afmt.channel_map = catpt_get_channel_map(afmt.channel_config);
afmt.interleaving = CATPT_INTERLEAVING_PER_CHANNEL;
dmab = snd_pcm_get_dma_buf(substream);
catpt_arrange_page_table(substream, &stream->pgtbl);
memset(&rinfo, 0, sizeof(rinfo));
rinfo.page_table_addr = stream->pgtbl.addr;
rinfo.num_pages = DIV_ROUND_UP(rtm->dma_bytes, PAGE_SIZE);
rinfo.size = rtm->dma_bytes;
rinfo.offset = 0;
rinfo.ring_first_page_pfn = PFN_DOWN(snd_sgbuf_get_addr(dmab, 0));
ret = catpt_ipc_alloc_stream(cdev, stream->template->path_id,
stream->template->type,
&afmt, &rinfo,
stream->template->num_entries,
stream->template->entries,
stream->persistent,
cdev->scratch,
&stream->info);
if (ret)
return CATPT_IPC_ERROR(ret);
ret = catpt_dai_apply_usettings(dai, stream);
if (ret)
return ret;
stream->allocated = true;
return 0;
}
static int catpt_dai_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
struct catpt_stream_runtime *stream;
stream = snd_soc_dai_get_dma_data(dai, substream);
if (!stream->allocated)
return 0;
catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id);
catpt_ipc_free_stream(cdev, stream->info.stream_hw_id);
stream->allocated = false;
return 0;
}
static int catpt_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@ -458,10 +462,6 @@ static int catpt_dai_prepare(struct snd_pcm_substream *substream,
if (ret)
return CATPT_IPC_ERROR(ret);
ret = catpt_dai_apply_usettings(dai, stream);
if (ret)
return ret;
stream->prepared = true;
return 0;
}