Browse Source

Merge "asoc: add support to get Direction of Arrival target scores"

Linux Build Service Account 6 years ago
parent
commit
bed688a58c
6 changed files with 270 additions and 4 deletions
  1. 66 2
      asoc/msm-pcm-routing-v2.c
  2. 75 0
      dsp/q6adm.c
  3. 101 2
      dsp/q6afe.c
  4. 24 0
      include/dsp/apr_audio-v2.h
  5. 2 0
      include/dsp/q6adm-v2.h
  6. 2 0
      include/dsp/q6afe-v2.h

+ 66 - 2
asoc/msm-pcm-routing-v2.c

@@ -17570,7 +17570,11 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type,
 	}
 
 	for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
-			 MSM_FRONTEND_DAI_MM_SIZE) {
+			 MSM_FRONTEND_DAI_MAX) {
+		if (!(is_mm_lsm_fe_id(i) &&
+				route_check_fe_id_adm_support(i)))
+			continue;
+
 		for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
 			copp = session_copp_map[i]
 				[session_type][be_idx];
@@ -17582,7 +17586,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type,
 		else
 			break;
 	}
-	if (i >= MSM_FRONTEND_DAI_MM_SIZE) {
+	if (i >= MSM_FRONTEND_DAI_MAX) {
 		pr_debug("%s: Invalid FE, exiting\n", __func__);
 
 		ret = -EINVAL;
@@ -17768,6 +17772,59 @@ done:
 	return ret;
 }
 
+static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = sizeof(struct doa_tracking_mon_param);
+
+	return 0;
+}
+
+static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = 0;
+	struct doa_tracking_mon_param doa_tracking_data;
+	int port_id, copp_idx;
+
+	memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param));
+	ret = msm_audio_sound_focus_derive_port_id(kcontrol,
+				"Doa Tracking Monitor Listen ", &port_id);
+	if (ret) {
+		pr_err("%s: Error in deriving port id, err=%d\n",
+			  __func__, ret);
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/*
+	 * If copp id exists for given port id, query adm to get doa data.
+	 * Else query afe for doa tracking params.
+	 * This is to support in cases where LSM directly connects to
+	 * AFE for FFNS.
+	 */
+	ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX,
+					    &copp_idx);
+	if (!ret)
+		ret = adm_get_doa_tracking_mon(port_id, copp_idx,
+					&doa_tracking_data);
+	else
+		ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data);
+
+	if (ret) {
+		pr_err("%s: Error getting Doa Tracking Params, err=%d\n",
+			  __func__, ret);
+		ret = -EINVAL;
+		goto done;
+	}
+
+	memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data,
+		sizeof(struct doa_tracking_mon_param));
+done:
+	return ret;
+}
+
 static const struct snd_kcontrol_new msm_source_tracking_controls[] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -17949,6 +18006,13 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = {
 		.info	= msm_source_tracking_info,
 		.get	= msm_audio_source_tracking_get,
 	},
+	{
+		.access = SNDRV_CTL_ELEM_ACCESS_READ,
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name	= "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0",
+		.info	= msm_doa_tracking_mon_info,
+		.get	= msm_doa_tracking_mon_get,
+	},
 };
 
 static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol,

+ 75 - 0
dsp/q6adm.c

@@ -4999,6 +4999,81 @@ done:
 }
 EXPORT_SYMBOL(adm_get_source_tracking);
 
