diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 4534c4cbae..c205601355 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -4986,6 +4986,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(¶m_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, ¶m_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; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e23..aa83dd37e5 100644 --- a/dsp/q6afe.c +++ b/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 { @@ -7350,6 +7402,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(¶m_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, ¶m_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; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 6193209b49..1199fa11f1 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12188,6 +12188,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]; @@ -12202,6 +12203,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]; @@ -12216,6 +12223,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 @@ -12231,6 +12250,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; diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 95fbb0d1fc..d65e6d49b3 100644 --- a/include/dsp/q6adm-v2.h +++ b/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, diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ec2a4368ab..9954d24a8f 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -448,4 +448,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__ */