mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ASoC: qcom: audioreach: support multichannel PCM formats
@ 2026-10-21 10:25 Zhangfei Gao
  2026-10-26  6:19 ` Prasad Kumpatla
  0 siblings, 1 reply; 3+ messages in thread
From: Zhangfei Gao @ 2026-10-21 10:25 UTC (permalink / raw)
  To: Mark Brown, Srinivas Kandagatla
  Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Krzysztof Kozlowski, shengchao.guo, mohammad.rafi.shaik,
	bartosz.golaszewski, linux-sound, linux-arm-msm, linux-kernel,
	Zhangfei Gao

AudioReach currently rejects PCM streams with more than four channels in
the PCM and shared-memory media format paths.

Extend the default channel map to support PCM streams with up to eight
channels and relax the PCM and shared-memory media format validation
accordingly.

Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
---
 sound/soc/qcom/qdsp6/audioreach.c | 74 ++++++++++++++++++++++++++-----
 1 file changed, 62 insertions(+), 12 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index d2dc5d37bccf..626cfbca79c8 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -308,20 +308,70 @@ EXPORT_SYMBOL_GPL(audioreach_alloc_apm_cmd_pkt);
 
 void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
 {
-	if (num_channels == 1) {
-		ch_map[0] =  PCM_CHANNEL_FL;
-	} else if (num_channels == 2) {
-		ch_map[0] =  PCM_CHANNEL_FL;
-		ch_map[1] =  PCM_CHANNEL_FR;
-	} else if (num_channels == 4) {
-		ch_map[0] =  PCM_CHANNEL_FL;
-		ch_map[1] =  PCM_CHANNEL_FR;
-		ch_map[2] =  PCM_CHANNEL_LS;
-		ch_map[3] =  PCM_CHANNEL_RS;
+	memset(ch_map, 0, AR_PCM_MAX_NUM_CHANNEL);
+
+	switch (num_channels) {
+	case 1:
+		ch_map[0] = PCM_CHANNEL_FL;
+		break;
+	case 2:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		break;
+	case 3:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_FC;
+		break;
+	case 4:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_LS;
+		ch_map[3] = PCM_CHANNEL_RS;
+		break;
+	case 5:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_FC;
+		ch_map[3] = PCM_CHANNEL_LS;
+		ch_map[4] = PCM_CHANNEL_RS;
+		break;
+	case 6:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_LFE;
+		ch_map[3] = PCM_CHANNEL_FC;
+		ch_map[4] = PCM_CHANNEL_LS;
+		ch_map[5] = PCM_CHANNEL_RS;
+		break;
+	case 7:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_LFE;
+		ch_map[3] = PCM_CHANNEL_FC;
+		ch_map[4] = PCM_CHANNEL_LS;
+		ch_map[5] = PCM_CHANNEL_RS;
+		ch_map[6] = PCM_CHANNEL_CS;
+		break;
+	case 8:
+		ch_map[0] = PCM_CHANNEL_FL;
+		ch_map[1] = PCM_CHANNEL_FR;
+		ch_map[2] = PCM_CHANNEL_LFE;
+		ch_map[3] = PCM_CHANNEL_FC;
+		ch_map[4] = PCM_CHANNEL_LS;
+		ch_map[5] = PCM_CHANNEL_RS;
+		ch_map[6] = PCM_CHANNEL_LB;
+		ch_map[7] = PCM_CHANNEL_RB;
+		break;
 	}
 }
 EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
 
+static bool audioreach_channels_supported(u32 num_channels)
+{
+	return num_channels >= 1 && num_channels <= AR_PCM_MAX_NUM_CHANNEL;
+}
+
 static void apm_populate_container_config(struct apm_container_obj *cfg,
 					  const struct audioreach_container *cont)
 {
@@ -1185,7 +1235,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
 	int payload_size;
 	int i, j;
 
-	if (num_channels > 4) {
+	if (!audioreach_channels_supported(num_channels)) {
 		dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
 		return -EINVAL;
 	}
@@ -1275,7 +1325,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
 	int i, j;
 	void *p;
 
-	if (num_channels > 4) {
+	if (!audioreach_channels_supported(num_channels)) {
 		dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
 		return -EINVAL;
 	}
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ASoC: qcom: audioreach: support multichannel PCM formats
  2026-10-21 10:25 [PATCH] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
@ 2026-10-26  6:19 ` Prasad Kumpatla
  2026-10-26  7:59   ` Zhangfei Gao
  0 siblings, 1 reply; 3+ messages in thread
From: Prasad Kumpatla @ 2026-10-26  6:19 UTC (permalink / raw)
  To: Zhangfei Gao, Mark Brown, Srinivas Kandagatla
  Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Krzysztof Kozlowski, shengchao.guo, mohammad.rafi.shaik,
	bartosz.golaszewski, linux-sound, linux-arm-msm, linux-kernel

>   void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
>   {
> -	if (num_channels == 1) {
> -		ch_map[0] =  PCM_CHANNEL_FL;
> -	} else if (num_channels == 2) {
> -		ch_map[0] =  PCM_CHANNEL_FL;
> -		ch_map[1] =  PCM_CHANNEL_FR;
> -	} else if (num_channels == 4) {
> -		ch_map[0] =  PCM_CHANNEL_FL;
> -		ch_map[1] =  PCM_CHANNEL_FR;
> -		ch_map[2] =  PCM_CHANNEL_LS;
> -		ch_map[3] =  PCM_CHANNEL_RS;
> +	memset(ch_map, 0, AR_PCM_MAX_NUM_CHANNEL);
> +
> +	switch (num_channels) {
> +	case 1:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		break;
> +	case 2:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		break;
> +	case 3:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_FC;
> +		break;
> +	case 4:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_LS;
> +		ch_map[3] = PCM_CHANNEL_RS;
> +		break;
> +	case 5:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_FC;
> +		ch_map[3] = PCM_CHANNEL_LS;
> +		ch_map[4] = PCM_CHANNEL_RS;
> +		break;
> +	case 6:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_LFE;
> +		ch_map[3] = PCM_CHANNEL_FC;
> +		ch_map[4] = PCM_CHANNEL_LS;
> +		ch_map[5] = PCM_CHANNEL_RS;
> +		break;
> +	case 7:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_LFE;
> +		ch_map[3] = PCM_CHANNEL_FC;
> +		ch_map[4] = PCM_CHANNEL_LS;
> +		ch_map[5] = PCM_CHANNEL_RS;
> +		ch_map[6] = PCM_CHANNEL_CS;
> +		break;
> +	case 8:
> +		ch_map[0] = PCM_CHANNEL_FL;
> +		ch_map[1] = PCM_CHANNEL_FR;
> +		ch_map[2] = PCM_CHANNEL_LFE;
> +		ch_map[3] = PCM_CHANNEL_FC;
> +		ch_map[4] = PCM_CHANNEL_LS;
> +		ch_map[5] = PCM_CHANNEL_RS;
> +		ch_map[6] = PCM_CHANNEL_LB;
> +		ch_map[7] = PCM_CHANNEL_RB;
> +		break;
>   	}
>   }
>   EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);

audioreach_set_default_channel_mapping() silently leaves an all-zero channel map for unsupported channel counts.
Since this helper is exported and callers such as q6apm_dai_prepare/q6dma_hw_params/q6hdmi_hw_params() don't validate the range.

would it make sense to return -EINVAL for unsupported values and have callers propagate the error?

Thanks,
Prasad

>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ASoC: qcom: audioreach: support multichannel PCM formats
  2026-10-26  6:19 ` Prasad Kumpatla
