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

Commit 663009d0 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: qdsp6: Add support for gapless audio playback"

parents 33c0beb5 8ea741c3
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -4729,6 +4729,25 @@ struct asm_stream_cmd_open_write_compressed {

} __packed;


/*
    Indicates the number of samples per channel to be removed from the
    beginning of the stream.
*/
#define ASM_DATA_CMD_REMOVE_INITIAL_SILENCE 0x00010D67
/*
    Indicates the number of samples per channel to be removed from
    the end of the stream.
*/
#define ASM_DATA_CMD_REMOVE_TRAILING_SILENCE 0x00010D68
struct asm_data_cmd_remove_silence {
	struct apr_hdr hdr;
	u32	num_samples_to_remove;
	/**< Number of samples per channel to be removed.

	   @values 0 to (2@sscr{32}-1) */
} __packed;

#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED                        0x00010D95

struct asm_stream_cmd_open_read_compressed {
+27 −0
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@
#define SESSION_MAX		0x08
#define ASM_CONTROL_SESSION	0x0F

#define ASM_SHIFT_GAPLESS_MODE_FLAG	31
#define ASM_SHIFT_LAST_BUFFER_FLAG	30

/* payload structure bytes */
#define READDONE_IDX_STATUS 0
#define READDONE_IDX_BUFADD_LSW 1
@@ -131,6 +134,7 @@ struct audio_aio_write_param {
	uint32_t      msw_ts;
	uint32_t      flags;
	uint32_t      metadata_len;
	uint32_t      last_buffer;
};

struct audio_aio_read_param {
@@ -163,12 +167,14 @@ struct audio_client {
	uint64_t	       time_stamp;
	struct apr_svc         *apr;
	struct apr_svc         *mmap_apr;
	struct apr_svc         *apr2;
	struct mutex	       cmd_lock;
	/* idx:1 out port, 0: in port*/
	struct audio_port_data port[2];
	wait_queue_head_t      cmd_wait;
	wait_queue_head_t      time_wait;
	bool                   perf_mode;
	int					   stream_id;
	/* audio cache operations fptr*/
	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
};
@@ -204,6 +210,10 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format
int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
			uint16_t bits_per_sample);

int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
				uint16_t bits_per_sample, int32_t stream_id,
				bool is_gapless_mode);

int q6asm_open_read_write(struct audio_client *ac,
			uint32_t rd_format,
			uint32_t wr_format);
@@ -240,12 +250,22 @@ int q6asm_run(struct audio_client *ac, uint32_t flags,
int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
		uint32_t msw_ts, uint32_t lsw_ts);

int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags,
		uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id);

int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable);

int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable);

int q6asm_cmd(struct audio_client *ac, int cmd);

int q6asm_stream_cmd(struct audio_client *ac, int cmd, uint32_t stream_id);

int q6asm_cmd_nowait(struct audio_client *ac, int cmd);

int q6asm_stream_cmd_nowait(struct audio_client *ac, int cmd,
			    uint32_t stream_id);

void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac,
				uint32_t *size, uint32_t *idx);

@@ -317,6 +337,9 @@ int q6asm_media_format_block_multi_ch_pcm_v2(
int q6asm_media_format_block_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg);

int q6asm_stream_media_format_block_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg, int stream_id);

int q6asm_media_format_block_multi_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg);

@@ -364,4 +387,8 @@ int q6asm_get_apr_service_id(int session_id);
*/
int q6asm_media_format_block(struct audio_client *ac, uint32_t format);

/* Send the meta data to remove initial and trailing silence */
int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
		uint32_t trailing_samples);

#endif /* __Q6_ASM_H__ */
+204 −35
Original line number Diff line number Diff line
@@ -811,6 +811,10 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
				(apr_fn)q6asm_callback,\
				((ac->session) << 8 | 0x0001),\
				ac);
	ac->apr2 = apr_register("ADSP", "ASM",
				(apr_fn)q6asm_callback,
				((ac->session) << 8 | 0x0002),
				ac);

	if (ac->apr == NULL) {
		pr_err("%s Registration with APR failed\n", __func__);
@@ -1210,7 +1214,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
		data->token, data->payload_size, data->src_port,
		data->dest_port);
	if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) &&
			(data->opcode != ASM_DATA_EVENT_EOS))
	    (data->opcode != ASM_DATA_EVENT_EOS) &&
	    (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW))
		pr_debug("%s:Payload = [0x%x] status[0x%x]\n",
			__func__, payload[0], payload[1]);
	if (data->opcode == APR_BASIC_RSP_RESULT) {
@@ -1244,6 +1249,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
		case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
		case ASM_CMD_ADD_TOPOLOGIES:
		case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
		case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
		case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
		pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
				__func__, payload[0], payload[1]);
			if (atomic_read(&ac->cmd_state) && wakeup_flag) {
@@ -1367,7 +1375,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
				  __func__, data->opcode);
		break;
	case ASM_SESSION_EVENTX_OVERFLOW:
		pr_err("ASM_SESSION_EVENTX_OVERFLOW\n");
		pr_debug("ASM_SESSION_EVENTX_OVERFLOW\n");
		break;
	case ASM_SESSION_EVENT_RX_UNDERFLOW:
		pr_debug("ASM_SESSION_EVENT_RX_UNDERFLOW\n");
		break;
	case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
		pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
@@ -1519,11 +1530,11 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac)
	return ret;
}

static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
			uint32_t pkt_size, uint32_t cmd_flg)
static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
			uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id)
{
	pr_debug("%s:pkt_size=%d cmd_flg=%d session=%d\n", __func__, pkt_size,
		cmd_flg, ac->session);
	pr_debug("%s:pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n",
		 __func__, pkt_size, cmd_flg, ac->session, stream_id);
	if (ac->apr == NULL) {
		pr_err("%s: ac->apr is NULL", __func__);
		return;
@@ -1537,8 +1548,8 @@ static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
	hdr->src_domain = APR_DOMAIN_APPS;
	hdr->dest_svc = APR_SVC_ASM;
	hdr->dest_domain = APR_DOMAIN_ADSP;
	hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
	hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
	hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
	hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
	if (cmd_flg) {
		hdr->token = ac->session;
		atomic_set(&ac->cmd_state, 1);
@@ -1548,11 +1559,25 @@ static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
	return;
}

static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
			uint32_t pkt_size, uint32_t cmd_flg)
{
	pr_debug("pkt_size = %d, cmd_flg = %d, session = %d\n",
			pkt_size, cmd_flg, ac->session);
	__q6asm_add_hdr(ac, hdr, pkt_size, cmd_flg, ac->stream_id);
	return;
}

static void q6asm_stream_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
			uint32_t pkt_size, uint32_t cmd_flg, int32_t stream_id)
{
	__q6asm_add_hdr(ac, hdr, pkt_size, cmd_flg, stream_id);
	return;
}

static void __q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
			uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id)
{
	pr_debug("%s pkt_size = %d, cmd_flg = %d, session = %d stream_id=%d\n",
		__func__, pkt_size, cmd_flg, ac->session, stream_id);
	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
				APR_HDR_LEN(sizeof(struct apr_hdr)),\
				APR_PKT_VER);
@@ -1564,8 +1589,8 @@ static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
	hdr->src_domain = APR_DOMAIN_APPS;
	hdr->dest_svc = APR_SVC_ASM;
	hdr->dest_domain = APR_DOMAIN_ADSP;
	hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
	hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
	hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
	hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id+1);
	if (cmd_flg) {
		hdr->token = ac->session;
		atomic_set(&ac->cmd_state, 1);
@@ -1574,6 +1599,21 @@ static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
	return;
}

static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
				uint32_t pkt_size, uint32_t cmd_flg)
{
	__q6asm_add_hdr_async(ac, hdr, pkt_size, cmd_flg, ac->stream_id);
	return;
}

static void q6asm_stream_add_hdr_async(struct audio_client *ac,
					struct apr_hdr *hdr, uint32_t pkt_size,
					uint32_t cmd_flg, int32_t stream_id)
{
	__q6asm_add_hdr_async(ac, hdr, pkt_size, cmd_flg, stream_id);
	return;
}

static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr,
			u32 pkt_size, u32 cmd_flg, u32 token)
{
@@ -1682,7 +1722,8 @@ int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
}

static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
		uint16_t bits_per_sample)
				uint16_t bits_per_sample, uint32_t stream_id,
				bool is_gapless_mode)
{
	int rc = 0x00;
	struct asm_stream_cmd_open_write_v3 open;
@@ -1694,14 +1735,17 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
	pr_debug("%s: session[%d] wr_format[0x%x]", __func__, ac->session,
		format);

	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
	q6asm_stream_add_hdr(ac, &open.hdr, sizeof(open), TRUE, stream_id);

	open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
	open.mode_flags = 0x00;
	if (ac->perf_mode)
		open.mode_flags |= ASM_ULTRA_LOW_LATENCY_STREAM_SESSION;
	else
	else {
		open.mode_flags |= ASM_LEGACY_STREAM_SESSION;
		if (is_gapless_mode)
			open.mode_flags |= 1 << ASM_SHIFT_GAPLESS_MODE_FLAG;
	}

	/* source endpoint : matrix */
	open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
@@ -1760,13 +1804,23 @@ fail_cmd:

int q6asm_open_write(struct audio_client *ac, uint32_t format)
{
	return __q6asm_open_write(ac, format, 16);
	return __q6asm_open_write(ac, format, 16, ac->stream_id,
					 false /*gapless*/);
}

int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
		uint16_t bits_per_sample)
{
	return __q6asm_open_write(ac, format, bits_per_sample);
	return __q6asm_open_write(ac, format, bits_per_sample,
					 ac->stream_id, false /*gapless*/);
}

int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
				uint16_t bits_per_sample, int32_t stream_id,
				bool is_gapless_mode)
{
	return __q6asm_open_write(ac, format, bits_per_sample,
					 stream_id, is_gapless_mode);
}

int q6asm_open_read_write(struct audio_client *ac,
@@ -1920,8 +1974,8 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
		uint32_t msw_ts, uint32_t lsw_ts)
static int __q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
		uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id)
{
	struct asm_session_cmd_run_v2 run;
	int rc;
@@ -1930,7 +1984,7 @@ int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
		return -EINVAL;
	}
	pr_debug("session[%d]", ac->session);
	q6asm_add_hdr_async(ac, &run.hdr, sizeof(run), TRUE);
	q6asm_stream_add_hdr_async(ac, &run.hdr, sizeof(run), TRUE, stream_id);

	run.hdr.opcode = ASM_SESSION_CMD_RUN_V2;
	run.flags    = flags;
@@ -1948,6 +2002,17 @@ int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
	return 0;
}

int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
			uint32_t msw_ts, uint32_t lsw_ts)
{
	return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, ac->stream_id);
}

int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags,
			uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id)
{
	return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id);
}

int q6asm_enc_cfg_blk_aac(struct audio_client *ac,
			 uint32_t frames_per_buf,
@@ -2467,12 +2532,6 @@ fail_cmd:
}


int q6asm_media_format_block_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg)
{
	return q6asm_media_format_block_multi_aac(ac, cfg);
}

static int __q6asm_media_format_block_pcm(struct audio_client *ac,
				uint32_t rate, uint32_t channels,
				uint16_t bits_per_sample)
@@ -2603,8 +2662,8 @@ int q6asm_media_format_block_multi_ch_pcm_v2(
			bits_per_sample);
}

int q6asm_media_format_block_multi_aac(struct audio_client *ac,
				struct asm_aac_cfg *cfg)
static int __q6asm_media_format_block_multi_aac(struct audio_client *ac,
				struct asm_aac_cfg *cfg, int stream_id)
{
	struct asm_aac_fmt_blk_v2 fmt;
	int rc = 0;
@@ -2612,7 +2671,7 @@ int q6asm_media_format_block_multi_aac(struct audio_client *ac,
	pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session,
		cfg->sample_rate, cfg->ch_cfg);

	q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
	q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);

	fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
	fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
@@ -2646,6 +2705,24 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_media_format_block_multi_aac(struct audio_client *ac,
				struct asm_aac_cfg *cfg)
{
	return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id);
}

int q6asm_media_format_block_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg)
{
	return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id);
}

int q6asm_stream_media_format_block_aac(struct audio_client *ac,
			struct asm_aac_cfg *cfg, int stream_id)
{
	return __q6asm_media_format_block_multi_aac(ac, cfg, stream_id);
}

