max77759_charger: set higher headroom on MW at high soc

Bug: 285158246
Change-Id: I4fd5d90e839e97ab435ca466db92c62984739781
Signed-off-by: Prasanna Prapancham <[email protected]>
(cherry picked from commit 9324f864dbb1f2294bd57d325ae2f6a255efab00)
diff --git a/max77759_charger.c b/max77759_charger.c
index e3bcf66..e3998d5 100644
--- a/max77759_charger.c
+++ b/max77759_charger.c
@@ -55,6 +55,9 @@
 #define CHGR_DTLS_OFF_JEITA				0x0c
 #define CHGR_DTLS_OFF_TEMP				0x0d
 
+#define CHGR_CHG_CNFG_12_VREG_4P6V			0x1
+#define CHGR_CHG_CNFG_12_VREG_4P7V			0x2
+
 static inline int max77759_reg_read(struct regmap *regmap, uint8_t reg,
 				    uint8_t *val)
 {
@@ -1856,6 +1859,37 @@
 	return 0;
 }
 
+static int max77759_higher_headroom_enable(struct max77759_chgr_data *data, bool flag)
+{
+	int ret = 0;
+	u8 reg, reg_rd, val = flag ? CHGR_CHG_CNFG_12_VREG_4P7V : CHGR_CHG_CNFG_12_VREG_4P6V;
+
+	ret = max77759_reg_read(data->regmap, MAX77759_CHG_CNFG_12, &reg);
+	if (ret < 0)
+		return ret;
+
+	reg_rd = reg;
+	ret = max77759_chg_prot(data->regmap, false);
+	if (ret < 0)
+		return ret;
+
+	reg = _chg_cnfg_12_vchgin_reg_set(reg, val);
+	ret = max77759_reg_write(data->regmap, MAX77759_CHG_CNFG_12, reg);
+	if (ret)
+		goto done;;
+
+	dev_dbg(data->dev, "%s: val: %#02x, reg: %#02x -> %#02x\n", __func__, val, reg_rd, reg);
+
+	ret = max77759_reg_read(data->regmap, MAX77759_CHG_CNFG_12, &reg);
+	if (ret)
+		goto done;
+
+done:
+	ret = max77759_chg_prot(data->regmap, true);
+	if (ret < 0)
+		dev_err(data->dev, "%s: error enabling prot (%d)\n", __func__, ret);
+	return ret < 0 ? ret : 0;
+}
 
 static int max77759_chg_is_valid(struct max77759_chgr_data *data)
 {
@@ -2180,6 +2214,10 @@
 		ret = max77759_set_regulation_voltage(data, pval->intval);
 		pr_debug("%s: charge_voltage=%d (%d)\n",
 			__func__, pval->intval, ret);
+		if (ret)
+			break;
+		if (max77759_is_online(data) && pval->intval >= data->chg_term_voltage * 1000)
+			ret = max77759_higher_headroom_enable(data, true);
 		break;
 	/* called from google_cpm when switching chargers */
 	case GBMS_PROP_CHARGING_ENABLED:
@@ -2791,6 +2829,10 @@
 		pr_debug("%s: INSEL insel_auto_clear=%d (%d)\n", __func__,
 			 data->insel_clear, data->insel_clear ? ret : 0);
 		atomic_inc(&data->insel_cnt);
+
+		ret = max77759_higher_headroom_enable(data, false); /* reset on plug/unplug */
+		if (ret)
+			return IRQ_NONE;
 	}
 
 #if IS_ENABLED(CONFIG_GOOGLE_BCL)