diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..758215b86e5a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24531,6 +24531,33 @@ static const struct snd_kcontrol_new aptx_dec_license_controls[] = { msm_aptx_dec_license_control_put), }; +static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint8_t channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; + uint32_t be_idx = ucontrol->value.integer.value[0]; + int i; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { + channel_map[i] = (char)(ucontrol->value.integer.value[i + 1]); + if (channel_map[i] > PCM_MAX_CHMAP_ID) { + pr_err("%s: Invalid channel map %d\n", + __func__, channel_map[i]); + return -EINVAL; + } + } + adm_set_port_multi_ch_map(channel_map, msm_bedais[be_idx].port_id); + + return 0; +} + +static const struct snd_kcontrol_new port_multi_channel_map_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("Backend Device Channel Map", SND_SOC_NOPM, 0, + MSM_BACKEND_DAI_MAX, 0, + PCM_FORMAT_MAX_NUM_CHANNEL_V8 + 1, NULL, + msm_routing_put_port_chmap_mixer), +}; + static int msm_routing_be_dai_name_table_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -24769,6 +24796,9 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls( component, msm_routing_feature_support_mixer_controls, ARRAY_SIZE(msm_routing_feature_support_mixer_controls)); + snd_soc_add_component_controls(component, + port_multi_channel_map_mixer_controls, + ARRAY_SIZE(port_multi_channel_map_mixer_controls)); return 0; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e7c132a69587..2167350b34cf 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -5569,12 +5569,17 @@ struct asm_softvolume_params { /* Left side direct channel. */ #define PCM_CHANNEL_LSD 33 -/* Right side direct channel. */ +/* Right side direct channel. Update PCM_MAX_CHMAP_ID when + * this list is extended. + */ #define PCM_CHANNEL_RSD 34 /* Mark unused channel. */ #define PCM_CHANNEL_UNUSED 47 +/* Max valid channel map index */ +#define PCM_MAX_CHMAP_ID PCM_CHANNEL_RSD + #define PCM_FORMAT_MAX_NUM_CHANNEL 8 #define PCM_FORMAT_MAX_CHANNELS_9 9