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

Commit 5ac11519 authored by Revathi Uddaraju's avatar Revathi Uddaraju
Browse files

ASoC: msm: qdsp6v2: Add support to connect LSM to ADM



LSM will connect to ADM to apply preprocessing and improve
detection performance. LSM can also directly connect to AFE
similar to existing mechanism.
MAD polling will be disabled in case of LSM connects to ADM.
Add EC reference end channel, bit format and sample rate control
to configure far end params for Echo Cancellation.

Change-Id: I4684ae346884d656e95350b7a63929b91a843512
Signed-off-by: default avatarChaithanya Krishna Bacharaju <chaithan@codeaurora.org>
Signed-off-by: default avatarRevathi Uddaraju <revathiu@codeaurora.org>
parent bdbcd945
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ struct param_outband {
#define ADM_MATRIX_ID_AUDIO_TX              1

#define ADM_MATRIX_ID_COMPRESSED_AUDIO_RX   2

#define ADM_MATRIX_ID_LISTEN_TX             4
/* Enumeration for an audio Tx matrix ID.*/
#define ADM_MATRIX_ID_AUDIOX              1

@@ -8362,6 +8364,10 @@ struct asm_dts_eagle_param_get {
#define LSM_PARAM_ID_LAB_ENABLE				(0x00012C09)
#define LSM_PARAM_ID_LAB_CONFIG				(0x00012C0A)
#define LSM_MODULE_ID_FRAMEWORK				(0x00012C0E)
#define LSM_PARAM_ID_SWMAD_CFG				(0x00012C18)
#define LSM_PARAM_ID_SWMAD_MODEL			(0x00012C19)
#define LSM_PARAM_ID_SWMAD_ENABLE			(0x00012C1A)
#define LSM_PARAM_ID_POLLING_ENABLE			(0x00012C1B)

/* HW MAD specific */
#define AFE_MODULE_HW_MAD				(0x00010230)
@@ -9451,6 +9457,7 @@ enum {
	LEGACY_PCM = 0,
	COMPRESSED_PASSTHROUGH,
	COMPRESSED_PASSTHROUGH_CONVERT,
	LISTEN,
};

#define AUDPROC_MODULE_ID_COMPRESSED_MUTE                0x00010770
+1 −1
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ int adm_unmap_rtac_block(uint32_t *mem_map_handle);
int adm_close(int port, int topology, int perf_mode);

int adm_matrix_map(int path, struct route_payload payload_map,
		   int perf_mode);
		   int perf_mode, uint32_t passthr_mode);

int adm_connect_afe_port(int mode, int session_id, int port_id);

+28 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,8 @@

#define MAX_NUM_CONFIDENCE 20

#define ADM_LSM_PORT_ID 0xADCB

typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
		       uint32_t *payload, void *priv);

@@ -81,6 +83,9 @@ struct lsm_client {
	struct lsm_lab_buffer *lab_buffer;
	struct lsm_lab_hw_params hw_params;
	bool		use_topology;
	int		session_state;
	bool		poll_enable;
	int		perf_mode;
};

struct lsm_stream_cmd_open_tx {
@@ -134,6 +139,12 @@ struct lsm_param_connect_to_port {
	uint16_t	reserved;
} __packed;

struct lsm_param_poll_enable {
	struct lsm_param_payload_common common;
	uint32_t	minor_version;
	/* indicates to voice wakeup that HW MAD/SW polling is enabled or not */
	uint32_t	polling_enable;
} __packed;

/*
 * This param cannot be sent in this format.
@@ -163,13 +174,24 @@ struct lsm_cmd_set_params_conf {
	struct lsm_param_min_confidence_levels	conf_payload;
} __packed;

struct lsm_cmd_set_opmode_connectport {
struct lsm_cmd_set_params_opmode {
	struct apr_hdr  msg_hdr;
	struct lsm_set_params_hdr params_hdr;
	struct lsm_param_connect_to_port	connect_to_port;
	struct lsm_param_op_mode op_mode;
} __packed;

struct lsm_cmd_set_connectport {
	struct apr_hdr msg_hdr;
	struct lsm_set_params_hdr params_hdr;
	struct lsm_param_connect_to_port connect_to_port;
} __packed;

struct lsm_cmd_poll_enable {
	struct apr_hdr  msg_hdr;
	struct lsm_set_params_hdr params_hdr;
	struct lsm_param_poll_enable poll_enable;
} __packed;

struct lsm_param_epd_thres {
	struct lsm_param_payload_common common;
	uint32_t	minor_version;
@@ -278,4 +300,6 @@ int q6lsm_set_one_param(struct lsm_client *client,
void q6lsm_sm_set_param_data(struct lsm_client *client,
		struct lsm_params_info *p_info,
		size_t *offset);
int q6lsm_set_port_connected(struct lsm_client *client);
int q6lsm_polling_enable(struct lsm_client *client, bool poll_enable);
#endif /* __Q6LSM_H__ */
+110 −1
Original line number Diff line number Diff line
@@ -94,6 +94,11 @@ struct lsm_priv {
	int dma_write;
};

enum { /* lsm session states */
	IDLE = 0,
	RUNNING,
};

static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i)
{
	int rc = 0;
@@ -647,6 +652,51 @@ err_ret:
	return rc;
}

