* [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
@ 2026-10-26 8:25 Zhangfei Gao
2026-10-27 8:46 ` Prasad Kumpatla
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Zhangfei Gao @ 2026-10-26 8: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, Prasad Kumpatla, 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.
Reuse q6dsp_map_channels() to support multichannel PCM formats.
Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
---
v2: reuse q6dsp_map_channels
sound/soc/qcom/qdsp6/audioreach.c | 26 -------------------------
sound/soc/qcom/qdsp6/audioreach.h | 1 -
sound/soc/qcom/qdsp6/q6apm-dai.c | 12 +++++++++---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 9 +++++++--
4 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index d2dc5d37bccf..33161523c7da 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -306,22 +306,6 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
}
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;
- }
-}
-EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
-
static void apm_populate_container_config(struct apm_container_obj *cfg,
const struct audioreach_container *cont)
{
@@ -1185,11 +1169,6 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
int payload_size;
int i, j;
- if (num_channels > 4) {
- dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
- return -EINVAL;
- }
-
payload_size = APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels);
struct gpr_pkt *pkt __free(kfree) =
@@ -1275,11 +1254,6 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
int i, j;
void *p;
- if (num_channels > 4) {
- dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
- return -EINVAL;
- }
-
payload_size = APM_SHMEM_FMT_CFG_PSIZE(num_channels) + APM_MODULE_PARAM_DATA_SIZE;
struct gpr_pkt *pkt __free(kfree) =
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 587f14ce71d2..495072da070b 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -1009,7 +1009,6 @@ static inline u16 audioreach_gpr_dest_domain(gpr_device_t *gdev)
void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode,
uint32_t token);
-void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels);
void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode,
uint32_t token, uint32_t src_port,
uint32_t dest_port);
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 58beaf906b9f..83594b693569 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -21,6 +21,7 @@
#include <asm/div64.h>
#include <asm/dma.h>
#include "q6apm.h"
+#include "q6dsp-common.h"
#define DRV_NAME "q6apm-dai"
#define POS_BUFFER_BYTES 4096
@@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
cfg.num_channels = runtime->channels;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = SND_AUDIOCODEC_PCM;
- audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
+ ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
+ if (ret)
+ return ret;
+
if (prtd->state) {
/* clear the previous setup if any */
q6apm_graph_stop(prtd->graph);
@@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
cfg.num_channels = 2;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = codec->id;
- audioreach_set_default_channel_mapping(cfg.channel_map,
- cfg.num_channels);
+ ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
+ if (ret)
+ return ret;
+
memcpy(&cfg.codec, codec, sizeof(*codec));
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 83f2711bceea..fcc0267d3657 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -147,7 +147,9 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
cfg->num_channels = channels;
- audioreach_set_default_channel_mapping(cfg->channel_map, channels);
+ ret = q6dsp_map_channels(cfg->channel_map, channels);
+ if (ret)
+ return ret;
switch (dai->id) {
case DISPLAY_PORT_RX_0:
@@ -173,11 +175,14 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
+ int ret;
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
cfg->num_channels = channels;
- audioreach_set_default_channel_mapping(cfg->channel_map, channels);
+ ret = q6dsp_map_channels(cfg->channel_map, channels);
+ if (ret)
+ return ret;
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-26 8:25 [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
@ 2026-10-27 8:46 ` Prasad Kumpatla
2026-10-27 9:55 ` Zhangfei Gao
2026-10-27 13:47 ` Srinivas Kandagatla
2026-10-28 2:47 ` [PATCH v3] " Zhangfei Gao
2 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-10-27 8:46 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
> #define DRV_NAME "q6apm-dai"
> #define POS_BUFFER_BYTES 4096
> @@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
> cfg.num_channels = runtime->channels;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = SND_AUDIOCODEC_PCM;
> - audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
> + ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
> + if (ret)
> + return ret;
> +
> if (prtd->state) {
> /* clear the previous setup if any */
> q6apm_graph_stop(prtd->graph);
> @@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
> cfg.num_channels = 2;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = codec->id;
> - audioreach_set_default_channel_mapping(cfg.channel_map,
> - cfg.num_channels);
> + ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
|
|
|q6dsp_map_channels()| changes the mono mapping from |PCM_CHANNEL_FL| to
|PCM_CHANNEL_FC| and does not handle 7 channels. Have these cases been
checked and confirmed to be supported as expected for AudioReach ?
Thanks,
Prasad
> + if (ret)
> + return ret;
> +
> memcpy(&cfg.codec, codec, sizeof(*codec));
>
> ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
> diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> index 83f2711bceea..fcc0267d3657 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> @@ -147,7 +147,9 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> switch (dai->id) {
> case DISPLAY_PORT_RX_0:
> @@ -173,11 +175,14 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
> struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
> struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
> int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
> + int ret;
>
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> return 0;
> }
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-27 8:46 ` Prasad Kumpatla
@ 2026-10-27 9:55 ` Zhangfei Gao
2026-10-27 11:45 ` Prasad Kumpatla
0 siblings, 1 reply; 10+ messages in thread
From: Zhangfei Gao @ 2026-10-27 9:55 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 Tue, Oct 27, 2026 at 4:46 PM Prasad Kumpatla
<prasad.kumpatla@oss.qualcomm.com> wrote:
>
> > #define DRV_NAME "q6apm-dai"
> > #define POS_BUFFER_BYTES 4096
> > @@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
> > cfg.num_channels = runtime->channels;
> > cfg.bit_width = prtd->bits_per_sample;
> > cfg.fmt = SND_AUDIOCODEC_PCM;
> > - audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
> > + ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
> > + if (ret)
> > + return ret;
> > +
> > if (prtd->state) {
> > /* clear the previous setup if any */
> > q6apm_graph_stop(prtd->graph);
> > @@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
> > cfg.num_channels = 2;
> > cfg.bit_width = prtd->bits_per_sample;
> > cfg.fmt = codec->id;
> > - audioreach_set_default_channel_mapping(cfg.channel_map,
> > - cfg.num_channels);
> > + ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
> |
> |
> |q6dsp_map_channels()| changes the mono mapping from |PCM_CHANNEL_FL| to
> |PCM_CHANNEL_FC| and does not handle 7 channels. Have these cases been
> checked and confirmed to be supported as expected for AudioReach ?
Yes, have checked with Rafi, should be PCM_CHANNEL_FC.
Also confirmed from audioreach-engine
https://github.com/AudioReach/audioreach-engine/blob/master/modules/processing/bassboost/capi/src/capi_bassboost_utils.cpp
case 1:
if (PCM_CHANNEL_C != format_ptr->format.channel_type[0])
https://github.com/AudioReach/audioreach-engine/blob/master/modules/processing/Virtualizer/api/Virtualizer_api.h
uint16_t channel_map[0];
/**< @h2xmle_description { Payload consisting of channel mapping
information for all the channels. \n
The channel mapping is specific for
specific number of channels \n
for 1 : [PCM_CHANNEL_C] \n
for 2 : [PCM_CHANNEL_L, PCM_CHANNEL_R] \n }
About 7 channel.
If hw requirement is there then we can add right.
Currently no qcom upstream device is testing 7 channels,
For example, RRD 4 chanels and Ride 6 channels.
Thanks
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-27 9:55 ` Zhangfei Gao
@ 2026-10-27 11:45 ` Prasad Kumpatla
0 siblings, 0 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-10-27 11:45 UTC (permalink / raw)
To: Zhangfei Gao
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 10/27/2026 3:25 PM, Zhangfei Gao wrote:
> On Tue, Oct 27, 2026 at 4:46 PM Prasad Kumpatla
> <prasad.kumpatla@oss.qualcomm.com> wrote:
>>> #define DRV_NAME "q6apm-dai"
>>> #define POS_BUFFER_BYTES 4096
>>> @@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
>>> cfg.num_channels = runtime->channels;
>>> cfg.bit_width = prtd->bits_per_sample;
>>> cfg.fmt = SND_AUDIOCODEC_PCM;
>>> - audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
>>> + ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
>>> + if (ret)
>>> + return ret;
>>> +
>>> if (prtd->state) {
>>> /* clear the previous setup if any */
>>> q6apm_graph_stop(prtd->graph);
>>> @@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
>>> cfg.num_channels = 2;
>>> cfg.bit_width = prtd->bits_per_sample;
>>> cfg.fmt = codec->id;
>>> - audioreach_set_default_channel_mapping(cfg.channel_map,
>>> - cfg.num_channels);
>>> + ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
>> |
>> |
>> |q6dsp_map_channels()| changes the mono mapping from |PCM_CHANNEL_FL| to
>> |PCM_CHANNEL_FC| and does not handle 7 channels. Have these cases been
>> checked and confirmed to be supported as expected for AudioReach ?
> Yes, have checked with Rafi, should be PCM_CHANNEL_FC.
Thanks for confirmation.
Reviewed-by: Prasad Kumpatla<prasad.kumpatla@oss.qualcomm.com>
Thanks,
Prasad
>
> Also confirmed from audioreach-engine
> https://github.com/AudioReach/audioreach-engine/blob/master/modules/processing/bassboost/capi/src/capi_bassboost_utils.cpp
> case 1:
> if (PCM_CHANNEL_C != format_ptr->format.channel_type[0])
>
> https://github.com/AudioReach/audioreach-engine/blob/master/modules/processing/Virtualizer/api/Virtualizer_api.h
> uint16_t channel_map[0];
> /**< @h2xmle_description { Payload consisting of channel mapping
> information for all the channels. \n
> The channel mapping is specific for
> specific number of channels \n
> for 1 : [PCM_CHANNEL_C] \n
> for 2 : [PCM_CHANNEL_L, PCM_CHANNEL_R] \n }
>
> About 7 channel.
> If hw requirement is there then we can add right.
> Currently no qcom upstream device is testing 7 channels,
>
> For example, RRD 4 chanels and Ride 6 channels.
>
> Thanks
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-26 8:25 [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
2026-10-27 8:46 ` Prasad Kumpatla
@ 2026-10-27 13:47 ` Srinivas Kandagatla
2026-10-28 2:40 ` Zhangfei Gao
2026-10-28 2:47 ` [PATCH v3] " Zhangfei Gao
2 siblings, 1 reply; 10+ messages in thread
From: Srinivas Kandagatla @ 2026-10-27 13:47 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, Prasad Kumpatla, linux-sound, linux-arm-msm,
linux-kernel
On 10/26/26 8:25 AM, Zhangfei Gao wrote:
> AudioReach currently rejects PCM streams with more than four channels in
> the PCM and shared-memory media format paths.
bit more context would help, why you need it now?
>
> Reuse q6dsp_map_channels() to support multichannel PCM formats.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
> ---
>
> v2: reuse q6dsp_map_channels
>
> sound/soc/qcom/qdsp6/audioreach.c | 26 -------------------------
> sound/soc/qcom/qdsp6/audioreach.h | 1 -
> sound/soc/qcom/qdsp6/q6apm-dai.c | 12 +++++++++---
> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 9 +++++++--
> 4 files changed, 16 insertions(+), 32 deletions(-)
>
> diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
> index d2dc5d37bccf..33161523c7da 100644
> --- a/sound/soc/qcom/qdsp6/audioreach.c
> +++ b/sound/soc/qcom/qdsp6/audioreach.c
> @@ -306,22 +306,6 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
> }
> 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;
> - }
> -}
> -EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
> -
while you at this, please remove AR_PCM_MAX_NUM_CHANNEL too.
Other than that it looks good to me.
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
--srini
> static void apm_populate_container_config(struct apm_container_obj *cfg,
> const struct audioreach_container *cont)
> {
> @@ -1185,11 +1169,6 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
> int payload_size;
> int i, j;
>
> - if (num_channels > 4) {
> - dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
> - return -EINVAL;
> - }
> -
> payload_size = APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels);
>
> struct gpr_pkt *pkt __free(kfree) =
> @@ -1275,11 +1254,6 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
> int i, j;
> void *p;
>
> - if (num_channels > 4) {
> - dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
> - return -EINVAL;
> - }
> -
> payload_size = APM_SHMEM_FMT_CFG_PSIZE(num_channels) + APM_MODULE_PARAM_DATA_SIZE;
>
> struct gpr_pkt *pkt __free(kfree) =
> diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
> index 587f14ce71d2..495072da070b 100644
> --- a/sound/soc/qcom/qdsp6/audioreach.h
> +++ b/sound/soc/qcom/qdsp6/audioreach.h
> @@ -1009,7 +1009,6 @@ static inline u16 audioreach_gpr_dest_domain(gpr_device_t *gdev)
>
> void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode,
> uint32_t token);
> -void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels);
> void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode,
> uint32_t token, uint32_t src_port,
> uint32_t dest_port);
> diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
> index 58beaf906b9f..83594b693569 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-dai.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
> @@ -21,6 +21,7 @@
> #include <asm/div64.h>
> #include <asm/dma.h>
> #include "q6apm.h"
> +#include "q6dsp-common.h"
>
> #define DRV_NAME "q6apm-dai"
> #define POS_BUFFER_BYTES 4096
> @@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
> cfg.num_channels = runtime->channels;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = SND_AUDIOCODEC_PCM;
> - audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
> + ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
> + if (ret)
> + return ret;
> +
> if (prtd->state) {
> /* clear the previous setup if any */
> q6apm_graph_stop(prtd->graph);
> @@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
> cfg.num_channels = 2;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = codec->id;
> - audioreach_set_default_channel_mapping(cfg.channel_map,
> - cfg.num_channels);
> + ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
> + if (ret)
> + return ret;
> +
> memcpy(&cfg.codec, codec, sizeof(*codec));
>
> ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
> diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> index 83f2711bceea..fcc0267d3657 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> @@ -147,7 +147,9 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> switch (dai->id) {
> case DISPLAY_PORT_RX_0:
> @@ -173,11 +175,14 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
> struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
> struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
> int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
> + int ret;
>
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> return 0;
> }
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-27 13:47 ` Srinivas Kandagatla
@ 2026-10-28 2:40 ` Zhangfei Gao
0 siblings, 0 replies; 10+ messages in thread
From: Zhangfei Gao @ 2026-10-28 2:40 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: Mark Brown, Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Krzysztof Kozlowski, shengchao.guo,
mohammad.rafi.shaik, bartosz.golaszewski, Prasad Kumpatla,
linux-sound, linux-arm-msm, linux-kernel
On Tue, Oct 27, 2026 at 9:47 PM Srinivas Kandagatla
<srinivas.kandagatla@oss.qualcomm.com> wrote:
>
> On 10/26/26 8:25 AM, Zhangfei Gao wrote:
> > AudioReach currently rejects PCM streams with more than four channels in
> > the PCM and shared-memory media format paths.
> bit more context would help, why you need it now?
Sure
>
> >
> > Reuse q6dsp_map_channels() to support multichannel PCM formats.
> >
> > Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
> > ---
> >
> > v2: reuse q6dsp_map_channels
> >
> > sound/soc/qcom/qdsp6/audioreach.c | 26 -------------------------
> > sound/soc/qcom/qdsp6/audioreach.h | 1 -
> > sound/soc/qcom/qdsp6/q6apm-dai.c | 12 +++++++++---
> > sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 9 +++++++--
> > 4 files changed, 16 insertions(+), 32 deletions(-)
> >
> > diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
> > index d2dc5d37bccf..33161523c7da 100644
> > --- a/sound/soc/qcom/qdsp6/audioreach.c
> > +++ b/sound/soc/qcom/qdsp6/audioreach.c
> > @@ -306,22 +306,6 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
> > }
> > 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;
> > - }
> > -}
> > -EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
> > -
> while you at this, please remove AR_PCM_MAX_NUM_CHANNEL too.
Good idea,
Will reuse PCM_MAX_NUM_CHANNEL to replace AR_PCM_MAX_NUM_CHANNEL
>
> Other than that it looks good to me.
>
>
> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>
Thanks
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-26 8:25 [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
2026-10-27 8:46 ` Prasad Kumpatla
2026-10-27 13:47 ` Srinivas Kandagatla
@ 2026-10-28 2:47 ` Zhangfei Gao
2026-11-04 3:40 ` Shawn Guo
2026-11-10 7:59 ` Zhangfei Gao
2 siblings, 2 replies; 10+ messages in thread
From: Zhangfei Gao @ 2026-10-28 2:47 UTC (permalink / raw)
To: Mark Brown, Srinivas Kandagatla
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Krzysztof Kozlowski, shengchao.guo, mohammad.rafi.shaik,
bartosz.golaszewski, Prasad Kumpatla, Srinivas Kandagatla,
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.
This prevents TDM links that expose more channels, such as the 6-channel
playback path used on SA8797P Ride, from being configured.
Reuse q6dsp_map_channels() to support multichannel PCM formats and use
the common PCM channel limit definition.
Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
Reviewed-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
v3: reuse PCM_MAX_NUM_CHANNEL to replace AR_PCM_MAX_NUM_CHANNEL (Srinivas)
v2: reuse q6dsp_map_channels
sound/soc/qcom/qdsp6/audioreach.c | 36 ++++---------------------
sound/soc/qcom/qdsp6/audioreach.h | 5 ++--
sound/soc/qcom/qdsp6/q6apm-dai.c | 12 ++++++---
sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 11 +++++---
4 files changed, 24 insertions(+), 40 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index d2dc5d37bccf..e6f077a5b750 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -306,22 +306,6 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
}
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;
- }
-}
-EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
-
static void apm_populate_container_config(struct apm_container_obj *cfg,
const struct audioreach_container *cont)
{
@@ -760,7 +744,7 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
intf_cfg->cfg.intf_index = module->hw_interface_idx;
intf_cfg->cfg.active_channels_mask = 0;
/* Convert the physical channel mapping into a bit field */
- for (i = 0; i < AR_PCM_MAX_NUM_CHANNEL; i++)
+ for (i = 0; i < PCM_MAX_NUM_CHANNEL; i++)
if (cfg->channel_map[i])
intf_cfg->cfg.active_channels_mask |= BIT(i);
@@ -883,7 +867,7 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
media_format->bit_width = cfg->bit_width;
media_format->num_channels = cfg->num_channels;
/* Convert the physical mapping to a logical mapping of the channels */
- for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
+ for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
if (!cfg->channel_map[i])
continue;
media_format->channel_mapping[j++] = cfg->channel_map[i];
@@ -1185,11 +1169,6 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
int payload_size;
int i, j;
- if (num_channels > 4) {
- dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
- return -EINVAL;
- }
-
payload_size = APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels);
struct gpr_pkt *pkt __free(kfree) =
@@ -1218,7 +1197,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
media_cfg->q_factor = mcfg->bit_width - 1;
media_cfg->bits_per_sample = mcfg->bit_width;
/* Convert the physical mapping to a logical mapping of the channels */
- for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < mcfg->num_channels; i++) {
+ for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < mcfg->num_channels; i++) {
if (!mcfg->channel_map[i])
continue;
media_cfg->channel_mapping[j++] = mcfg->channel_map[i];
@@ -1275,11 +1254,6 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
int i, j;
void *p;
- if (num_channels > 4) {
- dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
- return -EINVAL;
- }
-
payload_size = APM_SHMEM_FMT_CFG_PSIZE(num_channels) + APM_MODULE_PARAM_DATA_SIZE;
struct gpr_pkt *pkt __free(kfree) =
@@ -1313,7 +1287,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
cfg->endianness = PCM_LITTLE_ENDIAN;
cfg->num_channels = mcfg->num_channels;
/* Convert the physical mapping to a logical mapping of the channels */
- for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
+ for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
if (!mcfg->channel_map[i])
continue;
cfg->channel_mapping[j++] = mcfg->channel_map[i];
@@ -1436,7 +1410,7 @@ static int audioreach_speaker_protection_vi(struct q6apm_graph *graph,
cm_cfg->cfg.num_channels = num_channels * 2;
/* Convert the physical mapping to a logical mapping of the channels */
- for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < num_channels; i++) {
+ for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < num_channels; i++) {
if (!mcfg->channel_map[i])
continue;
/*
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 587f14ce71d2..9f4166ebdc10 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -6,6 +6,7 @@
#include <linux/soc/qcom/apr.h>
#include <uapi/sound/snd_ar_tokens.h>
#include <sound/soc.h>
+#include "q6dsp-common.h"
struct q6apm;
struct q6apm_graph;
@@ -805,7 +806,6 @@ struct param_id_hw_ep_power_mode_cfg {
#define PARAM_ID_HW_EP_DMA_DATA_ALIGN 0x08001233
#define AR_HW_EP_DMA_DATA_ALIGN_MSB 0
#define AR_HW_EP_DMA_DATA_ALIGN_LSB 1
-#define AR_PCM_MAX_NUM_CHANNEL 8
struct param_id_hw_ep_dma_data_align {
uint32_t dma_data_align;
@@ -998,7 +998,7 @@ struct audioreach_module_config {
u16 nslots_per_frame;
u16 slot_width;
struct snd_codec codec;
- u8 channel_map[AR_PCM_MAX_NUM_CHANNEL];
+ u8 channel_map[PCM_MAX_NUM_CHANNEL];
};
/* Packet Allocation routines */
@@ -1009,7 +1009,6 @@ static inline u16 audioreach_gpr_dest_domain(gpr_device_t *gdev)
void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode,
uint32_t token);
-void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels);
void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode,
uint32_t token, uint32_t src_port,
uint32_t dest_port);
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 58beaf906b9f..83594b693569 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -21,6 +21,7 @@
#include <asm/div64.h>
#include <asm/dma.h>
#include "q6apm.h"
+#include "q6dsp-common.h"
#define DRV_NAME "q6apm-dai"
#define POS_BUFFER_BYTES 4096
@@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
cfg.num_channels = runtime->channels;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = SND_AUDIOCODEC_PCM;
- audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
+ ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
+ if (ret)
+ return ret;
+
if (prtd->state) {
/* clear the previous setup if any */
q6apm_graph_stop(prtd->graph);
@@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
cfg.num_channels = 2;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = codec->id;
- audioreach_set_default_channel_mapping(cfg.channel_map,
- cfg.num_channels);
+ ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
+ if (ret)
+ return ret;
+
memcpy(&cfg.codec, codec, sizeof(*codec));
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 83f2711bceea..9a3994a4f475 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -94,7 +94,7 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
return -EINVAL;
}
- if (tx_num > AR_PCM_MAX_NUM_CHANNEL) {
+ if (tx_num > PCM_MAX_NUM_CHANNEL) {
dev_err(dai->dev, "invalid tx num %d\n",
tx_num);
return -EINVAL;
@@ -147,7 +147,9 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
cfg->num_channels = channels;
- audioreach_set_default_channel_mapping(cfg->channel_map, channels);
+ ret = q6dsp_map_channels(cfg->channel_map, channels);
+ if (ret)
+ return ret;
switch (dai->id) {
case DISPLAY_PORT_RX_0:
@@ -173,11 +175,14 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
+ int ret;
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
cfg->num_channels = channels;
- audioreach_set_default_channel_mapping(cfg->channel_map, channels);
+ ret = q6dsp_map_channels(cfg->channel_map, channels);
+ if (ret)
+ return ret;
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-28 2:47 ` [PATCH v3] " Zhangfei Gao
@ 2026-11-04 3:40 ` Shawn Guo
2026-11-10 7:59 ` Zhangfei Gao
1 sibling, 0 replies; 10+ messages in thread
From: Shawn Guo @ 2026-11-04 3:40 UTC (permalink / raw)
To: Zhangfei Gao
Cc: Mark Brown, Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Krzysztof Kozlowski, mohammad.rafi.shaik,
bartosz.golaszewski, Prasad Kumpatla, Srinivas Kandagatla,
linux-sound, linux-arm-msm, linux-kernel
On Wed, Oct 28, 2026 at 10:47:20AM +0800, Zhangfei Gao wrote:
> AudioReach currently rejects PCM streams with more than four channels in
> the PCM and shared-memory media format paths.
>
> This prevents TDM links that expose more channels, such as the 6-channel
> playback path used on SA8797P Ride, from being configured.
>
> Reuse q6dsp_map_channels() to support multichannel PCM formats and use
> the common PCM channel limit definition.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
> Reviewed-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
On Nord Ride board:
Tested-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3] ASoC: qcom: audioreach: support multichannel PCM formats
2026-10-28 2:47 ` [PATCH v3] " Zhangfei Gao
2026-11-04 3:40 ` Shawn Guo
@ 2026-11-10 7:59 ` Zhangfei Gao
2026-11-10 12:11 ` Mark Brown
1 sibling, 1 reply; 10+ messages in thread
From: Zhangfei Gao @ 2026-11-10 7:59 UTC (permalink / raw)
To: Mark Brown, Srinivas Kandagatla
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Krzysztof Kozlowski, shengchao.guo, mohammad.rafi.shaik,
bartosz.golaszewski, Prasad Kumpatla, Srinivas Kandagatla,
linux-sound, linux-arm-msm, linux-kernel
On Wed, Oct 28, 2026 at 10:47 AM Zhangfei Gao
<zhangfei.gao@oss.qualcomm.com> wrote:
>
> AudioReach currently rejects PCM streams with more than four channels in
> the PCM and shared-memory media format paths.
>
> This prevents TDM links that expose more channels, such as the 6-channel
> playback path used on SA8797P Ride, from being configured.
>
> Reuse q6dsp_map_channels() to support multichannel PCM formats and use
> the common PCM channel limit definition.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>
> Reviewed-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> ---
>
> v3: reuse PCM_MAX_NUM_CHANNEL to replace AR_PCM_MAX_NUM_CHANNEL (Srinivas)
> v2: reuse q6dsp_map_channels
>
> sound/soc/qcom/qdsp6/audioreach.c | 36 ++++---------------------
> sound/soc/qcom/qdsp6/audioreach.h | 5 ++--
> sound/soc/qcom/qdsp6/q6apm-dai.c | 12 ++++++---
> sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 11 +++++---
> 4 files changed, 24 insertions(+), 40 deletions(-)
>
> diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
> index d2dc5d37bccf..e6f077a5b750 100644
> --- a/sound/soc/qcom/qdsp6/audioreach.c
> +++ b/sound/soc/qcom/qdsp6/audioreach.c
> @@ -306,22 +306,6 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
> }
> 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;
> - }
> -}
> -EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
> -
> static void apm_populate_container_config(struct apm_container_obj *cfg,
> const struct audioreach_container *cont)
> {
> @@ -760,7 +744,7 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
> intf_cfg->cfg.intf_index = module->hw_interface_idx;
> intf_cfg->cfg.active_channels_mask = 0;
> /* Convert the physical channel mapping into a bit field */
> - for (i = 0; i < AR_PCM_MAX_NUM_CHANNEL; i++)
> + for (i = 0; i < PCM_MAX_NUM_CHANNEL; i++)
> if (cfg->channel_map[i])
> intf_cfg->cfg.active_channels_mask |= BIT(i);
>
> @@ -883,7 +867,7 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
> media_format->bit_width = cfg->bit_width;
> media_format->num_channels = cfg->num_channels;
> /* Convert the physical mapping to a logical mapping of the channels */
> - for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> + for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> if (!cfg->channel_map[i])
> continue;
> media_format->channel_mapping[j++] = cfg->channel_map[i];
> @@ -1185,11 +1169,6 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
> int payload_size;
> int i, j;
>
> - if (num_channels > 4) {
> - dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
> - return -EINVAL;
> - }
> -
> payload_size = APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels);
>
> struct gpr_pkt *pkt __free(kfree) =
> @@ -1218,7 +1197,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
> media_cfg->q_factor = mcfg->bit_width - 1;
> media_cfg->bits_per_sample = mcfg->bit_width;
> /* Convert the physical mapping to a logical mapping of the channels */
> - for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < mcfg->num_channels; i++) {
> + for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < mcfg->num_channels; i++) {
> if (!mcfg->channel_map[i])
> continue;
> media_cfg->channel_mapping[j++] = mcfg->channel_map[i];
> @@ -1275,11 +1254,6 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
> int i, j;
> void *p;
>
> - if (num_channels > 4) {
> - dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
> - return -EINVAL;
> - }
> -
> payload_size = APM_SHMEM_FMT_CFG_PSIZE(num_channels) + APM_MODULE_PARAM_DATA_SIZE;
>
> struct gpr_pkt *pkt __free(kfree) =
> @@ -1313,7 +1287,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
> cfg->endianness = PCM_LITTLE_ENDIAN;
> cfg->num_channels = mcfg->num_channels;
> /* Convert the physical mapping to a logical mapping of the channels */
> - for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> + for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> if (!mcfg->channel_map[i])
> continue;
> cfg->channel_mapping[j++] = mcfg->channel_map[i];
> @@ -1436,7 +1410,7 @@ static int audioreach_speaker_protection_vi(struct q6apm_graph *graph,
>
> cm_cfg->cfg.num_channels = num_channels * 2;
> /* Convert the physical mapping to a logical mapping of the channels */
> - for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < num_channels; i++) {
> + for (i = 0, j = 0; i < PCM_MAX_NUM_CHANNEL && j < num_channels; i++) {
> if (!mcfg->channel_map[i])
> continue;
> /*
> diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
> index 587f14ce71d2..9f4166ebdc10 100644
> --- a/sound/soc/qcom/qdsp6/audioreach.h
> +++ b/sound/soc/qcom/qdsp6/audioreach.h
> @@ -6,6 +6,7 @@
> #include <linux/soc/qcom/apr.h>
> #include <uapi/sound/snd_ar_tokens.h>
> #include <sound/soc.h>
> +#include "q6dsp-common.h"
> struct q6apm;
> struct q6apm_graph;
>
> @@ -805,7 +806,6 @@ struct param_id_hw_ep_power_mode_cfg {
> #define PARAM_ID_HW_EP_DMA_DATA_ALIGN 0x08001233
> #define AR_HW_EP_DMA_DATA_ALIGN_MSB 0
> #define AR_HW_EP_DMA_DATA_ALIGN_LSB 1
> -#define AR_PCM_MAX_NUM_CHANNEL 8
>
> struct param_id_hw_ep_dma_data_align {
> uint32_t dma_data_align;
> @@ -998,7 +998,7 @@ struct audioreach_module_config {
> u16 nslots_per_frame;
> u16 slot_width;
> struct snd_codec codec;
> - u8 channel_map[AR_PCM_MAX_NUM_CHANNEL];
> + u8 channel_map[PCM_MAX_NUM_CHANNEL];
> };
>
> /* Packet Allocation routines */
> @@ -1009,7 +1009,6 @@ static inline u16 audioreach_gpr_dest_domain(gpr_device_t *gdev)
>
> void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode,
> uint32_t token);
> -void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels);
> void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode,
> uint32_t token, uint32_t src_port,
> uint32_t dest_port);
> diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
> index 58beaf906b9f..83594b693569 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-dai.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
> @@ -21,6 +21,7 @@
> #include <asm/div64.h>
> #include <asm/dma.h>
> #include "q6apm.h"
> +#include "q6dsp-common.h"
>
> #define DRV_NAME "q6apm-dai"
> #define POS_BUFFER_BYTES 4096
> @@ -344,7 +345,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
> cfg.num_channels = runtime->channels;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = SND_AUDIOCODEC_PCM;
> - audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
> + ret = q6dsp_map_channels(cfg.channel_map, runtime->channels);
> + if (ret)
> + return ret;
> +
> if (prtd->state) {
> /* clear the previous setup if any */
> q6apm_graph_stop(prtd->graph);
> @@ -1007,8 +1011,10 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
> cfg.num_channels = 2;
> cfg.bit_width = prtd->bits_per_sample;
> cfg.fmt = codec->id;
> - audioreach_set_default_channel_mapping(cfg.channel_map,
> - cfg.num_channels);
> + ret = q6dsp_map_channels(cfg.channel_map, cfg.num_channels);
> + if (ret)
> + return ret;
> +
> memcpy(&cfg.codec, codec, sizeof(*codec));
>
> ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
> diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> index 83f2711bceea..9a3994a4f475 100644
> --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
> @@ -94,7 +94,7 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
> return -EINVAL;
> }
>
> - if (tx_num > AR_PCM_MAX_NUM_CHANNEL) {
> + if (tx_num > PCM_MAX_NUM_CHANNEL) {
> dev_err(dai->dev, "invalid tx num %d\n",
> tx_num);
> return -EINVAL;
> @@ -147,7 +147,9 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> switch (dai->id) {
> case DISPLAY_PORT_RX_0:
> @@ -173,11 +175,14 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
> struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
> struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
> int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
> + int ret;
>
> cfg->bit_width = params_width(params);
> cfg->sample_rate = params_rate(params);
> cfg->num_channels = channels;
> - audioreach_set_default_channel_mapping(cfg->channel_map, channels);
> + ret = q6dsp_map_channels(cfg->channel_map, channels);
> + if (ret)
> + return ret;
>
> return 0;
> }
> --
> 2.43.0
>
Hi, Mark
Any comments of this patch?
Thanks
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3] ASoC: qcom: audioreach: support multichannel PCM formats
2026-11-10 7:59 ` Zhangfei Gao
@ 2026-11-10 12:11 ` Mark Brown
0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2026-11-10 12:11 UTC (permalink / raw)
To: Zhangfei Gao
Cc: Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Krzysztof Kozlowski, shengchao.guo,
mohammad.rafi.shaik, bartosz.golaszewski, Prasad Kumpatla,
Srinivas Kandagatla, linux-sound, linux-arm-msm, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1282 bytes --]
On Tue, Nov 10, 2026 at 03:59:44PM +0800, Zhangfei Gao wrote:
> On Wed, Oct 28, 2026 at 10:47 AM Zhangfei Gao
> <zhangfei.gao@oss.qualcomm.com> wrote:
> >
> > AudioReach currently rejects PCM streams with more than four channels in
> > the PCM and shared-memory media format paths.
Please don't send content free pings and please allow a reasonable time
for review. People get busy, go on holiday, attend conferences and so
on so unless there is some reason for urgency (like critical bug fixes)
please allow at least a couple of weeks for review. If there have been
review comments then people may be waiting for those to be addressed.
Sending content free pings adds to the mail volume (if they are seen at
all) which is often the problem and since they can't be reviewed
directly if something has gone wrong you'll have to resend the patches
anyway, so sending again is generally a better approach though there are
some other maintainers who like them - if in doubt look at how patches
for the subsystem are normally handled.
Please delete unneeded context from mails when replying. Doing this
makes it much easier to find your reply in the message, helping ensure
it won't be missed by people scrolling through the irrelevant quoted
material.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-11-10 12:11 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 8:25 [PATCH v2] ASoC: qcom: audioreach: support multichannel PCM formats Zhangfei Gao
2026-10-27 8:46 ` Prasad Kumpatla
2026-10-27 9:55 ` Zhangfei Gao
2026-10-27 11:45 ` Prasad Kumpatla
2026-10-27 13:47 ` Srinivas Kandagatla
2026-10-28 2:40 ` Zhangfei Gao
2026-10-28 2:47 ` [PATCH v3] " Zhangfei Gao
2026-11-04 3:40 ` Shawn Guo
2026-11-10 7:59 ` Zhangfei Gao
2026-11-10 12:11 ` Mark Brown
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®