int q6asm_media_format_block_wma(struct audio_client *ac,
				void *cfg)
{
@@ -3630,7 +3707,7 @@ int q6asm_async_write(struct audio_client *ac,
		write.flags = (0x00000000 | (param->flags & 0x800000FF));
	else
		write.flags = (0x80000000 | param->flags);

	write.flags |= param->last_buffer << ASM_SHIFT_LAST_BUFFER_FLAG;
	write.seq_id = param->uid;
	list_for_each_safe(ptr, next, &ac->port[IN].mem_map_handle) {
		buf_node = list_entry(ptr, struct asm_buffer_node,
@@ -3880,7 +3957,7 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_cmd(struct audio_client *ac, int cmd)
static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id)
{
	struct apr_hdr hdr;
	int rc;
@@ -3891,7 +3968,7 @@ int q6asm_cmd(struct audio_client *ac, int cmd)
		pr_err("APR handle NULL\n");
		return -EINVAL;
	}
	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
	q6asm_stream_add_hdr(ac, &hdr, sizeof(hdr), TRUE, stream_id);
	switch (cmd) {
	case CMD_PAUSE:
		pr_debug("%s:CMD_PAUSE\n", __func__);
@@ -3969,7 +4046,18 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
int q6asm_cmd(struct audio_client *ac, int cmd)
{
	return __q6asm_cmd(ac, cmd, ac->stream_id);
}

int q6asm_stream_cmd(struct audio_client *ac, int cmd, uint32_t stream_id)
{
	return __q6asm_cmd(ac, cmd, stream_id);
}

static int __q6asm_cmd_nowait(struct audio_client *ac, int cmd,
			      uint32_t stream_id)
{
	struct apr_hdr hdr;
	int rc;
@@ -3978,7 +4066,7 @@ int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
		pr_err("%s:APR handle NULL\n", __func__);
		return -EINVAL;
	}
	q6asm_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE);
	q6asm_stream_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE, stream_id);
	switch (cmd) {
	case CMD_PAUSE:
		pr_debug("%s:CMD_PAUSE\n", __func__);
@@ -3988,6 +4076,10 @@ int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
		pr_debug("%s:CMD_EOS\n", __func__);
		hdr.opcode = ASM_DATA_CMD_EOS;
		break;
	case CMD_CLOSE:
		pr_debug("%s:CMD_CLOSE\n", __func__);
		hdr.opcode = ASM_STREAM_CMD_CLOSE;
		break;
	default:
		pr_err("%s:Invalid format[%d]\n", __func__, cmd);
		goto fail_cmd;
@@ -4008,6 +4100,54 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
{
	pr_debug("%s: stream_id: %d\n", __func__, ac->stream_id);
	return __q6asm_cmd_nowait(ac, cmd, ac->stream_id);
}

int q6asm_stream_cmd_nowait(struct audio_client *ac, int cmd,
			    uint32_t stream_id)
{
	pr_debug("%s: stream_id: %d\n", __func__, stream_id);
	return __q6asm_cmd_nowait(ac, cmd, stream_id);
}

int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
		uint32_t trailing_samples)
{
	struct asm_data_cmd_remove_silence silence;
	int rc = 0;
	if (!ac || ac->apr == NULL) {
		pr_err("APR handle NULL\n");
		return -EINVAL;
	}
	pr_debug("%s session[%d]", __func__, ac->session);
	q6asm_add_hdr_async(ac, &silence.hdr, sizeof(silence), FALSE);

	silence.hdr.opcode = ASM_DATA_CMD_REMOVE_INITIAL_SILENCE;
	silence.num_samples_to_remove    = initial_samples;

	rc = apr_send_pkt(ac->apr, (uint32_t *) &silence);
	if (rc < 0) {
		pr_err("Commmand silence failed[%d]", rc);
		goto fail_cmd;
	}

	silence.hdr.opcode = ASM_DATA_CMD_REMOVE_TRAILING_SILENCE;
	silence.num_samples_to_remove    = trailing_samples;

	rc = apr_send_pkt(ac->apr, (uint32_t *) &silence);
	if (rc < 0) {
		pr_err("Commmand silence failed[%d]", rc);
		goto fail_cmd;
	}

	return 0;
fail_cmd:
	return -EINVAL;
}

static void q6asm_reset_buf_state(struct audio_client *ac)
{
	int cnt = 0;
@@ -4067,6 +4207,35 @@ fail_cmd:
	return -EINVAL;
}

int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable)
{
	struct asm_session_cmd_rgstr_rx_underflow rx_underflow;
	int rc;

	if (!ac || ac->apr == NULL) {
		pr_err("APR handle NULL\n");
		return -EINVAL;
	}
	pr_debug("%s:session[%d]enable[%d]\n", __func__,
						ac->session, enable);
	q6asm_add_hdr_async(ac, &rx_underflow.hdr, sizeof(rx_underflow), FALSE);

	rx_underflow.hdr.opcode =
			ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS;
	/* tx overflow event: enable */
	rx_underflow.enable_flag = enable;

	rc = apr_send_pkt(ac->apr, (uint32_t *) &rx_underflow);
	if (rc < 0) {
		pr_err("tx overflow op[0x%x]rc[%d]\n",
						rx_underflow.hdr.opcode, rc);
		goto fail_cmd;
	}
	return 0;
fail_cmd:
	return -EINVAL;
}

int q6asm_get_apr_service_id(int session_id)
{
	pr_debug("%s\n", __func__);