mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
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 <quic_hongtaop@quicinc.com>
This commit is contained in:
parent
dd9977f073
commit
7efca5cc14
2 changed files with 106 additions and 50 deletions
148
asoc/msm-pcm-routing-v2.c
Normal file → Executable file
148
asoc/msm-pcm-routing-v2.c
Normal file → Executable 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];
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue