Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Cezary Rojewski <cezary.rojewski@intel.com>
To: "Amadeusz Sławiński" <amadeuszx.slawinski@linux.intel.com>
Cc: <linux-sound@vger.kernel.org>, Jaroslav Kysela <perex@perex.cz>,
	"Takashi Iwai" <tiwai@suse.com>, Mark Brown <broonie@kernel.org>
Subject: Re: [PATCH] ASoC: Intel: avs: Constrain path based on BE capabilities
Date: Mon, 7 Apr 2025 15:44:23 +0200	[thread overview]
Message-ID: <15b97e92-ff96-4244-a1c5-2ef4c511ec1a@intel.com> (raw)
In-Reply-To: <20250407130851.1726800-1-amadeuszx.slawinski@linux.intel.com>

On 2025-04-07 3:08 PM, Amadeusz Sławiński wrote:
> For i2s and DMIC copiers constraint stream capabilities based on
> available NHLT configuration. This allows topology to provide generic
> configuration that handles more hardware, while filtering unavailable
> ones at runtime.
> 
> Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>

A number of iterations reviewed by me in our linux.avs mainline.

Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>

> ---
>   sound/soc/intel/avs/path.c | 72 ++++++++++++++++++++++++++++++++++++++
>   sound/soc/intel/avs/path.h |  5 +++
>   sound/soc/intel/avs/pcm.c  | 49 +++++++++++++++++++++++++-
>   3 files changed, 125 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
> index ef0c1d125d66b..cafb8c6198bed 100644
> --- a/sound/soc/intel/avs/path.c
> +++ b/sound/soc/intel/avs/path.c
> @@ -115,6 +115,78 @@ avs_path_find_variant(struct avs_dev *adev,
>   	return NULL;
>   }
>   
> +static struct acpi_nhlt_config *
> +avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t);
> +
> +int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
> +			    struct snd_pcm_hw_constraint_list *rate_list,
> +			    struct snd_pcm_hw_constraint_list *channels_list,
> +			    struct snd_pcm_hw_constraint_list *sample_bits_list)
> +{
> +	struct avs_tplg_path *path_template;
> +	unsigned int *rlist, *clist, *slist;
> +	size_t i;
> +
> +	i = 0;
> +	list_for_each_entry(path_template, &template->path_list, node)
> +		i++;
> +
> +	rlist = kcalloc(i, sizeof(rlist), GFP_KERNEL);
> +	clist = kcalloc(i, sizeof(clist), GFP_KERNEL);
> +	slist = kcalloc(i, sizeof(slist), GFP_KERNEL);
> +
> +	i = 0;
> +	list_for_each_entry(path_template, &template->path_list, node) {
> +		struct avs_tplg_pipeline *pipeline_template;
> +
> +		list_for_each_entry(pipeline_template, &path_template->ppl_list, node) {
> +			struct avs_tplg_module *module_template;
> +
> +			list_for_each_entry(module_template, &pipeline_template->mod_list, node) {
> +				const guid_t *type = &module_template->cfg_ext->type;
> +				struct acpi_nhlt_config *blob;
> +
> +				if (!guid_equal(type, &AVS_COPIER_MOD_UUID) &&
> +				    !guid_equal(type, &AVS_WOVHOSTM_MOD_UUID))
> +					continue;
> +
> +				switch (module_template->cfg_ext->copier.dma_type) {
> +				case AVS_DMA_DMIC_LINK_INPUT:
> +				case AVS_DMA_I2S_LINK_OUTPUT:
> +				case AVS_DMA_I2S_LINK_INPUT:
> +					break;
> +				default:
> +					continue;
> +				}
> +
> +				blob = avs_nhlt_config_or_default(adev, module_template);
> +				if (IS_ERR(blob))
> +					continue;
> +
> +				rlist[i] = path_template->fe_fmt->sampling_freq;
> +				clist[i] = path_template->fe_fmt->num_channels;
> +				slist[i] = path_template->fe_fmt->bit_depth;
> +				i++;
> +			}
> +		}
> +	}
> +
> +	if (i) {
> +		rate_list->count = i;
> +		rate_list->list = rlist;
> +		channels_list->count = i;
> +		channels_list->list = clist;
> +		sample_bits_list->count = i;
> +		sample_bits_list->list = slist;
> +	} else {
> +		kfree(rlist);
> +		kfree(clist);
> +		kfree(slist);
> +	}
> +
> +	return i;
> +}
> +
>   static void avs_init_node_id(union avs_connector_node_id *node_id,
>   			     struct avs_tplg_modcfg_ext *te, u32 dma_id)
>   {
> diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h
> index 7ed7e94e0a566..c65ed84aa8530 100644
> --- a/sound/soc/intel/avs/path.h
> +++ b/sound/soc/intel/avs/path.h
> @@ -69,6 +69,11 @@ int avs_path_reset(struct avs_path *path);
>   int avs_path_pause(struct avs_path *path);
>   int avs_path_run(struct avs_path *path, int trigger);
>   
> +int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
> +			    struct snd_pcm_hw_constraint_list *rate_list,
> +			    struct snd_pcm_hw_constraint_list *channels_list,
> +			    struct snd_pcm_hw_constraint_list *sample_bits_list);
> +
>   int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod,
>   			   struct soc_mixer_control *mc, long *input);
>   int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod,
> diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
> index dac463390da13..b57db62d1b364 100644
> --- a/sound/soc/intel/avs/pcm.c
> +++ b/sound/soc/intel/avs/pcm.c
> @@ -31,6 +31,10 @@ struct avs_dma_data {
>   		struct hdac_ext_stream *host_stream;
>   	};
>   
> +	struct snd_pcm_hw_constraint_list rate_list;
> +	struct snd_pcm_hw_constraint_list channels_list;
> +	struct snd_pcm_hw_constraint_list sample_bits_list;
> +
>   	struct work_struct period_elapsed_work;
>   	struct snd_pcm_substream *substream;
>   };
> @@ -74,6 +78,45 @@ void avs_period_elapsed(struct snd_pcm_substream *substream)
>   	schedule_work(&data->period_elapsed_work);
>   }
>   
> +static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
> +static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_pcm_hw_constraint_list *r, *c, *s;
> +	struct avs_tplg_path_template *template;
> +	struct avs_dma_data *data;
> +	int ret;
> +
> +	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		return ret;
> +
> +	data = snd_soc_dai_get_dma_data(dai, substream);
> +	r = &(data->rate_list);
> +	c = &(data->channels_list);
> +	s = &(data->sample_bits_list);
> +
> +	template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
> +	ret = avs_path_set_constraint(data->adev, template, r, c, s);
> +	if (ret <= 0)
> +		return ret;
> +
> +	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, r);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, c);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, s);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
>   static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
>   {
>   	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> @@ -101,7 +144,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d
>   	if (rtd->dai_link->ignore_suspend)
>   		adev->num_lp_paths++;
>   
> -	return 0;
> +	return avs_hw_constraints_init(substream, dai);
>   }
>   
>   static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
> @@ -114,6 +157,10 @@ static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc
>   	if (rtd->dai_link->ignore_suspend)
>   		data->adev->num_lp_paths--;
>   
> +	kfree(data->rate_list.list);
> +	kfree(data->channels_list.list);
> +	kfree(data->sample_bits_list.list);
> +
>   	snd_soc_dai_set_dma_data(dai, substream, NULL);
>   	kfree(data);
>   }
> 
> base-commit: 3a0f0a4355df0240485ed62b6bd6afa5b3e689c5


  reply	other threads:[~2025-04-07 13:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-07 13:08 [PATCH] ASoC: Intel: avs: Constrain path based on BE capabilities Amadeusz Sławiński
2025-04-07 13:44 ` Cezary Rojewski [this message]
2025-04-08  9:24 ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15b97e92-ff96-4244-a1c5-2ef4c511ec1a@intel.com \
    --to=cezary.rojewski@intel.com \
    --cc=amadeuszx.slawinski@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox