mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
asoc: fix chmixer for playback and record
If we want to make chmixer work, chmixer input map should be the same as asm output map, output map should be the same as adm input map. and need to reverse when record. Currently if we set chmixer input map under pre-run, the override flags are not set true, and also default branch didn't work when record. Also chmixer didn't support customer value for record during run-time. This change make chmixer take effect when playback and record for both default value and customer value during pre-run and run-time. Change-Id: I3d1455092d41fa6a30c3ddf09c3b0b3023d9cc10 Signed-off-by: Hexuan Zhu <hexuzhu@codeaurora.org>
This commit is contained in:
parent
e2c2fd507c
commit
44a34d8c47
1 changed files with 58 additions and 22 deletions
|
|
@ -1870,6 +1870,8 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
struct msm_pcm_channel_map *chmap;
|
||||
u64 fe_id = kcontrol->private_value & 0xFF;
|
||||
int session_type = (kcontrol->private_value >> 8) & 0xFF;
|
||||
bool reset_override_out_ch_map = false;
|
||||
bool reset_override_in_ch_map = false;
|
||||
|
||||
pr_debug("%s: chmap ctl for fe_id: %d, session_type: %d\n",
|
||||
__func__, fe_id, session_type);
|
||||
|
|
@ -1922,20 +1924,33 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
(char)(ucontrol->value.integer.value[i]);
|
||||
|
||||
/* update chmixer_pspd chmap cached with routing driver as well */
|
||||
if (rtd) {
|
||||
if (component) {
|
||||
fe_id = rtd->dai_link->id;
|
||||
chmixer_pspd = pdata ?
|
||||
pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL;
|
||||
if (rtd && component) {
|
||||
fe_id = rtd->dai_link->id;
|
||||
chmixer_pspd = pdata ?
|
||||
pdata->chmixer_pspd[fe_id][session_type] : NULL;
|
||||
|
||||
if (chmixer_pspd && chmixer_pspd->enable) {
|
||||
if (chmixer_pspd && chmixer_pspd->enable) {
|
||||
if (session_type == SESSION_TYPE_RX &&
|
||||
!chmixer_pspd->override_in_ch_map) {
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->in_ch_map[i] = prtd->channel_map[i];
|
||||
chmixer_pspd->override_in_ch_map = true;
|
||||
msm_pcm_routing_set_channel_mixer_cfg(fe_id,
|
||||
SESSION_TYPE_RX, chmixer_pspd);
|
||||
reset_override_in_ch_map = true;
|
||||
} else if (session_type == SESSION_TYPE_TX &&
|
||||
!chmixer_pspd->override_out_ch_map) {
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->out_ch_map[i] = prtd->channel_map[i];
|
||||
chmixer_pspd->override_out_ch_map = true;
|
||||
reset_override_out_ch_map = true;
|
||||
}
|
||||
msm_pcm_routing_set_channel_mixer_cfg(fe_id,
|
||||
session_type, chmixer_pspd);
|
||||
if (reset_override_out_ch_map)
|
||||
chmixer_pspd->override_out_ch_map = false;
|
||||
if (reset_override_in_ch_map)
|
||||
chmixer_pspd->override_in_ch_map = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
|
@ -2264,6 +2279,7 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
struct snd_pcm *pcm = NULL;
|
||||
struct snd_pcm_substream *substream = NULL;
|
||||
struct msm_pcm_channel_mixer *chmixer_pspd = NULL;
|
||||
struct msm_pcm_channel_map *chmap = NULL;
|
||||
u8 asm_ch_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0};
|
||||
bool reset_override_out_ch_map = false;
|
||||
bool reset_override_in_ch_map = false;
|
||||
|
|
@ -2314,15 +2330,28 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
return -EINVAL;
|
||||
}
|
||||
prtd = substream->runtime ? substream->runtime->private_data : NULL;
|
||||
if (chmixer_pspd->enable && prtd) {
|
||||
chmap = msm_pcm_get_chmap(fe_id, session_type);
|
||||
if (!chmap) {
|
||||
pr_err("%s: invalid chmap handle\n", __func__);
|
||||
mutex_unlock(&pdata->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chmixer_pspd->enable) {
|
||||
if (session_type == SESSION_TYPE_RX &&
|
||||
!chmixer_pspd->override_in_ch_map) {
|
||||
if (prtd->set_channel_map) {
|
||||
if (chmap->set_channel_map) {
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->in_ch_map[i] = prtd->channel_map[i];
|
||||
chmixer_pspd->in_ch_map[i] = chmap->channel_map[i];
|
||||
} else {
|
||||
q6asm_map_channels(asm_ch_map,
|
||||
chmixer_pspd->input_channel, false);
|
||||
ret = q6asm_map_channels(asm_ch_map,
|
||||
chmixer_pspd->input_channel, false);
|
||||
if (ret) {
|
||||
pr_err("%s: unsupported chnum %d\n", __func__,
|
||||
chmixer_pspd->input_channel);
|
||||
mutex_unlock(&pdata->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->in_ch_map[i] = asm_ch_map[i];
|
||||
}
|
||||
|
|
@ -2330,14 +2359,21 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
reset_override_in_ch_map = true;
|
||||
} else if (session_type == SESSION_TYPE_TX &&
|
||||
!chmixer_pspd->override_out_ch_map) {
|
||||
/*
|
||||
* Channel map set in prtd is for plyback only,
|
||||
* hence always use default for capture path.
|
||||
*/
|
||||
q6asm_map_channels(asm_ch_map,
|
||||
chmixer_pspd->output_channel, false);
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
|
||||
if (chmap->set_channel_map) {
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->out_ch_map[i] = chmap->channel_map[i];
|
||||
} else {
|
||||
ret = q6asm_map_channels(asm_ch_map,
|
||||
chmixer_pspd->output_channel, false);
|
||||
if (ret) {
|
||||
pr_err("%s: unsupported chnum %d\n", __func__,
|
||||
chmixer_pspd->output_channel);
|
||||
mutex_unlock(&pdata->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
|
||||
}
|
||||
chmixer_pspd->override_out_ch_map = true;
|
||||
reset_override_out_ch_map = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue