Browse Source

ASoC: enable dynamic FFECNS effect control

Add interface for userspace to control FFECNS effect.

Change-Id: I78010899e6c193726a79d74e86f13a1546106eff
Signed-off-by: Xiaojun Sang <[email protected]>
Xiaojun Sang 5 years ago
parent
commit
dc9e8c2006
4 changed files with 112 additions and 0 deletions
  1. 48 0
      asoc/msm-qti-pp-config.c
  2. 54 0
      dsp/q6adm.c
  3. 8 0
      include/dsp/apr_audio-v2.h
  4. 2 0
      include/dsp/q6adm-v2.h

+ 48 - 0
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 */

+ 54 - 0
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(&param_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);
 

+ 8 - 0
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.
  */

+ 2 - 0
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,