Merge "ASoC: msm: support multi group matrix mixer configure for SSMD mode"

This commit is contained in:
qctecmdr 2022-03-29 10:47:12 -07:00 committed by Gerrit - the friendly Code Review server
commit 4019a3da22
2 changed files with 106 additions and 50 deletions

102
asoc/msm-pcm-routing-v2.c Normal file → Executable file
View File

@ -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,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 =
@ -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;
}

View File

@ -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