[PATCH 3/4] ASoC: qcom: q6dsp: Set channel mapping instead of fixed defaults

From: Krzysztof Kozlowski
Date: Tue May 07 2024 - 06:28:52 EST


Use previously set channel mapping instead of defaults when preparing
frontent Q6APM component. This allows machine sound card drivers to
override channel mappings.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx>
---
sound/soc/qcom/qdsp6/audioreach.c | 14 +++++---------
sound/soc/qcom/qdsp6/audioreach.h | 2 +-
sound/soc/qcom/qdsp6/q6apm-dai.c | 12 ++++++++++++
sound/soc/qcom/qdsp6/q6apm.c | 2 +-
4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 8175678d8843..83b33e4c9de2 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -267,7 +267,7 @@ 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_channel_mapping(u8 *ch_map, int num_channels)
+void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
{
if (num_channels == 1) {
ch_map[0] = PCM_CHANNEL_FL;
@@ -884,8 +884,8 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
mp3_cfg->endianness = PCM_LITTLE_ENDIAN;
mp3_cfg->num_channels = mcfg->num_channels;

- audioreach_set_channel_mapping(mp3_cfg->channel_mapping,
- mcfg->num_channels);
+ audioreach_set_default_channel_mapping(mp3_cfg->channel_mapping,
+ mcfg->num_channels);
break;
case SND_AUDIOCODEC_AAC:
media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
@@ -1104,9 +1104,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
media_cfg->num_channels = mcfg->num_channels;
media_cfg->q_factor = mcfg->bit_width - 1;
media_cfg->bits_per_sample = mcfg->bit_width;
-
- audioreach_set_channel_mapping(media_cfg->channel_mapping,
- num_channels);
+ memcpy(media_cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);

rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);

@@ -1163,9 +1161,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
cfg->q_factor = mcfg->bit_width - 1;
cfg->endianness = PCM_LITTLE_ENDIAN;
cfg->num_channels = mcfg->num_channels;
-
- audioreach_set_channel_mapping(cfg->channel_mapping,
- num_channels);
+ memcpy(cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
} else {
rc = audioreach_set_compr_media_format(header, p, mcfg);
if (rc) {
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index cef9a9015dcc..6ae95eb85118 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -767,7 +767,7 @@ struct audioreach_module_config {
/* Packet Allocation routines */
void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t
token);
-void audioreach_set_channel_mapping(u8 *ch_map, int num_channels);
+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 00bbd291be5c..5dfbd011bb97 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -8,6 +8,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
+#include <sound/soc-dai.h>
#include <sound/soc-dapm.h>
#include <linux/spinlock.h>
#include <sound/pcm.h>
@@ -223,7 +224,10 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0);
struct q6apm_dai_rtd *prtd = runtime->private_data;
+ struct q6apm *apm = prtd->graph->apm;
struct audioreach_module_config cfg;
struct device *dev = component->dev;
struct q6apm_dai_data *pdata;
@@ -238,9 +242,17 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
return -EINVAL;
}

+ if (cpu_dai->id >= ARRAY_SIZE(apm->dai_config)) {
+ dev_err(dev, "Unsupported DAI ID number %d (%s)\n",
+ cpu_dai->id, cpu_dai->name);
+ return -EINVAL;
+ }
+
cfg.direction = substream->stream;
cfg.sample_rate = runtime->rate;
cfg.num_channels = runtime->channels;
+ memcpy(cfg.channel_map, apm->dai_config[cpu_dai->id].channel_map,
+ runtime->channels);
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = SND_AUDIOCODEC_PCM;

diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index c29a2dd36992..f6fa15f42633 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -758,7 +758,7 @@ static int apm_probe(gpr_device_t *gdev)
apm->dev = dev;
apm->gdev = gdev;
for (i = 0; i < ARRAY_SIZE(apm->dai_config); i++)
- audioreach_set_channel_mapping(apm->dai_config[i].channel_map, 4);
+ audioreach_set_default_channel_mapping(apm->dai_config[i].channel_map, 4);
init_waitqueue_head(&apm->wait);

INIT_LIST_HEAD(&apm->widget_list);

--
2.43.0