diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c old mode 100644 new mode 100755 index 16b29cc70219..48c0cbe15108 --- 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]; @@ -1383,6 +1382,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 @@ -1460,31 +1491,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; @@ -2209,9 +2255,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) { @@ -2224,44 +2271,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 6414d959eb95..0ce5e1d73cdb 100755 --- 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