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

Commit 1803e36c authored by Revathi Uddaraju's avatar Revathi Uddaraju Committed by Gerrit - the friendly Code Review server
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 the 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 7da5d56b
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

@@ -9060,6 +9062,10 @@ struct asm_aptx_dec_fmt_blk_v2 {
#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)
@@ -10185,6 +10191,7 @@ enum {
	COMPRESSED_PASSTHROUGH,
	COMPRESSED_PASSTHROUGH_CONVERT,
	COMPRESSED_PASSTHROUGH_DSD,
	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);

+27 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2017 The 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,5 @@ 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);
#endif /* __Q6LSM_H__ */
+88 −1
Original line number Diff line number Diff line
@@ -88,6 +88,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;
@@ -641,6 +646,54 @@ static int msm_lsm_set_custom(struct snd_pcm_substream *substream,
	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) {
		prtd->lsm_client->poll_enable = poll_enable.poll_en;
	} else {
		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)
@@ -681,6 +734,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",
@@ -1035,6 +1091,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",
@@ -1635,6 +1697,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;
}

@@ -1643,6 +1709,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__);
@@ -1656,9 +1723,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->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)
@@ -1707,6 +1791,9 @@ static int msm_lsm_close(struct snd_pcm_substream *substream)
				 __func__);
	}

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

	if (prtd->lsm_client->opened) {
		q6lsm_close(prtd->lsm_client);
		prtd->lsm_client->opened = false;
Loading