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

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

Merge "ASoC: msm: qdsp6v2: Add matrix limiter support"

parents 4687d5a7 88fad2e0
Loading
Loading
Loading
Loading
+82 −1
Original line number Diff line number Diff line
@@ -446,6 +446,88 @@ struct adm_param_data_v5 {
	 */
} __packed;


struct param_data_v6 {
	/* Unique ID of the module. */
	u32		module_id;
	/* Unique ID of the instance. */
	u16		instance_id;
	/* Reserved for future enhancements.
	 * This field must be set to zero.
	 */
	u16		reserved;
	/* Unique ID of the parameter. */
	u32		param_id;
	/* Data size of the param_id/module_id combination.
	 * This value is a
	 * multiple of 4 bytes.
	 */
	u32		param_size;
} __packed;

/* ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1 command is used to set
 * calibration data to the ADSP Matrix Mixer the payload is
 * of struct adm_cmd_set_mtmx_params_v1.
 *
 * ADM_CMD_GET_MTMX_STRTR_DEV_PARAMS_V1 can be used to get
 * the calibration data from the ADSP Matrix Mixer and
 * ADM_CMDRSP_GET_MTMX_STRTR_DEV_PARAMS_V1 is the response
 * ioctl to ADM_CMD_GET_MTMX_STRTR_DEV_PARAMS_V1.
 */
#define ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1	0x00010367
#define ADM_CMD_GET_MTMX_STRTR_DEV_PARAMS_V1	0x00010368
#define ADM_CMDRSP_GET_MTMX_STRTR_DEV_PARAMS_V1	0x00010369

/* Payload of the #define ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1 command.
 * If the data_payload_addr_lsw and data_payload_addr_msw element
 * are NULL, a series of struct param_data_v6 structures immediately
 * follows, whose total size is payload_size bytes.
 */
struct adm_cmd_set_mtmx_params_v1 {
	struct apr_hdr	hdr;
	/* LSW of parameter data payload address.*/
	u32		payload_addr_lsw;

	/* MSW of parameter data payload address.*/
	u32		payload_addr_msw;

	/* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS
	 * command.
	 * If mem_map_handle is zero it implies the message is in
	 * the payload
	 */
	u32		mem_map_handle;

	/* Size in bytes of the variable payload accompanying this
	 * message or in shared memory. This is used for parsing
	 * the parameter payload.
	 */
	u32		payload_size;

	/* COPP ID/Device ID */
	u16		copp_id;

	/* For alignment, must be set to 0 */
	u16		reserved;
} __packed;

struct enable_param_v6 {
	/*
	 * Specifies whether the Audio processing module is enabled.
	 * This parameter is generic/common parameter to configure or
	 * determine the state of any audio processing module.
	 */
	struct param_data_v6		param;

	/* @values 0 : Disable 1: Enable */
	uint32_t			enable;
} __packed;

/* Defined in ADSP as VOICE_MODULE_TX_STREAM_LIMITER but
 * used for RX stream limiter on matrix input to ADM.
 */
#define ADM_MTMX_MODULE_STREAM_LIMITER  0x00010F15

#define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213
#define ASM_STREAM_PP_EVENT 0x00013214
#define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x13333
@@ -9224,7 +9306,6 @@ struct srs_trumedia_params {
} __packed;
/* SRS TruMedia end */

#define AUDPROC_PARAM_ID_ENABLE		0x00010904
#define ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS 0x1000FFFF
/* DTS Eagle */
#define AUDPROC_MODULE_ID_DTS_HPX_PREMIX 0x0001077C
+8 −0
Original line number Diff line number Diff line
@@ -51,6 +51,13 @@ enum {
	ADM_CLIENT_ID_MAX,
};

/* ENUM for adm_status & route_status */
enum adm_status_flags {
	ADM_STATUS_CALIBRATION_REQUIRED = 0,
	ADM_STATUS_LIMITER,
	ADM_STATUS_MAX,
};

#define MAX_COPPS_PER_PORT 0x8
#define ADM_MAX_CHANNELS 8

@@ -61,6 +68,7 @@ struct route_payload {
	int app_type[MAX_COPPS_PER_PORT];
	int acdb_dev_id[MAX_COPPS_PER_PORT];
	int sample_rate[MAX_COPPS_PER_PORT];
	unsigned long route_status[MAX_COPPS_PER_PORT];
	unsigned short num_copps;
	unsigned int session_id;
};
+59 −39
Original line number Diff line number Diff line
@@ -120,17 +120,13 @@ static const char * const lsm_port_text[] = {
};
struct msm_pcm_route_bdai_pp_params {
	u16 port_id; /* AFE port ID */
	unsigned long pp_params_config;
	bool mute_on;
	int latency;
};
static struct msm_pcm_route_bdai_pp_params
	msm_bedais_pp_params[MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX] = {
	{HDMI_RX, 0, 0, 0},
	{DISPLAY_PORT_RX, 0, 0, 0},
};
	msm_bedais_pp_params[MSM_BACKEND_DAI_MAX];