static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream,
		struct lsm_params_info *p_info)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lsm_priv *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_lsm_poll_enable poll_enable;
	int rc = 0;

	if (p_info->param_size != sizeof(poll_enable)) {
		dev_err(rtd->dev,
			"%s: Invalid param_size %d\n",
			__func__, p_info->param_size);
		rc = -EINVAL;
		goto done;
	}

	if (copy_from_user(&poll_enable, p_info->param_data,
			   sizeof(poll_enable))) {
		dev_err(rtd->dev,
			"%s: copy_from_user failed, size = %zd\n",
			__func__, sizeof(poll_enable));
		rc = -EFAULT;
		goto done;
	}

	if (prtd->lsm_client->poll_enable == poll_enable.poll_en) {
		dev_dbg(rtd->dev,
			"%s: Polling for session %d already %s\n",
			__func__, prtd->lsm_client->session,
			(poll_enable.poll_en ? "enabled" : "disabled"));
		rc = 0;
		goto done;
	}

	rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
				 &poll_enable, LSM_POLLING_ENABLE);
	if (rc)
		dev_err(rtd->dev,
			"%s: Failed to set poll enable, err = %d\n",
			__func__, rc);
done:
	return rc;
}

static int msm_lsm_process_params(struct snd_pcm_substream *substream,
		struct snd_lsm_module_params *p_data,
		void *params)
@@ -687,6 +737,9 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream,
		case LSM_CUSTOM_PARAMS:
			rc = msm_lsm_set_custom(substream, p_info);
			break;
		case LSM_POLLING_ENABLE:
			rc = msm_lsm_set_poll_enable(substream, p_info);
			break;
		default:
			dev_err(rtd->dev,
				"%s: Invalid param_type %d\n",
@@ -722,6 +775,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
	struct snd_lsm_event_status *user = arg;
	struct snd_lsm_detection_params det_params;
	uint8_t *confidence_level = NULL;
	bool poll_en;

	if (!substream || !substream->private_data) {
		pr_err("%s: Invalid %s\n", __func__,
@@ -857,10 +911,32 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
		rc = q6lsm_set_data(prtd->lsm_client,
			       det_params.detect_mode,
			       det_params.detect_failure);

		if (rc)
			dev_err(rtd->dev,
				"%s: Failed to set params, err = %d\n",
				__func__, rc);
		else {
			poll_en = det_params.poll_enable;
			if (prtd->lsm_client->poll_enable == poll_en) {
				dev_dbg(rtd->dev,
					"%s: Polling for session %d already %s\n",
					__func__, prtd->lsm_client->session,
					(poll_en ? "enabled" : "disabled"));
				rc = 0;
			} else {
				dev_dbg(rtd->dev, "%s: polling enable = %d\n",
					 __func__, poll_en);
				rc = q6lsm_polling_enable(prtd->lsm_client,
								poll_en);
				if (!rc)
					prtd->lsm_client->poll_enable = poll_en;
				else
					dev_err(rtd->dev,
						"%s: poll enable failed %d\n",
						__func__, rc);
			}
		}

		kfree(prtd->lsm_client->confidence_levels);
		prtd->lsm_client->confidence_levels = NULL;
@@ -1045,6 +1121,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
			prtd->lsm_client->lab_started = false;
		}
	break;

	case SNDRV_LSM_SET_PORT:
		dev_dbg(rtd->dev, "%s: set LSM port\n", __func__);
		rc = q6lsm_set_port_connected(prtd->lsm_client);
		break;

	default:
		dev_dbg(rtd->dev,
			"%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
@@ -1083,6 +1165,7 @@ struct snd_lsm_detection_params_32 {
	enum lsm_detection_mode detect_mode;
	u8 num_confidence_levels;
	bool detect_failure;
	bool poll_enable;
};

struct lsm_params_info_32 {
@@ -1264,6 +1347,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
				det_params32.num_confidence_levels;
			det_params.detect_failure =
				det_params32.detect_failure;
			det_params.poll_enable = det_params32.poll_enable;
			cmd = SNDRV_LSM_SET_PARAMS;
			err = msm_lsm_ioctl_shared(substream, cmd,
					&det_params);
@@ -1697,6 +1781,10 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
		return -ENOMEM;
	}
	prtd->lsm_client->opened = false;
	prtd->lsm_client->session_state = IDLE;
	prtd->lsm_client->poll_enable = true;
	prtd->lsm_client->perf_mode = 0;

	return 0;
}

@@ -1705,6 +1793,7 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lsm_priv *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd;
	int ret = 0;

	if (!substream->private_data) {
		pr_err("%s: Invalid private_data", __func__);
@@ -1718,9 +1807,26 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
			"%s: LSM client data ptr is NULL\n", __func__);
		return -EINVAL;
	}

	if (prtd->lsm_client->session_state == IDLE) {
		ret = msm_pcm_routing_reg_phy_compr_stream(
				rtd->dai_link->be_id,
				prtd->lsm_client->perf_mode,
				prtd->lsm_client->session,
				SNDRV_PCM_STREAM_CAPTURE,
				LISTEN);
		if (ret) {
			dev_err(rtd->dev,
				"%s: register phy compr stream failed %d\n",
					__func__, ret);
			return ret;
		}
	}

	prtd->lsm_client->session_state = RUNNING;
	prtd->lsm_client->started = false;
	runtime->private_data = prtd;
	return 0;
	return ret;
}

static int msm_lsm_close(struct snd_pcm_substream *substream)
@@ -1769,6 +1875,9 @@ static int msm_lsm_close(struct snd_pcm_substream *substream)
				 __func__);
	}

	msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id,
					SNDRV_PCM_STREAM_CAPTURE);

	if (prtd->lsm_client->opened) {
		q6lsm_close(prtd->lsm_client);
		prtd->lsm_client->opened = false;
+691 −205

File changed.

Preview size limit exceeded, changes collapsed.

Loading