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

Commit 210cbc1a authored by Kenneth Westfield's avatar Kenneth Westfield
Browse files

ASoC: msm: qdsp6v2: add ASM get_path_delay API



Add q6asm_get_path_delay API, which calls the
aDSP ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2
command and stores the result in the
audio client.  The aDSP command determines and
returns the current path delay for the given
audio session.

Change-Id: I813d202f1fdbed4e337c431d39868feab3a473b2
Signed-off-by: default avatarPatrick Lai <plai@codeaurora.org>
Signed-off-by: default avatarKenneth Westfield <kwestfie@codeaurora.org>
parent ff0543c7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -194,6 +194,8 @@ struct audio_client {
	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
	atomic_t               unmap_cb_success;
	atomic_t               reset;
	/* holds latest DSP pipeline delay */
	uint32_t               path_delay;
};

void q6asm_audio_client_free(struct audio_client *ac);
@@ -470,5 +472,7 @@ 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);

/* Retrieve the current DSP path delay */
int q6asm_get_path_delay(struct audio_client *ac);

#endif /* __Q6_ASM_H__ */
+61 −0
Original line number Diff line number Diff line
@@ -988,6 +988,7 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
	}
	ac->session = n;
	ac->cb = cb;
	ac->path_delay = UINT_MAX;
	ac->priv = priv;
	ac->io_mode = SYNC_IO_MODE;
	ac->perf_mode = LEGACY_PCM_MODE;
@@ -1823,6 +1824,20 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
	case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2:
		q6asm_process_mtmx_get_param_rsp(ac, (void *) payload);
		break;
	case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2:
		pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n",
				__func__, ac->session, payload[0], payload[2],
				payload[1]);
		if (payload[0] == 0) {
			atomic_set(&ac->cmd_state, 0);
			/* ignore msw, as a delay that large shouldn't happen */
			ac->path_delay = payload[1];
		} else {
			atomic_set(&ac->cmd_state, -payload[0]);
			ac->path_delay = UINT_MAX;
		}
		wake_up(&ac->cmd_wait);
		break;
	}
	if (ac->cb)
		ac->cb(data->opcode, data->token,
@@ -6162,6 +6177,52 @@ fail_cmd:
	return -EINVAL;
}

/*
 * q6asm_get_path_delay() - get the path delay for an audio session
 * @ac: audio client handle
 *
 * Retrieves the current audio DSP path delay for the given audio session.
 *
 * Return: 0 on success, error code otherwise
 */
int q6asm_get_path_delay(struct audio_client *ac)
{
	int rc = 0;
	struct apr_hdr hdr;

	if (!ac || ac->apr == NULL) {
		pr_err("%s: invalid audio client\n", __func__);
		return -EINVAL;
	}

	hdr.opcode = ASM_SESSION_CMD_GET_PATH_DELAY_V2;
	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
	atomic_set(&ac->cmd_state, 1);

	rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
	if (rc < 0) {
		pr_err("%s: Commmand 0x%x failed %d\n", __func__,
				hdr.opcode, rc);
		return rc;
	}

	rc = wait_event_timeout(ac->cmd_wait,
			(atomic_read(&ac->cmd_state) <= 0), 5 * HZ);
	if (!rc) {
		pr_err("%s: timeout. waited for response opcode[0x%x]\n",
				__func__, hdr.opcode);
		return -ETIMEDOUT;
	}

	rc = atomic_read(&ac->cmd_state);
	if (rc < 0) {
		pr_err("%s: DSP returned error[0x%x]\n", __func__, rc);
		return -EINVAL;
	}

	return 0;
}

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