@ 2026-10-26  7:59   ` Zhangfei Gao
  0 siblings, 0 replies; 3+ messages in thread
From: Zhangfei Gao @ 2026-10-26  7:59 UTC (permalink / raw)
  To: Prasad Kumpatla
  Cc: Mark Brown, Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela,
	Takashi Iwai, Krzysztof Kozlowski, shengchao.guo,
	mohammad.rafi.shaik, bartosz.golaszewski, linux-sound,
	linux-arm-msm, linux-kernel

On Mon, Oct 26, 2026 at 2:19 PM Prasad Kumpatla
<prasad.kumpatla@oss.qualcomm.com> wrote:
>
> >   void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
> >   {
> > -     if (num_channels == 1) {
> > -             ch_map[0] =  PCM_CHANNEL_FL;
> > -     } else if (num_channels == 2) {
> > -             ch_map[0] =  PCM_CHANNEL_FL;
> > -             ch_map[1] =  PCM_CHANNEL_FR;
> > -     } else if (num_channels == 4) {
> > -             ch_map[0] =  PCM_CHANNEL_FL;
> > -             ch_map[1] =  PCM_CHANNEL_FR;
> > -             ch_map[2] =  PCM_CHANNEL_LS;
> > -             ch_map[3] =  PCM_CHANNEL_RS;
> > +     memset(ch_map, 0, AR_PCM_MAX_NUM_CHANNEL);
> > +
> > +     switch (num_channels) {
> > +     case 1:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             break;
> > +     case 2:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             break;
> > +     case 3:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_FC;
> > +             break;
> > +     case 4:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_LS;
> > +             ch_map[3] = PCM_CHANNEL_RS;
> > +             break;
> > +     case 5:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_FC;
> > +             ch_map[3] = PCM_CHANNEL_LS;
> > +             ch_map[4] = PCM_CHANNEL_RS;
> > +             break;
> > +     case 6:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_LFE;
> > +             ch_map[3] = PCM_CHANNEL_FC;
> > +             ch_map[4] = PCM_CHANNEL_LS;
> > +             ch_map[5] = PCM_CHANNEL_RS;
> > +             break;
> > +     case 7:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_LFE;
> > +             ch_map[3] = PCM_CHANNEL_FC;
> > +             ch_map[4] = PCM_CHANNEL_LS;
> > +             ch_map[5] = PCM_CHANNEL_RS;
> > +             ch_map[6] = PCM_CHANNEL_CS;
> > +             break;
> > +     case 8:
> > +             ch_map[0] = PCM_CHANNEL_FL;
> > +             ch_map[1] = PCM_CHANNEL_FR;
> > +             ch_map[2] = PCM_CHANNEL_LFE;
> > +             ch_map[3] = PCM_CHANNEL_FC;
> > +             ch_map[4] = PCM_CHANNEL_LS;
> > +             ch_map[5] = PCM_CHANNEL_RS;
> > +             ch_map[6] = PCM_CHANNEL_LB;
> > +             ch_map[7] = PCM_CHANNEL_RB;
> > +             break;
> >       }
> >   }
> >   EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
>
> audioreach_set_default_channel_mapping() silently leaves an all-zero channel map for unsupported channel counts.
> Since this helper is exported and callers such as q6apm_dai_prepare/q6dma_hw_params/q6hdmi_hw_params() don't validate the range.
>
> would it make sense to return -EINVAL for unsupported values and have callers propagate the error?

Thanks Prasad,

Then we can directly reuse q6dsp_map_channels to make it simpler.
Will update.

Thanks

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-26  8:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 10:25 [PATCH] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
2026-10-26  6:19 ` Prasad Kumpatla
2026-10-26  7:59   ` Zhangfei Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®