asoc: codecs: bolero: Add HPH power modes on bolero

Two power modes are supported on bolero digital.
Add support to set required power mode using
mixer control and enable runtime during powerup
sequence.

Change-Id: I4c5a7560984d60745ac98848f1eec1d1f8485323
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index 986375d..4624eae 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -344,6 +344,7 @@
 	bool is_native_on;
 	bool is_ear_mode_on;
 	bool dev_up;
+	bool hph_pwr_mode;
 	u16 mclk_mux;
 	struct mutex mclk_lock;
 	struct mutex swr_clk_lock;
@@ -432,6 +433,10 @@
 static const struct soc_enum rx_macro_ear_mode_enum =
 	SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text);
 
+static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LoHIFI"};
+static const struct soc_enum rx_macro_hph_pwr_mode_enum =
+	SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text);
+
 static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"};
 static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum =
 	SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text);
@@ -1689,6 +1694,34 @@
 	return 0;
 }
 
+static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct device *rx_dev = NULL;
+	struct rx_macro_priv *rx_priv = NULL;
+
+	if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode;
+	return 0;
+}
+
+static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct device *rx_dev = NULL;
+	struct rx_macro_priv *rx_priv = NULL;
+
+	if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0];
+	return 0;
+}
+
 static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -1944,6 +1977,8 @@
 					hph_lut_bypass_reg,
 					0x80, 0x80);
 		}
+		if (rx_priv->hph_pwr_mode)
+			snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x00);
 	}
 
 	if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
@@ -1952,7 +1987,7 @@
 		snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
 					0x02, 0x00);
 		snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00);
-		snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0);
+		snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20);
 	}
 }
 
@@ -2375,6 +2410,9 @@
 	SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
 		rx_macro_get_ear_mode, rx_macro_put_ear_mode),
 
+	SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum,
+		rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode),
+
 	SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum,
 			rx_macro_vbat_bcl_gsm_mode_func_get,
 			rx_macro_vbat_bcl_gsm_mode_func_put),