/*
 * The be_dai_name_table is passed to HAL so that it can specify the
@@ -144,6 +140,7 @@ struct msm_pcm_route_bdai_name {
};
static struct msm_pcm_route_bdai_name be_dai_name_table[MSM_BACKEND_DAI_MAX];
static bool msm_pcm_routing_test_pp_param(int be_idx, long param_bit);
static int msm_routing_send_device_pp_params(int port_id,  int copp_idx,
					     int fe_id);
@@ -955,7 +952,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
					 uint32_t passthr_mode)
{
	int i, port_type, j, num_copps = 0;
	struct route_payload payload;
	struct route_payload payload = { {0} };
	port_type = ((path_type == ADM_PATH_PLAYBACK ||
		      path_type == ADM_PATH_COMPRESSED_RX) ?
@@ -985,6 +982,11 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
						fe_dai_app_type_cfg
							[fedai_id][sess_type][i]
								.sample_rate;
					if (msm_pcm_routing_test_pp_param(i,
					    ADM_PP_PARAM_LIMITER_BIT))
						set_bit(ADM_STATUS_LIMITER,
							&payload.route_status
							[num_copps]);
					num_copps++;
				}
			}
@@ -1206,6 +1208,11 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
						fe_dai_app_type_cfg
							[fe_id][session_type][i]
								.sample_rate;
					if (msm_pcm_routing_test_pp_param(i,
					    ADM_PP_PARAM_LIMITER_BIT))
						set_bit(ADM_STATUS_LIMITER,
							&payload.route_status
							[num_copps]);
					num_copps++;
				}
			}
@@ -1436,6 +1443,11 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
						fe_dai_app_type_cfg
							[fedai_id][session_type]
							[i].sample_rate;
					if (msm_pcm_routing_test_pp_param(i,
					    ADM_PP_PARAM_LIMITER_BIT))
						set_bit(ADM_STATUS_LIMITER,
							&payload.route_status
							[num_copps]);
					num_copps++;
				}
			}
@@ -15335,7 +15347,7 @@ done:
static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
					     int fe_id)
{
	int index, topo_id, be_idx;
	int topo_id, be_idx;
	unsigned long pp_config = 0;
	bool mute_on;
	int latency;
@@ -15359,16 +15371,6 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
		return  -EINVAL;
	}
	for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) {
		if (msm_bedais_pp_params[index].port_id == port_id)
			break;
	}
	if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) {
		pr_err("%s: Invalid backend pp params index %d\n",
			__func__, index);
		return -EINVAL;
	}
	topo_id = adm_get_topology_for_port_copp_idx(port_id, copp_idx);
	if (topo_id != COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY) {
		pr_err("%s: Invalid passthrough topology 0x%x\n",
@@ -15380,11 +15382,11 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
		(msm_bedais[be_idx].passthr_mode[fe_id] == LISTEN))
		compr_passthr_mode = false;
	pp_config = msm_bedais_pp_params[index].pp_params_config;
	pp_config = msm_bedais_pp_params[be_idx].pp_params_config;
	if (test_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config)) {
		pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
		clear_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config);
		mute_on = msm_bedais_pp_params[index].mute_on;
		mute_on = msm_bedais_pp_params[be_idx].mute_on;
		if ((msm_bedais[be_idx].active) && compr_passthr_mode)
			adm_send_compressed_device_mute(port_id,
								copp_idx,
@@ -15394,7 +15396,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
		pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__);
		clear_bit(ADM_PP_PARAM_LATENCY_BIT,
			  &pp_config);
		latency = msm_bedais_pp_params[index].latency;
		latency = msm_bedais_pp_params[be_idx].latency;
		if ((msm_bedais[be_idx].active) && compr_passthr_mode)
			adm_send_compressed_device_latency(port_id,
							   copp_idx,
@@ -15403,18 +15405,47 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
	return 0;
}
static bool msm_pcm_routing_test_pp_param(int be_idx, long param_bit)
{
	return test_bit(param_bit,
		&msm_bedais_pp_params[be_idx].pp_params_config);
}
static void msm_routing_set_pp_param(long param_bit, int value)
{
	int be_idx;
	if (value) {
		for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
			set_bit(param_bit,
				&msm_bedais_pp_params[be_idx].
				pp_params_config);
	} else {
		for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
			clear_bit(param_bit,
				&msm_bedais_pp_params[be_idx].
				pp_params_config);
	}
}
static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	int pp_id = ucontrol->value.integer.value[0];
	int value = ucontrol->value.integer.value[1];
	int port_id = 0;
	int index, be_idx, i, topo_id, idx;
	int be_idx, i, topo_id, idx;
	bool mute;
	int latency;
	bool compr_passthr_mode = true;
	pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id);
	if (pp_id == ADM_PP_PARAM_LIMITER_ID) {
		msm_routing_set_pp_param(ADM_PP_PARAM_LIMITER_BIT, value);
		goto done;
	}
	for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
		port_id = msm_bedais[be_idx].port_id;
		if (port_id == HDMI_RX || port_id == DISPLAY_PORT_RX)
@@ -15426,16 +15457,6 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
		return  -EINVAL;
	}
	for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) {
		if (msm_bedais_pp_params[index].port_id == port_id)
			break;
	}
	if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) {
		pr_err("%s: Invalid pp params backend index %d\n",
			__func__, index);
		return -EINVAL;
	}
	for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
				MSM_FRONTEND_DAI_MM_SIZE) {
		if ((msm_bedais[be_idx].passthr_mode[i] == LEGACY_PCM) ||
@@ -15458,22 +15479,20 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
		switch (pp_id) {
		case ADM_PP_PARAM_MUTE_ID:
			pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
			mute = ucontrol->value.integer.value[1] ? true : false;
			msm_bedais_pp_params[index].mute_on = mute;
			mute = value ? true : false;
			msm_bedais_pp_params[be_idx].mute_on = mute;
			set_bit(ADM_PP_PARAM_MUTE_BIT,
				&msm_bedais_pp_params[index].pp_params_config);
				&msm_bedais_pp_params[be_idx].pp_params_config);
			if ((msm_bedais[be_idx].active) && compr_passthr_mode)
				adm_send_compressed_device_mute(port_id,
					idx, mute);
			break;
		case ADM_PP_PARAM_LATENCY_ID:
			pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__);
			msm_bedais_pp_params[index].latency =
				ucontrol->value.integer.value[1];
			msm_bedais_pp_params[be_idx].latency = value;
			set_bit(ADM_PP_PARAM_LATENCY_BIT,
				&msm_bedais_pp_params[index].pp_params_config);
			latency = msm_bedais_pp_params[index].latency =
				ucontrol->value.integer.value[1];
				&msm_bedais_pp_params[be_idx].pp_params_config);
			latency = msm_bedais_pp_params[be_idx].latency = value;
			if ((msm_bedais[be_idx].active) && compr_passthr_mode)
				adm_send_compressed_device_latency(port_id,
					idx, latency);
@@ -15485,6 +15504,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
		}
		}
	}
done:
	return 0;
}
+13 −5
Original line number Diff line number Diff line
@@ -397,12 +397,20 @@ enum {
#define RELEASE_LOCK	0
#define ACQUIRE_LOCK	1

#define MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX	2
#define HDMI_RX_ID				0x8001
#define ADM_PP_PARAM_MUTE_ID			0
#define ADM_PP_PARAM_MUTE_BIT			1
#define ADM_PP_PARAM_LATENCY_ID			1
#define ADM_PP_PARAM_LATENCY_BIT		2

enum {
	ADM_PP_PARAM_MUTE_ID,
	ADM_PP_PARAM_LATENCY_ID,
	ADM_PP_PARAM_LIMITER_ID
};

enum {
	ADM_PP_PARAM_MUTE_BIT		= 0x1,
	ADM_PP_PARAM_LATENCY_BIT	= 0x2,
	ADM_PP_PARAM_LIMITER_BIT	= 0x4
};

#define BE_DAI_PORT_SESSIONS_IDX_MAX		4
#define BE_DAI_FE_SESSIONS_IDX_MAX		2

+100 −8
Original line number Diff line number Diff line
@@ -48,12 +48,6 @@
#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF
#endif

/* ENUM for adm_status */
enum adm_cal_status {
	ADM_STATUS_CALIBRATION_REQUIRED = 0,
	ADM_STATUS_MAX,
};

