From dc9e8c20063e0d247810b90f06cfe6424b562cc5 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 13 May 2019 14:46:15 +0800 Subject: [PATCH] ASoC: enable dynamic FFECNS effect control Add interface for userspace to control FFECNS effect. Change-Id: I78010899e6c193726a79d74e86f13a1546106eff Signed-off-by: Xiaojun Sang --- asoc/msm-qti-pp-config.c | 48 +++++++++++++++++++++++++++++++++ dsp/q6adm.c | 54 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 8 ++++++ include/dsp/q6adm-v2.h | 2 ++ 4 files changed, 112 insertions(+) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 48a784ed8b5c..d2da56e94423 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -73,6 +73,7 @@ static const DECLARE_TLV_DB_LINEAR(sec_auxpcm_lb_vol_gain, 0, INT_RX_VOL_MAX_STEPS); static int msm_multichannel_ec_primary_mic_ch; +static int msm_ffecns_effect; static void msm_qti_pp_send_eq_values_(int eq_idx) { @@ -1364,6 +1365,50 @@ static const struct snd_kcontrol_new msm_multichannel_ec_controls[] = { msm_multichannel_ec_primary_mic_ch_put), }; +static char const *ffecns_effect_text[] = {"NO_EFFECT", "EC_ONLY", "NS_ONLY", "ECNS"}; + +static int msm_ffecns_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] >= ARRAY_SIZE(ffecns_effect_text)) { + pr_err("%s: invalid ffecns effect value %ld\n", + __func__, ucontrol->value.integer.value[0]); + return -EINVAL; + } + + msm_ffecns_effect = ucontrol->value.integer.value[0]; + + pr_debug("%s: set %s for ffecns\n", __func__, + ffecns_effect_text[msm_ffecns_effect]); + + ret = adm_set_ffecns_effect(msm_ffecns_effect); + if (ret) + pr_err("%s: failed to set %s for ffecns\n", + __func__, ffecns_effect_text[msm_ffecns_effect]); + + return ret; +} + +static int msm_ffecns_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ffecns_effect; + pr_debug("%s: ffecns effect = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static SOC_ENUM_SINGLE_EXT_DECL(ffecns_effect_enum, ffecns_effect_text); + +static const struct snd_kcontrol_new ec_ffecns_controls[] = { + SOC_ENUM_EXT("FFECNS Effect", ffecns_effect_enum, + msm_ffecns_get, msm_ffecns_put), +}; + static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = { SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0, INT_RX_VOL_GAIN, 0, msm_qti_pp_get_fm_vol_mixer, @@ -1668,5 +1713,8 @@ void msm_qti_pp_add_controls(struct snd_soc_component *component) snd_soc_add_component_controls(component, dsp_bit_width_controls, ARRAY_SIZE(dsp_bit_width_controls)); + + snd_soc_add_component_controls(component, ec_ffecns_controls, + ARRAY_SIZE(ec_ffecns_controls)); } #endif /* CONFIG_QTI_PP */ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a265b7be2494..29bf67fdc0d2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -101,6 +101,7 @@ struct adm_ctl { int num_ec_ref_rx_chans_downmixed; uint16_t ec_ref_chmixer_weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] [PCM_FORMAT_MAX_NUM_CHANNEL_V8]; + int ffecns_port_id; int native_mode; }; @@ -2985,6 +2986,12 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, rate = 16000; } + if (topology == FFECNS_TOPOLOGY) { + this_adm.ffecns_port_id = port_id; + pr_debug("%s: ffecns port id =%x\n", __func__, + this_adm.ffecns_port_id); + } + if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) channel_mode = 1; @@ -3842,6 +3849,10 @@ int adm_close(int port_id, int perf_mode, int copp_idx) pr_debug("%s: remove adm device from rtac\n", __func__); rtac_remove_adm_device(port_id, copp_id); } + + if (port_id == this_adm.ffecns_port_id) + this_adm.ffecns_port_id = -1; + return 0; } EXPORT_SYMBOL(adm_close); @@ -4442,6 +4453,48 @@ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch); +/** + * adm_set_ffecns_effect - + * command to set effect for ffecns module + * + * @effect: effect payload + * + * Returns 0 on success or error on failure + */ +int adm_set_ffecns_effect(int effect) +{ + struct ffecns_effect ffecns_params; + struct param_hdr_v3 param_hdr; + int rc = 0; + int copp_idx = 0; + + copp_idx = adm_get_default_copp_idx(this_adm.ffecns_port_id); + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s, no active copp to query rms copp_idx:%d\n", + __func__, copp_idx); + return -EINVAL; + } + + memset(&ffecns_params, 0, sizeof(ffecns_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = FFECNS_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = FLUENCE_CMN_GLOBAL_EFFECT_PARAM_ID; + param_hdr.param_size = sizeof(ffecns_params); + + ffecns_params.payload = effect; + + rc = adm_pack_and_set_one_pp_param(this_adm.ffecns_port_id, copp_idx, + param_hdr, (uint8_t *) &ffecns_params); + if (rc) + pr_err("%s: Failed to set ffecns effect, err %d\n", + __func__, rc); + + return rc; +} +EXPORT_SYMBOL(adm_set_ffecns_effect); + /** * adm_param_enable - * command to send params to ADM for given module @@ -5296,6 +5349,7 @@ int __init adm_init(void) int i = 0, j; this_adm.ec_ref_rx = -1; + this_adm.ffecns_port_id = -1; init_waitqueue_head(&this_adm.matrix_map_wait); init_waitqueue_head(&this_adm.adm_wait); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index a90cb05bcd6f..68c491ff2666 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12524,6 +12524,14 @@ struct admx_sec_primary_mic_ch { uint16_t reserved1; } __packed; +#define FFECNS_MODULE_ID 0x00010952 +#define FLUENCE_CMN_GLOBAL_EFFECT_PARAM_ID 0x00010EAF +#define FFECNS_TOPOLOGY 0X10028003 + +struct ffecns_effect { + uint32_t payload; +}; + /** ID of the Voice Activity Detection (VAD) module, which is used to * configure AFE VAD. */ diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index a48082b75cce..894bca40c816 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -178,6 +178,8 @@ int adm_set_mic_gain(int port_id, int copp_idx, int volume); int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int primary_mic_ch); +int adm_set_ffecns_effect(int effect); + int adm_param_enable(int port_id, int copp_idx, int module_id, int enable); int adm_param_enable_v2(int port_id, int copp_idx,