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

Commit ae9190ed authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: enable TTP generator"

parents d5f64568 b50f4233
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
				     int stream_id);

static int msm_compr_set_render_mode(struct msm_compr_audio *prtd,
				     uint32_t render_mode) {
				     uint32_t render_mode, int dir) {
	int ret = -EINVAL;
	struct audio_client *ac = prtd->audio_client;

@@ -250,7 +250,7 @@ static int msm_compr_set_render_mode(struct msm_compr_audio *prtd,
		goto exit;
	}

	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
	if (ret) {
		pr_err("%s, Render mode can't be set error %d\n", __func__,
			ret);
@@ -324,6 +324,29 @@ static int msm_compr_set_render_window(struct audio_client *ac,
	return ret;
}

static int msm_compr_set_ttp_offset(struct audio_client *ac,
		uint32_t offset_lsw, uint32_t offset_msw, int dir)
{
	int ret = -EINVAL;
	struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset;
	uint32_t param_id;

	pr_debug("%s, ttp offset lsw 0x%x  ttp offset msw 0x%x\n",
		 __func__, offset_lsw, offset_msw);

	memset(&ttp_offset, 0,
	       sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));
	ttp_offset.ttp_offset_lsw = offset_lsw;
	ttp_offset.ttp_offset_msw = offset_msw;
	param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET;
	ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir);
	if (ret)
		pr_err("%s, ttp offset can't be set error %d\n", __func__,
			ret);

	return ret;
}

static int msm_compr_enable_adjust_session_clock(struct audio_client *ac,
		bool enable)
{
@@ -3221,7 +3244,8 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream,
			 __func__, metadata->value[0]);
		prtd->gapless_state.initial_samples_drop = metadata->value[0];
	} else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) {
		return msm_compr_set_render_mode(prtd, metadata->value[0]);
		return msm_compr_set_render_mode(prtd, metadata->value[0],
				cstream->direction);
	} else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) {
		return msm_compr_set_clk_rec_mode(ac, metadata->value[0]);
	} else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) {
@@ -3242,6 +3266,9 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream,
		return msm_compr_adjust_session_clock(ac,
				metadata->value[0],
				metadata->value[1]);
	} else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) {
		return msm_compr_set_ttp_offset(ac, metadata->value[0],
				metadata->value[1], cstream->direction);
	}

	return 0;
+135 −7
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ struct msm_dai_q6_dai_data {
	u16 afe_tx_out_bitformat;
	struct afe_enc_config enc_config;
	struct afe_dec_config dec_config;
	struct afe_ttp_config ttp_config;
	union afe_port_config port_config;
	u16 vi_feed_mono;
	u32 xt_logging_disable;
@@ -2230,6 +2231,7 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
{
	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
	int rc = 0;
	uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable;

	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
		if (dai_data->enc_config.format != ENC_FMT_NONE) {
@@ -2279,13 +2281,27 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
				bitwidth = 0;
				break;
			}

			if (ttp_gen_enable == true) {
				pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n",
					 __func__, dai_data->dec_config.format);
				rc = afe_port_start_v3(dai->id,
						&dai_data->port_config,
						dai_data->rate,
						dai_data->afe_tx_out_channels,
						bitwidth,
						NULL, &dai_data->dec_config,
						&dai_data->ttp_config);
			} else {
				pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n",
					 __func__, dai_data->dec_config.format);
			rc = afe_port_start_v2(dai->id, &dai_data->port_config,
				rc = afe_port_start_v2(dai->id,
						&dai_data->port_config,
						dai_data->rate,
						dai_data->afe_tx_out_channels,
						bitwidth,
						NULL, &dai_data->dec_config);
			}
			if (rc < 0) {
				pr_err("%s: fail to open AFE port 0x%x\n",
					__func__, dai->id);
@@ -3669,6 +3685,91 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol,
	return ret;
}

static int  msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = sizeof(struct afe_ttp_gen_enable_t);

	return 0;
}