struct adm_copp {

	atomic_t id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT];
@@ -1413,6 +1407,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
			case ADM_CMD_DEVICE_OPEN_V5:
			case ADM_CMD_DEVICE_CLOSE_V5:
			case ADM_CMD_DEVICE_OPEN_V6:
			case ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1:
				pr_debug("%s: Basic callback received, wake up.\n",
					__func__);
				atomic_set(&this_adm.copp.stat[port_idx]
@@ -2695,6 +2690,97 @@ fail_cmd:
	return;
}


static int adm_set_mtmx_params_v1(int port_idx, int copp_idx,
				  int params_length, void *params)
{
	struct adm_cmd_set_mtmx_params_v1 *adm_params = NULL;
	int rc = 0;
	int sz;

	sz = sizeof(*adm_params) + params_length;
	adm_params = kzalloc(sz, GFP_KERNEL);
	if (!adm_params)
		return -ENOMEM;

	memcpy(((u8 *)adm_params + sizeof(*adm_params)),
			params, params_length);
	adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	adm_params->hdr.pkt_size = sz;
	adm_params->hdr.src_svc = APR_SVC_ADM;
	adm_params->hdr.src_domain = APR_DOMAIN_APPS;
	adm_params->hdr.src_port = 0;
	adm_params->hdr.dest_svc = APR_SVC_ADM;
	adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
	adm_params->hdr.dest_port =
			atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
	adm_params->hdr.token = port_idx << 16 | copp_idx;
	adm_params->hdr.opcode = ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1;
	adm_params->payload_addr_lsw = 0;
	adm_params->payload_addr_msw = 0;
	adm_params->mem_map_handle = 0;
	adm_params->payload_size = params_length;
	adm_params->copp_id = atomic_read(&this_adm.copp.
					  id[port_idx][copp_idx]);

	atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
	rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
	if (rc < 0) {
		pr_err("%s: Set params failed port_idx = 0x%x rc %d\n",
			__func__, port_idx, rc);
		rc = -EINVAL;
		goto send_param_return;
	}
	/* Wait for the callback */
	rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
		atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
		msecs_to_jiffies(TIMEOUT_MS));
	if (!rc) {
		pr_err("%s: Set params timed out port_idx = 0x%x\n",
			 __func__, port_idx);
		rc = -EINVAL;
		goto send_param_return;
	} else if (atomic_read(&this_adm.copp.stat
				[port_idx][copp_idx]) > 0) {
		pr_err("%s: DSP returned error[%s]\n",
				__func__, adsp_err_get_err_str(
				atomic_read(&this_adm.copp.stat
				[port_idx][copp_idx])));
		rc = adsp_err_get_lnx_err_code(
				atomic_read(&this_adm.copp.stat
					[port_idx][copp_idx]));
		goto send_param_return;
	}
	rc = 0;
