From 7efca5cc14ed8d3886edc617af19641b251789e6 Mon Sep 17 00:00:00 2001 From: Hongtao Peng Date: Thu, 24 Feb 2022 00:05:54 +0800 Subject: [PATCH] ASoC: msm: support multi group matrix mixer configure for SSMD mode SSMD mode need to map one ASM session to multiple devices Need to configure all Matrix Mixer map for each device. Change-Id: I149a2f91561a99539cfbd16f1dbfe4c973976575 Signed-off-by: Hongtao Peng --- asoc/msm-pcm-routing-v2.c | 148 +++++++++++++++++++++++++------------- asoc/msm-pcm-routing-v2.h | 8 +++ 2 files changed, 106 insertions(+), 50 deletions(-) mode change 100644 => 100755 asoc/msm-pcm-routing-v2.c diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c old mode 100644 new mode 100755 index 5b7fc20a08e4..5c1c6b7bad44 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -105,8 +105,7 @@ static struct msm_ec_ref_port_cfg ec_ref_port_cfg; static struct msm_pcm_channel_mixer channel_mixer[MSM_FRONTEND_DAI_MM_SIZE]; /* all the FES which can support channel mixer for bidirection */ -static struct msm_pcm_channel_mixer - channel_mixer_v2[MSM_FRONTEND_DAI_MM_SIZE][2]; +static struct msm_pcm_channel_mixer_v2 channel_mixer_v2[MT_MX_MAX_PORTS]; /* input BE for each FE */ static int channel_input[MSM_FRONTEND_DAI_MM_SIZE][ADM_MAX_CHANNELS]; @@ -1308,6 +1307,38 @@ static int get_copp_perf_mode(int fe_id, int sess_type, int port) return rc; } +static int get_available_chmixer_index(int fe_id, int sess_type, int be_id) +{ + int index = 0; + bool need_research = true; + + /* + * If there is a item that have the same fe_id sess_type and be_id + * with input, use the index of this item and update it. + */ + for (index = 0; index < MT_MX_MAX_PORTS; index++) { + if ((channel_mixer_v2[index].fedai_id == fe_id) && + (channel_mixer_v2[index].session_type == sess_type) && + (channel_mixer_v2[index].be_id == be_id)) { + need_research = false; + break; + } + } + + /* + * If the item with fe_id sess_type and be_id is not exist, + * find an new unused item + */ + if (need_research) { + for (index = 0; index < MT_MX_MAX_PORTS; index++) { + if (!channel_mixer_v2[index].is_used) + break; + } + } + + return index; +} + /* * msm_pcm_routing_send_chmix_cfg: * send the channel mixer command to mix the input channels @@ -1385,31 +1416,46 @@ int msm_pcm_routing_set_channel_mixer_cfg( int fe_id, int type, struct msm_pcm_channel_mixer *params) { - int i, j = 0; + int i, j, index = 0; + int be_id = params->port_idx - 1; - channel_mixer_v2[fe_id][type].enable = params->enable; - channel_mixer_v2[fe_id][type].rule = params->rule; - channel_mixer_v2[fe_id][type].input_channel = + index = get_available_chmixer_index(fe_id, type, be_id); + if (index >= MT_MX_MAX_PORTS) { + pr_err("%s: Set channel mixer configure Fail!\n", __func__); + return -EINVAL; + } + + memset(&channel_mixer_v2[index], 0, + sizeof(struct msm_pcm_channel_mixer_v2)); + channel_mixer_v2[index].is_used = true; + channel_mixer_v2[index].fedai_id = fe_id; + channel_mixer_v2[index].session_type = type; + channel_mixer_v2[index].be_id = be_id; + channel_mixer_v2[index].mixer_cfg.port_idx = params->port_idx; + channel_mixer_v2[index].mixer_cfg.enable = params->enable; + channel_mixer_v2[index].mixer_cfg.rule = params->rule; + channel_mixer_v2[index].mixer_cfg.input_channel = params->input_channel; - channel_mixer_v2[fe_id][type].output_channel = + channel_mixer_v2[index].mixer_cfg.output_channel = params->output_channel; - channel_mixer_v2[fe_id][type].port_idx = params->port_idx; + channel_mixer_v2[index].mixer_cfg.input_channels[0] = + params->input_channel; for (i = 0; i < ADM_MAX_CHANNELS; i++) - channel_mixer_v2[fe_id][type].in_ch_map[i] = + channel_mixer_v2[index].mixer_cfg.in_ch_map[i] = params->in_ch_map[i]; for (i = 0; i < ADM_MAX_CHANNELS; i++) - channel_mixer_v2[fe_id][type].out_ch_map[i] = + channel_mixer_v2[index].mixer_cfg.out_ch_map[i] = params->out_ch_map[i]; for (i = 0; i < ADM_MAX_CHANNELS; i++) for (j = 0; j < ADM_MAX_CHANNELS; j++) - channel_mixer_v2[fe_id][type].channel_weight[i][j] = + channel_mixer_v2[index].mixer_cfg.channel_weight[i][j] = params->channel_weight[i][j]; - channel_mixer_v2[fe_id][type].override_in_ch_map = + channel_mixer_v2[index].mixer_cfg.override_in_ch_map = params->override_in_ch_map; - channel_mixer_v2[fe_id][type].override_out_ch_map = + channel_mixer_v2[index].mixer_cfg.override_out_ch_map = params->override_out_ch_map; return 0; @@ -2134,9 +2180,10 @@ static u32 msm_pcm_routing_get_voc_sessionid(u16 val) static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, int dspst_id, int stream_type) { + struct msm_pcm_channel_mixer *mixer_config; int copp_idx = 0; int sess_type = 0; - int j = 0, be_id = 0; + int i = 0, j = 0, be_id = 0; int ret = 0; if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { @@ -2149,44 +2196,45 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, else sess_type = SESSION_TYPE_TX; - if (!(channel_mixer_v2[fe_id][sess_type].enable)) { - pr_debug("%s: channel mixer not enabled for FE %d direction %d\n", - __func__, fe_id, sess_type); - return 0; - } - - be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; - if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { - pr_err("%s: Received out of bounds be_id %d\n", - __func__, be_id); - return -EINVAL; - } - channel_mixer_v2[fe_id][sess_type].input_channels[0] = - channel_mixer_v2[fe_id][sess_type].input_channel; - - pr_debug("%s sess type %d,fe_id %d,override in:%d out:%d,be active %d\n", - __func__, sess_type, fe_id, - channel_mixer_v2[fe_id][sess_type].override_in_ch_map, - channel_mixer_v2[fe_id][sess_type].override_out_ch_map, - msm_bedais[be_id].active); - - if ((msm_bedais[be_id].active) && - test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) { - unsigned long copp = - session_copp_map[fe_id][sess_type][be_id]; - for (j = 0; j < MAX_COPPS_PER_PORT; j++) { - if (test_bit(j, &copp)) { - copp_idx = j; - break; + for (i = 0; i < MT_MX_MAX_PORTS; i++) { + if ((channel_mixer_v2[i].fedai_id == fe_id) && + (channel_mixer_v2[i].session_type == sess_type)) { + if ((!channel_mixer_v2[i].mixer_cfg.enable) || + !(channel_mixer_v2[i].is_used)) { + pr_debug("%s: channel mixer not enabled for FE %d direction %d\n", + __func__, fe_id, sess_type); + continue; + } + be_id = channel_mixer_v2[i].be_id; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + return -EINVAL; + } + mixer_config = &channel_mixer_v2[i].mixer_cfg; + pr_debug("%s sess type %d,fe_id %d,override in:%d out:%d,be active %d\n", + __func__, sess_type, fe_id, + mixer_config->override_in_ch_map, + mixer_config->override_out_ch_map, + msm_bedais[be_id].active); + if ((msm_bedais[be_id].active) && + test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) { + unsigned long copp = + session_copp_map[fe_id][sess_type][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (test_bit(j, &copp)) { + copp_idx = j; + break; + } + } + ret = adm_programable_channel_mixer( + msm_bedais[be_id].port_id, + copp_idx, dspst_id, sess_type, + mixer_config, 0); + channel_mixer_v2[i].is_used = false; + } } - } - - ret = adm_programable_channel_mixer( - msm_bedais[be_id].port_id, - copp_idx, dspst_id, sess_type, - &channel_mixer_v2[fe_id][sess_type], 0); } - return ret; } diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 4a8e4b6eda58..583189b93371 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -688,6 +688,7 @@ enum { #define STREAM_TYPE_ASM 0 #define STREAM_TYPE_LSM 1 +#define MT_MX_MAX_PORTS 64 #define PP_PERF_MODE_FLAG_MASK 0x10000 #define PP_PERF_MODE_VALUE_MASK 0xF @@ -749,6 +750,13 @@ struct msm_pcm_stream_app_type_cfg { int copp_perf_mode; }; +struct msm_pcm_channel_mixer_v2 { + struct msm_pcm_channel_mixer mixer_cfg; + int fedai_id; + int session_type; + int be_id; + bool is_used; +}; /* dai_id: front-end ID, * dspst_id: DSP audio stream ID * stream_type: playback or capture