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