send_param_return:
	kfree(adm_params);
	return rc;
}

static void adm_enable_mtmx_limiter(int port_idx, int copp_idx)
{
	int rc;
	struct enable_param_v6 adm_param = { {0} };

	adm_param.param.module_id = ADM_MTMX_MODULE_STREAM_LIMITER;
	adm_param.param.param_id = AUDPROC_PARAM_ID_ENABLE;
	adm_param.param.param_size = sizeof(adm_param.enable);
	adm_param.enable = 1;

	rc = adm_set_mtmx_params_v1(port_idx, copp_idx,
				    sizeof(adm_param), &adm_param);
	if (rc < 0) {
		pr_err("%s: adm_set_mtmx_params_v1 failed port_idx = 0x%x rc %d\n",
			__func__, port_idx, rc);
		goto done;
	}
	set_bit(ADM_STATUS_LIMITER,
		(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
done:
	return;
}

static void route_set_opcode_matrix_id(
			struct adm_cmd_matrix_map_routings_v5 **route_addr,
			int path, uint32_t passthr_mode)
@@ -2791,6 +2877,11 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode,
		copp_idx = payload_map.copp_idx[i];
		copps_list[i] = atomic_read(&this_adm.copp.id[port_idx]
							     [copp_idx]);
		if (test_bit(ADM_STATUS_LIMITER,
		    (void *)&payload_map.route_status) &&
		    ((path == ADM_PATH_PLAYBACK) ||
		     (path == ADM_PATH_COMPRESSED_RX)))
			adm_enable_mtmx_limiter(port_idx, copp_idx);
	}
	atomic_set(&this_adm.matrix_map_stat, -1);

@@ -2991,6 +3082,8 @@ int adm_close(int port_id, int perf_mode, int copp_idx)

		clear_bit(ADM_STATUS_CALIBRATION_REQUIRED,
			(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
		clear_bit(ADM_STATUS_LIMITER,
			(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);

		ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
		if (ret < 0) {
@@ -4807,8 +4900,7 @@ static int __init adm_init(void)
				&this_adm.copp.adm_delay_wait[i][j]);
			atomic_set(&this_adm.copp.topology[i][j], 0);
			this_adm.copp.adm_delay[i][j] = 0;
			this_adm.copp.adm_status[i][j] =
				ADM_STATUS_CALIBRATION_REQUIRED;
			this_adm.copp.adm_status[i][j] = 0;
		}
	}