Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44a34d8c authored by Hexuan Zhu's avatar Hexuan Zhu
Browse files

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: default avatarHexuan Zhu <hexuzhu@codeaurora.org>
parent e2c2fd50
Loading
Loading
Loading
Loading
+58 −22
Original line number Diff line number Diff line
@@ -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) {
		if (rtd && component) {
			fe_id = rtd->dai_link->id;
			chmixer_pspd = pdata ?
					pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL;
				pdata->chmixer_pspd[fe_id][session_type] : NULL;

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