+/**
+ * adm_get_doa_tracking_mon -
+ *        Retrieve doa tracking monitor info
+ *
+ * @port_id: Port ID number
+ * @copp_idx: copp index assigned
+ * @doa_tracking_data: pointer for doa data to be updated with
+ *
+ * Returns 0 on success or error on failure
+ */
+int adm_get_doa_tracking_mon(int port_id, int copp_idx,
+	struct doa_tracking_mon_param *doa_tracking_data)
+{
+	int ret = 0, i;
+	char *params_value;
+	uint32_t max_param_size = 0;
+	struct adm_param_doa_tracking_mon_t *doa_tracking_params = NULL;
+	struct param_hdr_v3 param_hdr;
+
+	pr_debug("%s: Enter, port_id %d, copp_idx %d\n",
+		 __func__, port_id, copp_idx);
+
+	if (doa_tracking_data == NULL) {
+		pr_err("%s: Received NULL pointer for doa tracking data\n",
+			 __func__);
+		return -EINVAL;
+	}
+
+	max_param_size = sizeof(struct adm_param_doa_tracking_mon_t) +
+			 sizeof(union param_hdrs);
+	params_value = kzalloc(max_param_size, GFP_KERNEL);
+	if (!params_value)
+		return -ENOMEM;
+
+	memset(&param_hdr, 0, sizeof(param_hdr));
+	param_hdr.module_id = AUDPROC_MODULE_ID_FFECNS;
+	param_hdr.instance_id = INSTANCE_ID_0;
+	param_hdr.param_id = AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR;
+	param_hdr.param_size = max_param_size;
+	ret = adm_get_pp_params(port_id, copp_idx,
+				ADM_CLIENT_ID_DEFAULT, NULL, &param_hdr,
+				params_value);
+	if (ret) {
+		pr_err("%s: get parameters failed ret:%d\n", __func__, ret);
+		goto done;
+	}
+
+	doa_tracking_params =
+		(struct adm_param_doa_tracking_mon_t *)params_value;
+	for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) {
+		doa_tracking_data->target_angle_L16[i] =
+			doa_tracking_params->target_angle_L16[i];
+		pr_debug("%s: target angle[%d] = %d\n",
+			 __func__, i, doa_tracking_data->target_angle_L16[i]);
+	}
+
+	for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) {
+		doa_tracking_data->interf_angle_L16[i] =
+			doa_tracking_params->interf_angle_L16[i];
+		pr_debug("%s: interference angle[%d] = %d\n",
+			 __func__, i, doa_tracking_data->interf_angle_L16[i]);
+	}
+
+	for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) {
+		doa_tracking_data->polar_activity[i] =
+			doa_tracking_params->polar_activity[i];
+	}
+
+done:
+	pr_debug("%s: Exit, ret = %d\n", __func__, ret);
+	kfree(params_value);
+	return ret;
+}
+EXPORT_SYMBOL(adm_get_doa_tracking_mon);
+
 int __init adm_init(void)
 {
 	int i = 0, j;

+ 101 - 2
dsp/q6afe.c

@@ -122,6 +122,7 @@ struct afe_ctl {
 	struct afe_sp_th_vi_get_param_resp	th_vi_resp;
 	struct afe_sp_ex_vi_get_param_resp	ex_vi_resp;
 	struct afe_av_dev_drift_get_param_resp	av_dev_drift_resp;
+	struct afe_doa_tracking_mon_get_param_resp	doa_tracking_mon_resp;
 	int vi_tx_port;
 	int vi_rx_port;
 	uint32_t afe_sample_rates[AFE_MAX_PORTS];
@@ -264,12 +265,60 @@ static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload,
 	if (!this_afe.av_dev_drift_resp.status) {
 		atomic_set(&this_afe.state, 0);
 	} else {
-		pr_debug("%s: av_dev_drift_resp status: %d", __func__,
+		pr_debug("%s: av_dev_drift_resp status: %d\n", __func__,
 			 this_afe.av_dev_drift_resp.status);
 		atomic_set(&this_afe.state, -1);
 	}
 }
 
+static void doa_tracking_mon_afe_cb_handler(uint32_t opcode, uint32_t *payload,
+					uint32_t payload_size)
+{
+	size_t expected_size =
+		sizeof(u32) + sizeof(struct doa_tracking_mon_param);
+
+	switch (opcode) {
+	case AFE_PORT_CMDRSP_GET_PARAM_V2:
+		expected_size += sizeof(struct param_hdr_v1);
+		if (payload_size < expected_size) {
+			pr_err("%s: Error: received size %d, expected size %zu\n",
+				 __func__, payload_size, expected_size);
+			return;
+		}
+		/* Repack response to add IID */
+		this_afe.doa_tracking_mon_resp.status = payload[0];
+		this_afe.doa_tracking_mon_resp.pdata.module_id = payload[1];
+		this_afe.doa_tracking_mon_resp.pdata.instance_id =
+			INSTANCE_ID_0;
+		this_afe.doa_tracking_mon_resp.pdata.param_id = payload[2];
+		this_afe.doa_tracking_mon_resp.pdata.param_size = payload[3];
+		memcpy(&this_afe.doa_tracking_mon_resp.doa, &payload[4],
+			sizeof(struct doa_tracking_mon_param));
+		break;
+	case AFE_PORT_CMDRSP_GET_PARAM_V3:
+		expected_size += sizeof(struct param_hdr_v3);
+		if (payload_size < expected_size) {
+			pr_err("%s: Error: received size %d, expected size %zu\n",
+				 __func__, payload_size, expected_size);
+			return;
+		}
+		memcpy(&this_afe.doa_tracking_mon_resp, payload,
+			sizeof(this_afe.doa_tracking_mon_resp));
+		break;
+	default:
+		pr_err("%s: Unrecognized command %d\n", __func__, opcode);
+		return;
+	}
+
+	if (!this_afe.doa_tracking_mon_resp.status) {
+		atomic_set(&this_afe.state, 0);
+	} else {
+		pr_debug("%s: doa_tracking_mon_resp status: %d\n", __func__,
+			 this_afe.doa_tracking_mon_resp.status);
+		atomic_set(&this_afe.state, -1);
+	}
+}
+
 static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
 				    uint32_t payload_size)
 {
@@ -479,7 +528,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
 		param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ?
 				   payload[3] :
 				   payload[2];
-		if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
+		if (param_id == AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR) {
+			doa_tracking_mon_afe_cb_handler(data->opcode,
+				data->payload, data->payload_size);
+		} else if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
 			av_dev_drift_afe_cb_handler(data->opcode, data->payload,
 						    data->payload_size);
 		} else {
@@ -7352,6 +7404,53 @@ exit:
 }
 EXPORT_SYMBOL(afe_get_av_dev_drift);
 
+/**
+ * afe_get_doa_tracking_mon -
+ *       command to retrieve doa tracking monitor data
+ *
+ * @port: AFE port ID
+ * @doa_tracking_data: param to be updated with doa tracking data
+ *
+ * Returns 0 on success or error on failure
+ */
+int afe_get_doa_tracking_mon(u16 port,
+		struct doa_tracking_mon_param *doa_tracking_data)
+{
+	struct param_hdr_v3 param_hdr;
+	int ret = -EINVAL, i = 0;
+
+	if (!doa_tracking_data) {
+		pr_err("%s: Invalid params\n", __func__);
+		goto exit;
+	}
+
+	memset(&param_hdr, 0, sizeof(param_hdr));
+	param_hdr.module_id = AUDPROC_MODULE_ID_FFNS;
+	param_hdr.instance_id = INSTANCE_ID_0;
+	param_hdr.param_id = AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR;
+	param_hdr.param_size = sizeof(struct doa_tracking_mon_param);
+
+	ret = q6afe_get_params(port, NULL, &param_hdr);
+	if (ret < 0) {
+		pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
+			 __func__, port, param_hdr.param_id, ret);
+		goto exit;
+	}
+
+	memcpy(doa_tracking_data, &this_afe.doa_tracking_mon_resp.doa,
+			param_hdr.param_size);
+	for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) {
+		pr_debug("%s: target angle[%d] = %d\n",
+			 __func__, i, doa_tracking_data->target_angle_L16[i]);
+		pr_debug("%s: interference angle[%d] = %d\n",
+			 __func__, i, doa_tracking_data->interf_angle_L16[i]);
+	}
+
+exit:
+	return ret;
+}
+EXPORT_SYMBOL(afe_get_doa_tracking_mon);
+
 int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
 {
 	struct param_hdr_v3 param_hdr;

+ 24 - 0
include/dsp/apr_audio-v2.h

@@ -12189,6 +12189,7 @@ struct adm_set_compressed_device_latency {
 #define MAX_SECTORS                                         8
 #define MAX_NOISE_SOURCE_INDICATORS                         3
 #define MAX_POLAR_ACTIVITY_INDICATORS                       360
+#define MAX_DOA_TRACKING_ANGLES                             2
 
 struct sound_focus_param {
 	uint16_t start_angle[MAX_SECTORS];
@@ -12203,6 +12204,12 @@ struct source_tracking_param {
 	uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS];
 } __packed;
 
+struct doa_tracking_mon_param {
+	uint16_t target_angle_L16[MAX_DOA_TRACKING_ANGLES];
+	uint16_t interf_angle_L16[MAX_DOA_TRACKING_ANGLES];
+	uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS];
+} __packed;
+
 struct adm_param_fluence_soundfocus_t {
 	uint16_t start_angles[MAX_SECTORS];
 	uint8_t enables[MAX_SECTORS];
@@ -12217,6 +12224,18 @@ struct adm_param_fluence_sourcetracking_t {
 	uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS];
 } __packed;
 
+struct adm_param_doa_tracking_mon_t {
+	uint16_t target_angle_L16[MAX_DOA_TRACKING_ANGLES];
+	uint16_t interf_angle_L16[MAX_DOA_TRACKING_ANGLES];
+	uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS];
+} __packed;
+
+struct afe_doa_tracking_mon_get_param_resp {
+	uint32_t status;
+	struct param_hdr_v3 pdata;
+	struct doa_tracking_mon_param doa;
+} __packed;
+
 #define AUDPROC_MODULE_ID_AUDIOSPHERE               0x00010916
 #define AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE         0x00010917
 #define AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH       0x00010918