static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	pr_debug("%s:\n", __func__);
	if (!dai_data) {
		pr_err("%s: Invalid dai data\n", __func__);
		return -EINVAL;
	}

	memcpy(ucontrol->value.bytes.data,
	       &dai_data->ttp_config.ttp_gen_enable,
	       sizeof(struct afe_ttp_gen_enable_t));
	return 0;
}

static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	pr_debug("%s:\n", __func__);
	if (!dai_data) {
		pr_err("%s: Invalid dai data\n", __func__);
		return -EINVAL;
	}

	memcpy(&dai_data->ttp_config.ttp_gen_enable,
		ucontrol->value.bytes.data,
		sizeof(struct afe_ttp_gen_enable_t));
	return 0;
}

static int  msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = sizeof(struct afe_ttp_gen_cfg_t);

	return 0;
}

static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	pr_debug("%s:\n", __func__);
	if (!dai_data) {
		pr_err("%s: Invalid dai data\n", __func__);
		return -EINVAL;
	}

	memcpy(ucontrol->value.bytes.data,
	       &dai_data->ttp_config.ttp_gen_cfg,
	       sizeof(struct afe_ttp_gen_cfg_t));
	return 0;
}

static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;

	pr_debug("%s: Received ttp config\n", __func__);
	if (!dai_data) {
		pr_err("%s: Invalid dai data\n", __func__);
		return -EINVAL;
	}

	memcpy(&dai_data->ttp_config.ttp_gen_cfg,
		ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t));
	return 0;
}

static const struct snd_kcontrol_new afe_dec_config_controls[] = {
	{
		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -3696,6 +3797,27 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = {
		     msm_dai_q6_afe_output_bit_format_put),
};

static const struct snd_kcontrol_new afe_ttp_config_controls[] = {
	{
		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
			   SNDRV_CTL_ELEM_ACCESS_INACTIVE),
		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
		.name = "TTP Enable",
		.info = msm_dai_q6_afe_enable_ttp_info,
		.get = msm_dai_q6_afe_enable_ttp_get,
		.put = msm_dai_q6_afe_enable_ttp_put,
	},
	{
		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
			   SNDRV_CTL_ELEM_ACCESS_INACTIVE),
		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
		.name = "AFE TTP config",
		.info = msm_dai_q6_afe_ttp_cfg_info,
		.get = msm_dai_q6_afe_ttp_cfg_get,
		.put = msm_dai_q6_afe_ttp_cfg_put,
	},
};

static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_info *uinfo)
{
@@ -3919,6 +4041,12 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_dec_config_controls[3],
				 dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_ttp_config_controls[0],
				 dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				 snd_ctl_new1(&afe_ttp_config_controls[1],
				 dai_data));
		break;
	case RT_PROXY_DAI_001_RX:
		rc = snd_ctl_add(dai->component->card->snd_card,
+4 −3
Original line number Diff line number Diff line
@@ -613,7 +613,7 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream,
}

static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd,
					 uint32_t render_mode)
					 uint32_t render_mode, int dir)
{
	int ret = -EINVAL;
	struct audio_client *ac = prtd->audio_client;
@@ -639,7 +639,7 @@ static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd,
		goto exit;
	}

	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
	if (ret) {
		pr_err("%s: Render mode can't be set error %d\n", __func__,
			ret);
@@ -705,7 +705,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream,
	}
	case SNDRV_COMPRESS_RENDER_MODE:
	{
		rc = msm_transcode_set_render_mode(prtd, metadata->value[0]);
		rc = msm_transcode_set_render_mode(prtd, metadata->value[0],
						   cstream->direction);
		if (rc)
			pr_err("%s: error setting render mode %d\n", __func__,
				rc);
+94 −5
Original line number Diff line number Diff line
@@ -3925,6 +3925,51 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config)
	return ret;
}

static int q6afe_send_ttp_config(u16 port_id,
			union afe_port_config afe_config,
			struct afe_ttp_config *ttp_cfg)
{
	struct afe_ttp_gen_enable_t ttp_gen_enable;
	struct afe_ttp_gen_cfg_t ttp_gen_cfg;
	struct param_hdr_v3 param_hdr;
	int ret;

	memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable));
	memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg));
	memset(&param_hdr, 0, sizeof(param_hdr));

	param_hdr.module_id = AFE_MODULE_ID_DECODER;
	param_hdr.instance_id = INSTANCE_ID_0;

	pr_debug("%s: Enable TTP generator\n", __func__);
	ttp_gen_enable = ttp_cfg->ttp_gen_enable;
	param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE;
	param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t);
	ret = q6afe_pack_and_set_param_in_band(port_id,
					       q6audio_get_port_index(port_id),
					       param_hdr,
					       (u8 *) &ttp_gen_enable);
	if (ret) {
		pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n",
			__func__, port_id, ret);
		goto exit;
	}

	pr_debug("%s: sending TTP generator config\n", __func__);
	ttp_gen_cfg = ttp_cfg->ttp_gen_cfg;
	param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG;
	param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t);
	ret = q6afe_pack_and_set_param_in_band(port_id,
					       q6audio_get_port_index(port_id),
					       param_hdr,
					       (u8 *) &ttp_gen_cfg);
	if (ret)
		pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n",
			__func__, port_id, ret);
exit:
	return ret;
}

static int q6afe_send_dec_config(u16 port_id,
			union afe_port_config afe_config,
			struct afe_dec_config *cfg,
@@ -4595,7 +4640,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
			    u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
			    union afe_enc_config_data *enc_cfg,
			    u32 codec_format, u32 scrambler_mode, u32 mono_mode,
			    struct afe_dec_config *dec_cfg)
			    struct afe_dec_config *dec_cfg,
			    struct afe_ttp_config *ttp_cfg)
{
	union afe_port_config port_cfg;
	struct param_hdr_v3 param_hdr;
@@ -4913,6 +4959,15 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
				goto fail_cmd;
			}
		}
		if (ttp_cfg != NULL) {
			ret = q6afe_send_ttp_config(port_id, *afe_config,
						    ttp_cfg);
			if (ret) {
				pr_err("%s: AFE TTP config for port 0x%x failed %d\n",
					 __func__, port_id, ret);
				goto fail_cmd;
			}
		}
	}

	port_index = afe_get_port_index(port_id);
@@ -4959,8 +5014,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
		   u32 rate)
{
	return __afe_port_start(port_id, afe_config, rate,
				0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL);
	return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL,
				ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL);
}
EXPORT_SYMBOL(afe_port_start);

@@ -4990,16 +5045,50 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
					afe_in_channels, afe_in_bit_width,
					&enc_cfg->data, enc_cfg->format,
					enc_cfg->scrambler_mode,
					enc_cfg->mono_mode, dec_cfg);
					enc_cfg->mono_mode, dec_cfg, NULL);
	else if (dec_cfg != NULL)
		ret = __afe_port_start(port_id, afe_config, rate,
					afe_in_channels, afe_in_bit_width,
					NULL, dec_cfg->format, 0, 0, dec_cfg);
					NULL, dec_cfg->format, 0, 0,
					dec_cfg, NULL);

	return ret;
}
EXPORT_SYMBOL(afe_port_start_v2);

/**
 * afe_port_start_v3 - to configure AFE session with
 * specified port configuration and encoder /decoder params
 *
 * @port_id: AFE port id number
 * @afe_config: port configuration
 * @rate: sampling rate of port
 * @enc_cfg: AFE enc configuration information to setup encoder
 * @afe_in_channels: AFE input channel configuration, this needs
 *  update only if input channel is differ from AFE output
 * @dec_cfg: AFE dec configuration information to set up decoder
 * @ttp_cfg: TTP generator configuration to enable TTP in AFE
 *
 * Returns 0 on success or error value on port start failure.
 */
int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
		      u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
		      struct afe_enc_config *enc_cfg,
		      struct afe_dec_config *dec_cfg,
		      struct afe_ttp_config *ttp_cfg)
{
	int ret = 0;

