Loading asoc/msm-pcm-routing-v2.c 100644 → 100755 +98 −50 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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 Loading Loading @@ -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; 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; } 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 = 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; Loading Loading @@ -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) { Loading @@ -2224,27 +2271,27 @@ 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)) { 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); return 0; continue; } be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; 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; } channel_mixer_v2[fe_id][sess_type].input_channels[0] = channel_mixer_v2[fe_id][sess_type].input_channel; 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, channel_mixer_v2[fe_id][sess_type].override_in_ch_map, channel_mixer_v2[fe_id][sess_type].override_out_ch_map, 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 = Loading @@ -2255,13 +2302,14 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, break; } } 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); mixer_config, 0); channel_mixer_v2[i].is_used = false; } } } return ret; } asoc/msm-pcm-routing-v2.h +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading
asoc/msm-pcm-routing-v2.c 100644 → 100755 +98 −50 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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 Loading Loading @@ -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; 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; } 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 = 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; Loading Loading @@ -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) { Loading @@ -2224,27 +2271,27 @@ 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)) { 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); return 0; continue; } be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; 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; } channel_mixer_v2[fe_id][sess_type].input_channels[0] = channel_mixer_v2[fe_id][sess_type].input_channel; 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, channel_mixer_v2[fe_id][sess_type].override_in_ch_map, channel_mixer_v2[fe_id][sess_type].override_out_ch_map, 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 = Loading @@ -2255,13 +2302,14 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, break; } } 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); mixer_config, 0); channel_mixer_v2[i].is_used = false; } } } return ret; }
asoc/msm-pcm-routing-v2.h +8 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading