From 79038187084c65c8408c86220bb78abe01c6c8ce Mon Sep 17 00:00:00 2001 From: Deru Wang Date: Thu, 28 May 2020 22:11:52 +0800 Subject: [PATCH] asoc: add AFE logging PID and APIs The current AFE logging point is global, once enabled all active AFE ports will log its data through DIAG to PC, However, diag logging throughput is limited. Need add kcontrol for enable/disable AFE logging by AFE port per direction. Change-Id: I05a12f2eb4bc5b5a3ad39b8bbf2f4148bec05002 Signed-off-by: Deru Wang --- asoc/msm-dai-q6-v2.c | 99 ++++++++++++++++++++++++++++++++++++++ dsp/q6afe.c | 34 +++++++++++++ include/dsp/apr_audio-v2.h | 40 +++++++++++++++ include/dsp/q6afe-v2.h | 2 + 4 files changed, 175 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 92d20838433a..afec883e3265 100755 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -394,6 +394,12 @@ static const struct soc_enum tdm_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_header_type), tdm_header_type), }; +static u16 afe_port_logging_port_id; + +static bool afe_port_logging_item[IDX_TDM_MAX]; + +static int afe_port_loggging_control_added; + static DEFINE_MUTEX(tdm_mutex); static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX]; @@ -9272,6 +9278,87 @@ static int msm_dai_q6_tdm_set_clk( return rc; } +static int msm_pcm_afe_port_logging_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info* ucontrol) +{ + ucontrol->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + /* two int values: port_id and enable/disable */ + ucontrol->count = 2; + /* Valid range is all positive values to support above controls */ + ucontrol->value.integer.min = 0; + ucontrol->value.integer.max = INT_MAX; + return 0; +} + +static int msm_pcm_afe_port_logging_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int port_idx = afe_port_logging_port_id - AFE_PORT_ID_TDM_PORT_RANGE_START; + + ucontrol->value.integer.value[0] = afe_port_logging_port_id; + ucontrol->value.integer.value[1] = afe_port_logging_item[port_idx]; + + return 0; +} + +static int msm_pcm_afe_port_logging_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 port_id; + struct afe_param_id_port_data_log_disable_t log_disable; + struct param_hdr_v3 param_hdr; + int ret = -EINVAL, port_idx; + + pr_debug("%s: enter\n", __func__); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + port_id = ucontrol->value.integer.value[0]; + log_disable.disable_logging_flag = ucontrol->value.integer.value[1]; + + ret = afe_port_send_logging_cfg(port_id, &log_disable); + if (ret) + pr_err("%s: AFE port logging setting for port 0x%x failed %d\n", + __func__, port_id, ret); + + afe_port_logging_port_id = port_id; + port_idx = port_id - AFE_PORT_ID_TDM_PORT_RANGE_START; + afe_port_logging_item[port_idx] = ucontrol->value.integer.value[1]; + + return ret; +} + +static int msm_pcm_add_afe_port_logging_control(struct snd_soc_dai *dai) +{ + const char* afe_port_logging_ctl_name = "AFE_port_logging_disable"; + int rc = 0; + struct snd_kcontrol_new *knew = NULL; + struct snd_kcontrol* kctl = NULL; + + /* Add AFE port logging controls */ + knew = kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL); + if (!knew) { + return -ENOMEM; + } + knew->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + knew->info = msm_pcm_afe_port_logging_info; + knew->get = msm_pcm_afe_port_logging_ctl_get; + knew->put = msm_pcm_afe_port_logging_ctl_put; + knew->name = afe_port_logging_ctl_name; + knew->private_value = dai->id; + kctl = snd_ctl_new1(knew, knew); + if (!kctl) { + kfree(knew); + return -ENOMEM; + } + + rc = snd_ctl_add(dai->component->card->snd_card, kctl); + if (rc < 0) + pr_err("%s: err add AFE port logging disable control, DAI = %s\n", + __func__, dai->name); + + return rc; +} + static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) { int rc = 0; @@ -9348,6 +9435,18 @@ static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) } } + /* add AFE port logging controls */ + if (!afe_port_loggging_control_added) { + rc = msm_pcm_add_afe_port_logging_control(dai); + if (rc < 0) { + dev_err(dai->dev, "%s: add AFE port logging control failed DAI: %s\n", + __func__, dai->name); + goto rtn; + } + + afe_port_loggging_control_added = 1; + } + if (tdm_dai_data->is_island_dai) rc = msm_dai_q6_add_island_mx_ctls( dai->component->card->snd_card, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6a145210f250..7ba22b1709d4 100755 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4800,6 +4800,40 @@ void afe_set_routing_callback(routing_cb cb) } EXPORT_SYMBOL(afe_set_routing_callback); +/** + * afe_port_send_logging_cfg - + * set AFE port logging status + * + * @port_id: AFE port id number + * @log_disable: logging payload + * + * Returns 0 on success or error value on set param failure + */ +int afe_port_send_logging_cfg(u16 port_id, + struct afe_param_id_port_data_log_disable_t *log_disable) +{ + struct param_hdr_v3 param_hdr; + int ret = -EINVAL; + + pr_debug("%s: enter, port: 0x%x logging flag: %x\n", __func__, port_id, + log_disable->disable_logging_flag); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_PORT_DATA_LOGGING_DISABLE; + param_hdr.param_size = sizeof(&log_disable); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), param_hdr, (u8*)log_disable); + if (ret) + pr_err("%s: AFE port logging setting for port 0x%x failed %d\n", + __func__, port_id, ret); + + return ret; +} +EXPORT_SYMBOL(afe_port_send_logging_cfg); + int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { struct afe_param_id_usb_audio_dev_params usb_dev; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 182a0c87b696..5abaf15a81e2 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -13414,4 +13414,44 @@ struct afe_param_id_tdm_lane_cfg { */ }; +/** ID of the parameter used to set the AFE port data logging to enable or disable state. + * For non-group device use cases, #AFE_MODULE_AUDIO_DEV_INTERFACE uses this + * parameter to configure the flag used for data logging in afe_data_logging_t + * of the respective port to enabled or disabled state. + * The HLOS client can use this parameter to configure the data logging + * disable flag for it's respective port. + * The reason for this parameter addition is if a number of ports are + * configured and running, Upon enabling logging through 0x1586 tap point, + * we will get input/output logs for all the enabled ports. + * In order to disabled logging for a specific port for which data logging + * is not needed, the HLOS client can make use of AFE_PORT_DATA_LOGGING_DISABLE flag. + * This flag will set to AFE_PORT_DATA_LOGGING_ENABLE during port initialization and also + * during port stop. If port is restarted, the set param should be called again + * by the HLOS client if needed to disable data logging. + * @par + * If HLOS client doesn't set this paramter, by default the disable flag = AFE_PORT_DATA_LOGGING_ENABLE. + * If HLOS client sets the flag = AFE_PORT_DATA_LOGGING_DISABLE, the respective port will be disabled for data logging. + */ +#define AFE_PARAM_ID_PORT_DATA_LOGGING_DISABLE 0x000102E9 + + /** Enable flag for port data logging. */ +#define AFE_PORT_DATA_LOGGING_ENABLE 0 + +/** Disable flag for port data logging. */ +#define AFE_PORT_DATA_LOGGING_DISABLE 1 + +/* + * Payload of the AFE_PARAM_ID_PORT_DATA_LOGGING_DISABLE parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE + */ +struct afe_param_id_port_data_log_disable_t +{ + uint32_t disable_logging_flag; + /** Flag for enabling or disabling data logging. + * @values + * - AFE_PORT_DATA_LOGGING_ENABLE - enable data logging. + * - AFE_PORT_DATA_LOGGING_DISABLE - disable data logging. + */ +} __packed; + #endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 5ac9637eae33..ba4e19be3535 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -520,6 +520,8 @@ int afe_send_custom_tdm_header_cfg( int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate, u16 num_groups); void afe_set_routing_callback(routing_cb cb); +int afe_port_send_logging_cfg(u16 port_id, + struct afe_param_id_port_data_log_disable_t *log_disable); int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); int afe_get_sp_rx_tmax_xmax_logging_data(