@@ -12232,6 +12251,11 @@ struct adm_param_fluence_sourcetracking_t {
 #define AUDPROC_MODULE_ID_VOICE_TX_SECNS   0x10027059
 #define AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH 0x10014444
 
+#define AUDPROC_MODULE_ID_FFECNS 0x00010952
+#define AUDPROC_MODULE_ID_FFNS 0x00010962
+#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_PARAM 0x11003
+#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x11004
+
 struct admx_sec_primary_mic_ch {
 	uint16_t version;
 	uint16_t reserved;

+ 2 - 0
include/dsp/q6adm-v2.h

@@ -191,6 +191,8 @@ int adm_get_sound_focus(int port_id, int copp_idx,
 			struct sound_focus_param *soundFocusData);
 int adm_get_source_tracking(int port_id, int copp_idx,
 			    struct source_tracking_param *sourceTrackingData);
+int adm_get_doa_tracking_mon(int port_id, int copp_idx,
+			    struct doa_tracking_mon_param *doa_tracking_data);
 int adm_set_custom_chmix_cfg(int port_id, int copp_idx,
 			     unsigned int session_id, char *params,
 			     uint32_t params_length, int direction,

+ 2 - 0
include/dsp/q6afe-v2.h

@@ -449,4 +449,6 @@ int afe_send_port_island_mode(u16 port_id);
 int afe_send_cmd_wakeup_register(void *handle, bool enable);
 void afe_register_wakeup_irq_callback(
 	void (*afe_cb_wakeup_irq)(void *handle));
+int afe_get_doa_tracking_mon(u16 port_id,
+	struct doa_tracking_mon_param *doa_tracking_data);
 #endif /* __Q6AFE_V2_H__ */