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

Commit 799b65fb authored by Ben Romberger's avatar Ben Romberger
Browse files

ASoC: msm: qdsp6v2: Upgrade to RTAC version 1.5



Upgrade to RTAC version 1.5. Add support
for getting AFE topologies and ASM app
types. ASM and AFE not track topology
per session and port.

Change-Id: I69dd96d47a3acbd3a06d71cd28233db2ab518add
Signed-off-by: default avatarBen Romberger <bromberg@codeaurora.org>
parent 9fd50032
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#define RTAC_MAX_ACTIVE_DEVICES		4
#define RTAC_MAX_ACTIVE_POPP		8

#define DEFAULT_APP_TYPE	0x00011130

enum {
	ADM_RTAC_CAL,
	ASM_RTAC_CAL,
@@ -53,10 +55,12 @@ struct rtac_cal_block_data {
struct rtac_popp_data {
	uint32_t	popp;
	uint32_t	popp_topology;
	uint32_t	app_type;
};

struct rtac_adm_data {
	uint32_t		topology_id;
	uint32_t		afe_topology;
	uint32_t		afe_port;
	uint32_t		copp;
	uint32_t		num_of_popp;
+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ int afe_sidetone(u16 tx_port_id, u16 rx_port_id, u16 enable, uint16_t gain);
int afe_loopback_gain(u16 port_id, u16 volume);
int afe_validate_port(u16 port_id);
int afe_get_port_index(u16 port_id);
int afe_get_topology(int port_id);
int afe_start_pseudo_port(u16 port_id);
int afe_stop_pseudo_port(u16 port_id);
uint32_t afe_req_mmap_handle(struct afe_audio_client *ac);
+3 −2
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ struct audio_client {
	int					   stream_id;
	struct device *dev;
	int		       topology;
	int		       app_type;
	/* audio cache operations fptr*/
	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
	atomic_t               unmap_cb_success;
@@ -470,8 +471,8 @@ int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples,
int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id,
		uint32_t initial_samples, uint32_t trailing_samples);

/* Get current ASM topology */
int q6asm_get_asm_topology(void);
int q6asm_get_asm_topology(int session_id);
int q6asm_get_asm_app_type(int session_id);

int q6asm_send_mtmx_strtr_window(struct audio_client *ac,
		struct asm_session_mtmx_strtr_param_window_v2_t *window_param,
+20 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct afe_ctl {
	void *rx_private_data;
	uint32_t mmap_handle;

	int	topology[AFE_MAX_PORTS];
	struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES];

	atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES];
@@ -127,6 +128,22 @@ static int afe_get_cal_hw_delay(int32_t path,
				struct audio_cal_hw_delay_entry *entry);
static int remap_cal_data(struct cal_block_data *cal_block, int cal_index);

int afe_get_topology(int port_id)
{
	int topology;
	int port_index = afe_get_port_index(port_id);

	if ((port_index < 0) || (port_index > AFE_MAX_PORTS)) {
		pr_err("%s: Invalid port index %d\n", __func__, port_index);
		topology = -EINVAL;
		goto done;
	}

	topology = this_afe.topology[port_index];
done:
	return topology;
}

void afe_set_aanc_info(struct aanc_data *q6_aanc_info)
{
	this_afe.aanc_info.aanc_active = q6_aanc_info->aanc_active;
@@ -1067,6 +1084,8 @@ static int afe_send_port_topology_id(u16 port_id)
			__func__, port_id, ret);
		goto done;
	}

	this_afe.topology[index] = topology_id;
done:
	pr_debug("%s: AFE set topology id 0x%x  enable for port 0x%x ret %d\n",
			__func__, topology_id, port_id, ret);
@@ -3895,6 +3914,7 @@ int afe_close(int port_id)
	port_index = afe_get_port_index(port_id);
	if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
		this_afe.afe_sample_rates[port_index] = 0;
		this_afe.topology[port_index] = 0;
	} else {
		pr_err("%s: port %d\n", __func__, port_index);
		ret = -EINVAL;
+69 −7
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ void *q6asm_mmap_apr_reg(void);

static int q6asm_is_valid_session(struct apr_client_data *data, void *priv);
static int q6asm_send_asm_cal(struct audio_client *ac);
static int q6asm_get_asm_topology_cal(void);
static int q6asm_get_asm_app_type_cal(void);

/* for ASM custom topology */
static struct cal_type_data *cal_data[ASM_MAX_CAL_TYPES];
@@ -2137,13 +2139,15 @@ static int __q6asm_open_read(struct audio_client *ac,
	/* Stream prio : High, provide meta info with encoded frames */
	open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX;

	open.preprocopo_id = q6asm_get_asm_topology();
	open.preprocopo_id = q6asm_get_asm_topology_cal();
	if ((open.preprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
	    (open.preprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS))
		open.preprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE;
	open.bits_per_sample = bits_per_sample;
	open.mode_flags = 0x0;

	ac->topology = open.preprocopo_id;
	ac->app_type = q6asm_get_asm_app_type_cal();
	if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
		open.mode_flags |= ASM_LOW_LATENCY_TX_STREAM_SESSION <<
			ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
@@ -2363,7 +2367,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
	open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
	open.bits_per_sample = bits_per_sample;

	open.postprocopo_id = q6asm_get_asm_topology();
	open.postprocopo_id = q6asm_get_asm_topology_cal();
	if ((ac->perf_mode != LEGACY_PCM_MODE) &&
	    ((open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
	     (open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS)))
@@ -2381,8 +2385,10 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
	 * For Gapless playback it will use the same session for next stream,
	 * So use the same topology
	 */
	if (!ac->topology)
	if (!ac->topology) {
		ac->topology = open.postprocopo_id;
		ac->app_type = q6asm_get_asm_app_type_cal();
	}
	switch (format) {
	case FORMAT_LINEAR_PCM:
		open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
@@ -2509,11 +2515,12 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
	open.mode_flags = is_meta_data_mode ? BUFFER_META_ENABLE : 0;
	open.bits_per_sample = bits_per_sample;
	/* source endpoint : matrix */
	open.postprocopo_id = q6asm_get_asm_topology();
	open.postprocopo_id = q6asm_get_asm_topology_cal();

	open.postprocopo_id = overwrite_topology ?
			      topology : open.postprocopo_id;
	ac->topology = open.postprocopo_id;
	ac->app_type = q6asm_get_asm_app_type_cal();

	/* For DTS EAGLE only, force 24 bit */
	if ((open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX) ||
@@ -2682,8 +2689,9 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
	open.src_endpointype = 0;
	open.sink_endpointype = 0;
	/* source endpoint : matrix */
	open.postprocopo_id = q6asm_get_asm_topology();
	open.postprocopo_id = q6asm_get_asm_topology_cal();

	ac->app_type = q6asm_get_asm_app_type_cal();
	ac->topology = open.postprocopo_id;
	open.bits_per_sample = bits_per_sample;
	open.reserved = 0;
@@ -6483,11 +6491,40 @@ int q6asm_get_apr_service_id(int session_id)
	return ((struct apr_svc *)session[session_id]->apr)->id;
}

int q6asm_get_asm_topology(void)
int q6asm_get_asm_topology(int session_id)
{
	int topology;

	if (session_id <= 0 || session_id > SESSION_MAX) {
		pr_err("%s: invalid session_id = %d\n", __func__, session_id);
		topology = -EINVAL;
		goto done;
	}

	topology = session[session_id]->topology;
done:
	return topology;
}

int q6asm_get_asm_app_type(int session_id)
{
	int app_type;

	if (session_id <= 0 || session_id > SESSION_MAX) {
		pr_err("%s: invalid session_id = %d\n", __func__, session_id);
		app_type = -EINVAL;
		goto done;
	}

	app_type = session[session_id]->app_type;
done:
	return app_type;
}

static int q6asm_get_asm_topology_cal(void)
{
	int topology = DEFAULT_POPP_TOPOLOGY;
	struct cal_block_data *cal_block = NULL;
	pr_debug("%s:\n", __func__);

	if (cal_data[ASM_TOPOLOGY_CAL] == NULL)
		goto done;
@@ -6506,6 +6543,31 @@ done:
	return topology;
}

static int q6asm_get_asm_app_type_cal(void)
{
	int app_type = DEFAULT_APP_TYPE;
	struct cal_block_data *cal_block = NULL;

	if (cal_data[ASM_TOPOLOGY_CAL] == NULL)
		goto done;

	mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
	cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]);
	if (cal_block == NULL)
		goto unlock;

	app_type = ((struct audio_cal_info_asm_top *)
		cal_block->cal_info)->app_type;

	if (app_type == 0)
		app_type = DEFAULT_APP_TYPE;
unlock:
	mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
done:
	pr_debug("%s: Using app_type %d\n", __func__, app_type);
	return app_type;
}

static int q6asm_send_asm_cal(struct audio_client *ac)
{
	struct cal_block_data *cal_block = NULL;
Loading