Browse Source

Merge "asoc: codecs: Change LPASS DRE to use WSA sys_gain and bat_cfg"

qctecmdr 3 years ago
parent
commit
dde20c8484
2 changed files with 91 additions and 20 deletions
  1. 42 15
      asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c
  2. 49 5
      asoc/codecs/wsa884x/wsa884x.c

+ 42 - 15
asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c

@@ -130,19 +130,6 @@ enum {
 	INTn_2_INP_SEL_RX8,
 };
 
-enum {
-	WSA_MODE_21DB,
-	WSA_MODE_19P5DB,
-	WSA_MODE_18DB,
-	WSA_MODE_16P5DB,
-	WSA_MODE_15DB,
-	WSA_MODE_13P5DB,
-	WSA_MODE_12DB,
-	WSA_MODE_10P5DB,
-	WSA_MODE_9DB,
-	WSA_MODE_MAX
-};
-
 enum {
 	INTERP_RX0,
 	INTERP_RX1
@@ -160,7 +147,7 @@ enum {
 	INTERP_MIX_PATH,
 };
 
-static struct lpass_cdc_comp_setting comp_setting_table[WSA_MODE_MAX] = {
+static struct lpass_cdc_comp_setting comp_setting_table[G_MAX_DB] = {
 	{42, 0, 42},
 	{39, 0, 42},
 	{36, 0, 42},
@@ -1454,7 +1441,9 @@ static int lpass_cdc_wsa_macro_config_compander(struct snd_soc_component *compon
 	u16 comp_ctl0_reg, comp_ctl8_reg, rx_path_cfg0_reg;
 	struct device *wsa_dev = NULL;
 	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	struct lpass_cdc_comp_setting *comp_settings = NULL;
 	u16 mode = 0;
+	int sys_gain, bat_cfg, sys_gain_int, upper_gain, lower_gain;
 
 	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
 		return -EINVAL;
@@ -1472,11 +1461,49 @@ static int lpass_cdc_wsa_macro_config_compander(struct snd_soc_component *compon
 					(comp * LPASS_CDC_WSA_MACRO_RX_COMP_OFFSET);
 	rx_path_cfg0_reg = LPASS_CDC_WSA_RX0_RX_PATH_CFG0 +
 					(comp * LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET);
+	comp_settings = &comp_setting_table[mode];
+
+	/* If System has battery configuration */
+	if (wsa_priv->wsa_bat_cfg[comp]) {
+		sys_gain = wsa_priv->wsa_sys_gain[comp * 2 + wsa_priv->wsa_spkrrecv];
+		bat_cfg = wsa_priv->wsa_bat_cfg[comp];
+		/* Convert enum to value and
+		 * multiply all values by 10 to avoid float
+		 */
+		sys_gain_int = -15 * sys_gain + 210;
+		switch (bat_cfg) {
+		case CONFIG_1S:
+		case EXT_1S:
+			if (sys_gain > G_13P5_DB) {
+				upper_gain = sys_gain_int + 60;
+				lower_gain = 0;
+			} else {
+				upper_gain = 210;
+				lower_gain = 0;
+			}
+			break;
+		case CONFIG_3S:
+		case EXT_3S:
+			upper_gain = sys_gain_int;
+			lower_gain = 75;
+		case EXT_ABOVE_3S:
+			upper_gain = sys_gain_int;
+			lower_gain = 120;
+			break;
+		default:
+			upper_gain = sys_gain_int;
+			lower_gain = 0;
+			break;
+		}
+		/* Truncate after calculation */
+		comp_settings->lower_gain_int = (lower_gain * 2) / 10;
+		comp_settings->upper_gain_int = (upper_gain * 2) / 10;
+	}
 
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
 		lpass_cdc_update_compander_setting(component,
 					comp_ctl8_reg,
-					&comp_setting_table[mode]);
+					comp_settings);
 		/* Enable Compander Clock */
 		snd_soc_component_update_bits(component, comp_ctl0_reg,
 						0x01, 0x01);

+ 49 - 5
asoc/codecs/wsa884x/wsa884x.c

@@ -39,6 +39,7 @@
 #define HIGH_TEMP_THRESHOLD 45
 #define TEMP_INVALID	0xFFFF
 #define WSA884X_TEMP_RETRY 3
+#define WSA884X_IRQ_RETRY 2
 #define PBR_MAX_VOLTAGE 20
 #define PBR_MAX_CODE 255
 #define WSA884X_IDLE_DETECT_NG_BLOCK_MASK	0x38
@@ -191,13 +192,41 @@ static int wsa884x_handle_post_irq(void *data)
 {
 	struct wsa884x_priv *wsa884x = data;
 	u32 sts1 = 0, sts2 = 0;
+	int retry = WSA884X_IRQ_RETRY;
 
-	regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS0, &sts1);
-	regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS1, &sts2);
+	struct snd_soc_component *component = NULL;
 
-	wsa884x->swr_slave->slave_irq_pending =
-			((sts1 || sts2) ? true : false);
+	if (!wsa884x)
+		return IRQ_NONE;
 
+	component = wsa884x->component;
+	if (!wsa884x->pa_mute) {
+		do {
+			wsa884x->pa_mute = 0;
+			snd_soc_component_update_bits(component,
+				REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01));
+			usleep_range(1000, 1100);
+
+			regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS0, &sts1);
+			regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS1, &sts2);
+
+			wsa884x->swr_slave->slave_irq_pending =
+					((sts1 || sts2) ? true : false);
+			pr_debug("%s: IRQs Sts0: %x, Sts1: %x\n", __func__,
+				 sts1, sts2);
+			if (wsa884x->swr_slave->slave_irq_pending) {
+				pr_debug("%s: IRQ retries left: %0d\n",
+					__func__, retry);
+				snd_soc_component_update_bits(component,
+					REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00));
+				wsa884x->pa_mute = 1;
+				if (retry--)
+					usleep_range(1000, 1100);
+			} else {
+				break;
+			}
+		} while (retry);
+	}
 	return IRQ_HANDLED;
 }
 
