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

Commit c18924b1 authored by Damir Didjusto's avatar Damir Didjusto Committed by Kuirong Wang
Browse files

ASoC: msm: qdsp6v2: Add the matrix mixer call during ASM loopback



Add support for matrix mixer command. The render window start and
end are set up before RUN CMD for ASM loopback is issued. This
will ensure that audio data is not dropped and audio quality
is good.

CRs-fixed: 667925
Change-Id: I406d86e9805d9f57613c0349f11cfc729ef7a24c
Signed-off-by: default avatarDamir Didjusto <damird@codeaurora.org>
parent 384894c9
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -7459,4 +7459,96 @@ struct afe_port_group_create {
	} __packed data;
} __packed;

/* Command for Matrix or Stream Router */
#define ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2    0x00010DCE
/* Module for AVSYNC */
#define ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC    0x00010DC6

/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the
 * render window start value. This parameter is supported only for a Set
 * command (not a Get command) in the Rx direction
 * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2).
 * Render window start is a value (session time minus timestamp, or ST-TS)
 * below which frames are held, and after which frames are immediately
 * rendered.
 */
#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2 0x00010DD1

/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the
 * render window end value. This parameter is supported only for a Set
 * command (not a Get command) in the Rx direction
 * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). Render window end is a value
 * (session time minus timestamp) above which frames are dropped, and below
 * which frames are immediately rendered.
 */
#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2   0x00010DD2

/* Generic payload of the window parameters in the
 * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module.
 * This payload is supported only for a Set command
 * (not a Get command) on the Rx path.
 */
struct asm_session_mtmx_strtr_param_window_v2_t {
	u32    window_lsw;
	/* Lower 32 bits of the render window start value. */

	u32    window_msw;
	/* Upper 32 bits of the render window start value.

	 * The 64-bit number formed by window_lsw and window_msw specifies a
	 * signed 64-bit window value in microseconds. The sign extension is
	 * necessary. This value is used by the following parameter IDs:
	 * #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2
	 * #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2
	 * #ASM_SESSION_MTMX_STRTR_PARAM_STAT_WINDOW_START_V2
	 * #ASM_SESSION_MTMX_STRTR_PARAM_STAT_WINDOW_END_V2
	 * The value depends on which parameter ID is used.
	 * The aDSP honors the windows at a granularity of 1 ms.
	 */
};

struct asm_session_cmd_set_mtmx_strstr_params_v2 {
	uint32_t                  data_payload_addr_lsw;
	/* Lower 32 bits of the 64-bit data payload address. */

	uint32_t                  data_payload_addr_msw;
	/* Upper 32 bits of the 64-bit data payload address.
	 * If the address is not sent (NULL), the message is in the payload.
	 * If the address is sent (non-NULL), the parameter data payloads
	 * begin at the specified address.
	 */

	uint32_t                  mem_map_handle;
	/* Unique identifier for an address. This memory map handle is returned
	 * by the aDSP through the #ASM_CMD_SHARED_MEM_MAP_REGIONS command.
	 * values
	 * - NULL -- Parameter data payloads are within the message payload
	 * (in-band).
	 * - Non-NULL -- Parameter data payloads begin at the address specified
	 * in the data_payload_addr_lsw and data_payload_addr_msw fields
	 * (out-of-band).
	 */

	uint32_t                  data_payload_size;
	/* Actual size of the variable payload accompanying the message, or in
	 * shared memory. This field is used for parsing the parameter payload.
	 * values > 0 bytes
	 */

	uint32_t                  direction;
	/* Direction of the entity (matrix mixer or stream router) on which
	 * the parameter is to be set.
	 * values
	 * - 0 -- Rx (for Rx stream router or Rx matrix mixer)
	 * - 1 -- Tx (for Tx stream router or Tx matrix mixer)
	 */
};

struct asm_mtmx_strtr_params {
	struct apr_hdr  hdr;
	struct asm_session_cmd_set_mtmx_strstr_params_v2 param;
	struct asm_stream_param_data_v2 data;
	u32 window_lsw;
	u32 window_msw;
} __packed;
#endif /*_APR_AUDIO_V2_H_ */
+5 −0
Original line number Diff line number Diff line
@@ -418,4 +418,9 @@ int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id,
/* Get current ASM topology */
int q6asm_get_asm_topology(void);

int q6asm_send_mtmx_strtr_window(struct audio_client *ac,
		struct asm_session_mtmx_strtr_param_window_v2_t *window_param,
		uint32_t param_id);


#endif /* __Q6_ASM_H__ */
+16 −0
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
	int ret = 0;
	uint16_t bits_per_sample = 16;
	struct msm_pcm_routing_evt event;
	struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window;
	uint32_t param_id;

	pcm = dev_get_drvdata(rtd->platform->dev);
	mutex_lock(&pcm->lock);
@@ -192,6 +194,20 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
				dev_err(rtd->platform->dev,
					"Error %d setting volume", ret);
		}
		/* Set to largest negative value */
		asm_mtmx_strtr_window.window_lsw = 0x00000000;
		asm_mtmx_strtr_window.window_msw = 0x80000000;
		param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2;
		q6asm_send_mtmx_strtr_window(pcm->audio_client,
					     &asm_mtmx_strtr_window,
					     param_id);
		/* Set to largest positive value */
		asm_mtmx_strtr_window.window_lsw = 0xffffffff;
		asm_mtmx_strtr_window.window_msw = 0x7fffffff;
		param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2;
		q6asm_send_mtmx_strtr_window(pcm->audio_client,
					     &asm_mtmx_strtr_window,
					     param_id);
	}
	dev_info(rtd->platform->dev, "%s: Instance = %d, Stream ID = %s\n",
			__func__ , pcm->instance, substream->pcm->id);
+64 −1
Original line number Diff line number Diff line
@@ -1428,7 +1428,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
		ret = q6asm_is_valid_session(data, priv);
		if (ret != 0)
			return ret;

		case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2:
		case ASM_STREAM_CMD_OPEN_READ_V3:
		case ASM_STREAM_CMD_OPEN_WRITE_V3:
		case ASM_STREAM_CMD_OPEN_READWRITE_V2:
@@ -4626,6 +4626,69 @@ fail_send_param:
	return rc;
}

int q6asm_send_mtmx_strtr_window(struct audio_client *ac,
		struct asm_session_mtmx_strtr_param_window_v2_t *window_param,
		uint32_t param_id)
{
	struct asm_mtmx_strtr_params matrix;
	int sz = 0;
	int rc  = 0;

	pr_debug("%s: Window lsw is %d, window msw is %d\n", __func__,
		  window_param->window_lsw, window_param->window_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;
	}

	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(matrix) -
			sizeof(matrix.hdr) - sizeof(matrix.param);
	matrix.param.direction = 0; /* RX */
	matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
	matrix.data.param_id = param_id;
	matrix.data.param_size = matrix.param.data_payload_size -
			sizeof(matrix.data);
	matrix.data.reserved = 0;
	matrix.window_lsw = window_param->window_lsw;
	matrix.window_msw = window_param->window_msw;

	rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix);
	if (rc < 0) {
		pr_err("%s: Render window start 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), 5*HZ);
	if (!rc) {
		pr_err("%s: timeout, Render window start paramid[0x%x]\n",
			__func__, matrix.data.param_id);
		rc = -EINVAL;
		goto fail_cmd;
	}
	rc = 0;
fail_cmd:
	return rc;
};

static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id)
{
	struct apr_hdr hdr;