	if (dec_cfg != NULL && ttp_cfg != NULL)
		ret = __afe_port_start(port_id, afe_config, rate,
				       afe_in_channels, afe_in_bit_width,
				       NULL, dec_cfg->format, 0, 0,
				       dec_cfg, ttp_cfg);

	return ret;
}
EXPORT_SYMBOL(afe_port_start_v3);

int afe_get_port_index(u16 port_id)
{
	switch (port_id) {
+91 −2
Original line number Diff line number Diff line
@@ -10047,17 +10047,106 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac,
}
EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window);

/**
 * q6asm_send_mtmx_strtr_ttp_offset -
 *       command to send matrix for ttp offset
 *
 * @ac: Audio client handle
 * @ttp_offset: ttp offset params
 * @param_id: param id for ttp offset
 * @dir: RX or TX direction
 *
 * Returns 0 on success or error on failure
 */
int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac,
		struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset,
		uint32_t param_id, int dir)
{
	struct asm_mtmx_strtr_params matrix;
	int sz = 0;
	int rc  = 0;

	pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__,
		  ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw);

	if (!ac) {
		pr_err("%s: audio client handle is NULL\n", __func__);
		rc = -EINVAL;
		goto fail_cmd;
	}

	if (ac->apr == NULL) {
		pr_err("%s: ac->apr is NULL", __func__);
		rc = -EINVAL;
		goto fail_cmd;
	}

	memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params));
	sz = sizeof(struct asm_mtmx_strtr_params);
	q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE);
	atomic_set(&ac->cmd_state, -1);
	matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2;

	matrix.param.data_payload_addr_lsw = 0;
	matrix.param.data_payload_addr_msw = 0;
	matrix.param.mem_map_handle = 0;
	matrix.param.data_payload_size =
		sizeof(struct param_hdr_v1) +
		sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
	matrix.param.direction = dir;
	matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
	matrix.data.param_id = param_id;
	matrix.data.param_size =
		sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
	matrix.data.reserved = 0;
	memcpy(&(matrix.config.ttp_offset),
	       ttp_offset,
	       sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));

	rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix);
	if (rc < 0) {
		pr_err("%s: ttp offset send failed paramid [0x%x]\n",
			__func__, matrix.data.param_id);
		rc = -EINVAL;
		goto fail_cmd;
	}

	rc = wait_event_timeout(ac->cmd_wait,
			(atomic_read(&ac->cmd_state) >= 0),
			msecs_to_jiffies(TIMEOUT_MS));
	if (!rc) {
		pr_err("%s: timeout, ttp offset paramid[0x%x]\n",
			__func__, matrix.data.param_id);
		rc = -ETIMEDOUT;
		goto fail_cmd;
	}

	if (atomic_read(&ac->cmd_state) > 0) {
		pr_err("%s: DSP returned error[%s]\n",
				__func__, adsp_err_get_err_str(
				atomic_read(&ac->cmd_state)));
		rc = adsp_err_get_lnx_err_code(
				atomic_read(&ac->cmd_state));
		goto fail_cmd;
	}
	rc = 0;
fail_cmd:
	return rc;
}
EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset);

/**
 * q6asm_send_mtmx_strtr_render_mode -
 *       command to send matrix for render mode
 *
 * @ac: Audio client handle
 * @render_mode: rendering mode
 * @dir: RX or TX direction
 *
 * Returns 0 on success or error on failure
 */
int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
		uint32_t render_mode)
		uint32_t render_mode, int dir)
{
	struct asm_mtmx_strtr_params matrix;
	struct asm_session_mtmx_strtr_param_render_mode_t render_param;
@@ -10101,7 +10190,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
	matrix.param.data_payload_size =
		sizeof(struct param_hdr_v1) +
		sizeof(struct asm_session_mtmx_strtr_param_render_mode_t);
	matrix.param.direction = 0; /* RX */
	matrix.param.direction = dir;
	matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
	matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD;
	matrix.data.param_size =
Loading