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

Commit 176c7d17 authored by Tanya Dixit's avatar Tanya Dixit
Browse files

ASoC: msm: qdsp6v2: Add support to query AVCS version info



Add APIs to get AVCS service version info.

CRs-Fixed: 2082133
Change-Id: I9d65d5013153e45cf9517b3334d00d196173628c
Signed-off-by: default avatarTanya Dixit <tdixit@codeaurora.org>
parent 654596fb
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -8537,6 +8537,8 @@ struct asm_eq_params {
#define VSS_ICOMMON_CMD_GET_PARAM_V2	0x0001133E
#define VSS_ICOMMON_RSP_GET_PARAM	0x00011008

#define VSS_MAX_AVCS_NUM_SERVICES	25

/* ID of the Bass Boost module.
 * This module supports the following parameter IDs:
 *  - #AUDPROC_PARAM_ID_BASS_BOOST_ENABLE
@@ -9202,6 +9204,7 @@ struct asm_aptx_dec_fmt_blk_v2 {
#define AVCS_CMDRSP_GET_FWK_VERSION (0x0001292D)

#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF)
#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V	(0xB)

struct avcs_get_fwk_version {
	/*
@@ -9260,9 +9263,9 @@ struct avs_svc_api_info {
};

struct avcs_fwk_ver_info {
	struct avcs_get_fwk_version avcs_build;
	struct avs_svc_api_info services[0];
};
	struct avcs_get_fwk_version avcs_fwk_version;
	struct avs_svc_api_info *services;
} __packed;

/* LSM Specific */
#define VW_FEAT_DIM					(39)
+4 −2
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@

bool q6core_is_adsp_ready(void);

int q6core_get_avcs_fwk_ver_info(uint32_t service_id,
				 struct avcs_fwk_ver_info *ver_info);
int q6core_get_service_version(uint32_t service_id,
			       struct avcs_fwk_ver_info *ver_info,
			       size_t size);
size_t q6core_get_avcs_service_size(uint32_t service_id);

#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
#define DTS_EAGLE_LICENSE_ID           0x00028346
+125 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <sound/q6core.h>
#include <sound/audio_cal_utils.h>
#include <sound/adsp_err.h>
#include <sound/apr_audio-v2.h>

#define TIMEOUT_MS 1000
/*
@@ -45,7 +46,7 @@ enum ver_query_status {

struct q6core_avcs_ver_info {
	enum ver_query_status status;
	struct avcs_fwk_ver_info avcs_fwk_ver_info;
	struct avcs_fwk_ver_info ver_info;
};

struct q6core_str {
@@ -81,9 +82,61 @@ struct generic_get_data_ {
};
static struct generic_get_data_ *generic_get_data;

static int parse_fwk_version_info(uint32_t *payload)
{
	size_t fwk_ver_size;
	size_t svc_size;
	int num_services;
	int ret = 0;

	pr_debug("%s: Payload info num services %d\n",
		 __func__, payload[4]);
	/*
	 * payload1[4] is the number of services running on DSP
	 * Based on this info, we copy the payload into core
	 * avcs version info structure.
	 */
	num_services = payload[4];
	q6core_lcl.q6core_avcs_ver_info.ver_info.avcs_fwk_version.
			num_services = num_services;
	if (num_services > VSS_MAX_AVCS_NUM_SERVICES) {
		pr_err("%s: num_services: %d greater than max services: %d\n",
		       __func__, num_services, VSS_MAX_AVCS_NUM_SERVICES);
		ret = -EINVAL;
		goto done;
	}
	fwk_ver_size = sizeof(struct avcs_get_fwk_version);
	svc_size = num_services * sizeof(struct avs_svc_api_info);
	/*
	 * Dynamically allocate memory for all
	 * the services based on num_services
	 */
	q6core_lcl.q6core_avcs_ver_info.ver_info.services = NULL;
	q6core_lcl.q6core_avcs_ver_info.ver_info.services =
				kzalloc(svc_size, GFP_ATOMIC);
	if (q6core_lcl.q6core_avcs_ver_info.ver_info.services == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	/*
	 * memcpy is done twice because the memory allocated for
	 * q6core_lcl.q6core_avcs_ver_info.ver_info is not
	 * contiguous.
	 */
	memcpy(&q6core_lcl.q6core_avcs_ver_info.ver_info,
	       (uint8_t *)payload, fwk_ver_size);
	memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info.services,
	       (uint8_t *)&payload[sizeof(struct avcs_get_fwk_version)/
				   sizeof(uint32_t)], svc_size);
	ret = 0;
done:
	return ret;
}

static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
{
	uint32_t *payload1;
	int ret = 0;

	if (data == NULL) {
		pr_err("%s: data argument is null\n", __func__);
@@ -157,7 +210,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
	case RESET_EVENTS:{
		pr_debug("%s: Reset event received in Core service\n",
			__func__);
		apr_reset(q6core_lcl.core_handle_q);
		/* no reset done as the data will not change after SSR*/
		q6core_lcl.core_handle_q = NULL;
		break;
	}
@@ -191,8 +244,13 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
	case AVCS_CMDRSP_GET_FWK_VERSION:
		pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n",
			 __func__);
		payload1 = data->payload;
		q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED;
		q6core_lcl.avcs_fwk_ver_resp_received = 1;
		ret = parse_fwk_version_info(payload1);
		if (ret < 0)
			pr_err("%s: Failed to parse payload:%d\n",
			       __func__, ret);
		wake_up(&q6core_lcl.avcs_fwk_ver_req_wait);
		break;
	default:
@@ -305,10 +363,61 @@ static int q6core_send_get_avcs_fwk_ver_cmd(void)
	return ret;
}

int q6core_get_avcs_fwk_ver_info(uint32_t service_id,
				 struct avcs_fwk_ver_info *ver_info)
int q6core_get_service_version(uint32_t service_id,
			       struct avcs_fwk_ver_info *ver_info,
			       size_t size)
{
	int ret;
	int i;
	uint32_t num_services;
	size_t svc_size;

	svc_size = q6core_get_avcs_service_size(service_id);
	if (svc_size != size) {
		pr_err("%s: Expected size: %ld, Provided size: %ld",
		       __func__, svc_size, size);
		return -EINVAL;
	}

	num_services =
		q6core_lcl.q6core_avcs_ver_info.ver_info.
		avcs_fwk_version.num_services;

	if (ver_info == NULL) {
		pr_err("%s: NULL parameter ver_info\n", __func__);
		return -EINVAL;
	}

	memcpy(ver_info, &q6core_lcl.q6core_avcs_ver_info.
	       ver_info.avcs_fwk_version, sizeof(struct avcs_get_fwk_version));

	if (service_id == AVCS_SERVICE_ID_ALL) {
		memcpy(&ver_info->services[0], &q6core_lcl.
		       q6core_avcs_ver_info.ver_info.services[0],
		       (num_services * sizeof(struct avs_svc_api_info)));
	} else {
		for (i = 0; i < num_services; i++) {
			if (q6core_lcl.q6core_avcs_ver_info.
			    ver_info.services[i].service_id == service_id) {
				memcpy(&ver_info->services[0],
				       &q6core_lcl.q6core_avcs_ver_info.
				       ver_info.services[i], size);
				break;
			}
		}
	}

	return 0;
}
EXPORT_SYMBOL(q6core_get_service_version);

size_t q6core_get_avcs_service_size(uint32_t service_id)
{
	int ret = 0;
	uint32_t num_services;

	num_services =
		q6core_lcl.q6core_avcs_ver_info.ver_info.
		avcs_fwk_version.num_services;

	mutex_lock(&(q6core_lcl.ver_lock));
	pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__,
@@ -316,14 +425,20 @@ int q6core_get_avcs_fwk_ver_info(uint32_t service_id,

	switch (q6core_lcl.q6core_avcs_ver_info.status) {
	case VER_QUERY_SUPPORTED:
		ret = 0;
		pr_debug("%s: AVCS FWK version query already attempted\n",
			 __func__);
		ret = num_services * sizeof(struct avs_svc_api_info);
		break;
	case VER_QUERY_UNSUPPORTED:
		ret = -EOPNOTSUPP;
		break;
	case VER_QUERY_UNATTEMPTED:
		pr_debug("%s: Attempting AVCS FWK version query\n", __func__);
		if (q6core_is_adsp_ready()) {
			ret = q6core_send_get_avcs_fwk_ver_cmd();
			if (ret == 0)
				ret = num_services *
				      sizeof(struct avs_svc_api_info);
		} else {
			pr_err("%s: ADSP is not ready to query version\n",
			       __func__);
@@ -338,9 +453,12 @@ int q6core_get_avcs_fwk_ver_info(uint32_t service_id,
	}
	mutex_unlock(&(q6core_lcl.ver_lock));

	if (service_id != AVCS_SERVICE_ID_ALL)
		return sizeof(struct avs_svc_api_info);

	return ret;
}
EXPORT_SYMBOL(q6core_get_avcs_fwk_ver_info);
EXPORT_SYMBOL(q6core_get_avcs_service_size);

int32_t core_set_license(uint32_t key, uint32_t module_id)
{