@@ -493,6 +522,17 @@ static irqreturn_t wsa884x_clip_handle_irq(int irq, void *data)
 
 static irqreturn_t wsa884x_pdm_wd_handle_irq(int irq, void *data)
 {
+	struct wsa884x_priv *wsa884x = data;
+	struct snd_soc_component *component = NULL;
+
+	if (!wsa884x)
+		return IRQ_NONE;
+	component = wsa884x->component;
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PDM_WD_CTL, PDM_WD_EN, 0x00));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PDM_WD_CTL, PDM_WD_EN, 0x01));
+
 	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
 			   __func__, irq);
 	return IRQ_HANDLED;
@@ -532,6 +572,8 @@ static irqreturn_t wsa884x_pa_on_err_handle_irq(int irq, void *data)
 	if (!component)
 		return IRQ_NONE;
 
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00));
 	pa_fsm_sta = (snd_soc_component_read(component, WSA884X_PA_FSM_STA1)
 			& 0x1F);
 	if (pa_fsm_sta)
@@ -1383,7 +1425,8 @@ static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w,
 		/* Force remove group */
 		swr_remove_from_group(wsa884x->swr_slave,
 				      wsa884x->swr_slave->dev_num);
-		if (test_bit(SPKR_ADIE_LB, &wsa884x->status_mask))
+		if (test_bit(SPKR_ADIE_LB, &wsa884x->status_mask) &&
+		    !wsa884x->pa_mute)
 			snd_soc_component_update_bits(component,
 				REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01));
 		break;
@@ -1394,6 +1437,7 @@ static int wsa884x_spkr_event(struct snd_soc_dapm_widget *w,
 			REG_FIELD_VALUE(PDM_WD_CTL, PDM_WD_EN, 0x00));
 		clear_bit(SPKR_STATUS, &wsa884x->status_mask);
 		clear_bit(SPKR_ADIE_LB, &wsa884x->status_mask);
+		wsa884x->pa_mute = 0;
 		break;
 	}
 	return 0;