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

Commit 805c4223 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: msm-lsm-client: add support for shared buffer DAM module"

parents 8105363c 845b66f4
Loading
Loading
Loading
Loading
+72 −1
Original line number Diff line number Diff line
@@ -2425,6 +2425,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lsm_priv *prtd;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	int ret = 0;

	pr_debug("%s\n", __func__);
@@ -2488,6 +2489,8 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
	prtd->lsm_client->perf_mode = 0;
	prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE;
	prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY;
	prtd->lsm_client->fe_id = rtd->dai_link->id;
	prtd->lsm_client->unprocessed_data = 0;

	return 0;
}
@@ -2958,6 +2961,70 @@ static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
	return 0;
}

static int msm_lsm_afe_data_ctl_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	u64 fe_id = kcontrol->private_value;
	uint16_t afe_data_format = 0;
	int ret = 0;

	afe_data_format = ucontrol->value.integer.value[0];
	pr_debug("%s: afe data is %s\n", __func__,
		 afe_data_format ? "unprocessed" : "processed");

	ret = q6lsm_set_afe_data_format(fe_id, afe_data_format);
	if (ret)
		pr_err("%s: q6lsm_set_afe_data_format failed, ret = %d\n",
			__func__, ret);

	return ret;
}

static int msm_lsm_afe_data_ctl_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	u64 fe_id = kcontrol->private_value;
	uint16_t afe_data_format = 0;
	int ret = 0;

	q6lsm_get_afe_data_format(fe_id, &afe_data_format);
	ucontrol->value.integer.value[0] = afe_data_format;
	pr_debug("%s: afe data is %s\n", __func__,
		 afe_data_format ? "unprocessed" : "processed");

	return ret;
}

static int msm_lsm_add_afe_data_controls(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_pcm *pcm = rtd->pcm;
	struct snd_pcm_usr *afe_data_info;
	struct snd_kcontrol *kctl;
	const char *mixer_ctl_name	= "Listen Stream";
	const char *deviceNo		= "NN";
	const char *suffix		= "Unprocessed Data";
	int ctl_len, ret = 0;

	ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
		  strlen(suffix) + 1;
	pr_debug("%s: Adding Listen afe data cntrls\n", __func__);
	ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
				   NULL, 1, ctl_len, rtd->dai_link->id,
				   &afe_data_info);
	if (ret < 0) {
		pr_err("%s: Adding Listen afe data cntrls failed: %d\n",
		       __func__, ret);
		return ret;
	}
	kctl = afe_data_info->kctl;
	snprintf(kctl->id.name, ctl_len, "%s %d %s",
		 mixer_ctl_name, rtd->pcm->device, suffix);
	kctl->put = msm_lsm_afe_data_ctl_put;
	kctl->get = msm_lsm_afe_data_ctl_get;

	return 0;
}

static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
	int ret = 0;
@@ -2966,6 +3033,10 @@ static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
	if (ret)
		pr_err("%s, add app type controls failed:%d\n", __func__, ret);

	ret = msm_lsm_add_afe_data_controls(rtd);
	if (ret)
		pr_err("%s, add afe data controls failed:%d\n", __func__, ret);

	return ret;
}

+80 −0
Original line number Diff line number Diff line
@@ -89,6 +89,13 @@ static int q6lsm_memory_map_regions(struct lsm_client *client,
static int q6lsm_memory_unmap_regions(struct lsm_client *client,
				      uint32_t handle);

struct lsm_client_afe_data {
	uint64_t fe_id;
	uint16_t unprocessed_data;
};

static struct lsm_client_afe_data lsm_client_afe_data[LSM_MAX_SESSION_ID + 1];

static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client)
{
	int n;
@@ -255,6 +262,8 @@ static void q6lsm_session_free(struct lsm_client *client)
	pr_debug("%s: Freeing session ID %d\n", __func__, client->session);
	spin_lock_irqsave(&lsm_session_lock, flags);
	lsm_session[client->session] = NULL;
	lsm_client_afe_data[client->session].fe_id = 0;
	lsm_client_afe_data[client->session].unprocessed_data = 0;
	spin_unlock_irqrestore(&lsm_session_lock, flags);
	client->session = LSM_INVALID_SESSION_ID;
}
@@ -1062,6 +1071,72 @@ int get_lsm_port(void)
	return lsm_afe_port;
}

/**
 * q6lsm_set_afe_data_format -
 * command to set afe data format
 *
 * @fe_id: FrontEnd DAI link ID
 * @afe_data_format: afe data format
 *
 * Returns 0 on success or -EINVAL on failure
 */
int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format)
{
	int n = 0;

	if (0 != afe_data_format && 1 != afe_data_format)
		goto done;

	pr_debug("%s: afe data is %s\n", __func__,
		 afe_data_format ? "unprocessed" : "processed");

	for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
		if (0 == lsm_client_afe_data[n].fe_id) {
			lsm_client_afe_data[n].fe_id = fe_id;
			lsm_client_afe_data[n].unprocessed_data =
							afe_data_format;
			pr_debug("%s: session ID is %d, fe_id is %d\n",
				 __func__, n, fe_id);
			return 0;
		}
	}

	pr_err("%s: all lsm sessions are taken\n", __func__);
done:
	return -EINVAL;
}
EXPORT_SYMBOL(q6lsm_set_afe_data_format);

/**
 * q6lsm_get_afe_data_format -
 * command to get afe data format
 *
 * @fe_id: FrontEnd DAI link ID
 * @afe_data_format: afe data format
 *
 */
void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format)
{
	int n = 0;

	if (NULL == afe_data_format) {
		pr_err("%s: Pointer afe_data_format is NULL\n", __func__);
		return;
	}

	for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
		if (fe_id == lsm_client_afe_data[n].fe_id) {
			*afe_data_format =
				lsm_client_afe_data[n].unprocessed_data;
			pr_debug("%s: session: %d, fe_id: %d, afe data: %s\n",
				__func__, n, fe_id,
				*afe_data_format ? "unprocessed" : "processed");
			return;
		}
	}
}
EXPORT_SYMBOL(q6lsm_get_afe_data_format);

/**
 * q6lsm_set_port_connected -
 *       command to set LSM port connected
@@ -1092,14 +1167,19 @@ int q6lsm_set_port_connected(struct lsm_client *client)
	connectport_hdr.param_size = sizeof(connect_port);

	client->connect_to_port = get_lsm_port();
	if (ADM_LSM_PORT_ID != client->connect_to_port)
		q6lsm_get_afe_data_format(client->fe_id,
					  &client->unprocessed_data);
	connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
	connect_port.port_id = client->connect_to_port;
	connect_port.unprocessed_data = client->unprocessed_data;

	rc = q6lsm_pack_and_set_params(client, &connectport_hdr,
				       (uint8_t *) &connect_port,
				       set_param_opcode);
	if (rc)
		pr_err("%s: Failed set_params, rc %d\n", __func__, rc);

	return rc;
}
EXPORT_SYMBOL(q6lsm_set_port_connected);
+6 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
 */
#ifndef __Q6LSM_H__
#define __Q6LSM_H__
@@ -102,6 +102,8 @@ struct lsm_client {
	uint32_t	event_type;
	uint32_t	num_stages;
	struct lsm_stage_config	stage_cfg[LSM_MAX_STAGES_PER_SESSION];
	uint64_t	fe_id;
	uint16_t	unprocessed_data;
};

struct lsm_stream_cmd_open_tx {
@@ -159,7 +161,7 @@ struct lsm_param_connect_to_port {
	uint32_t	minor_version;
	/* AFE port id that receives voice wake up data */
	uint16_t	port_id;
	uint16_t	reserved;
	uint16_t	unprocessed_data;
} __packed;

struct lsm_param_poll_enable {
@@ -295,4 +297,6 @@ int q6lsm_set_media_fmt_v2_params(struct lsm_client *client);
int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map,
		struct lsm_params_info_v2 *p_info);
bool q6lsm_adsp_supports_multi_stage_detection(void);
int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format);
void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format);
#endif /* __Q6LSM_H__ */