power: pm8921-charger: api to control input regulation

The pmic charger can take measures such as reducing charing
current if the input charger voltage falls below certain point.
Create api to use this feature.

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 976e351..65f3150 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -197,6 +197,7 @@
 	int			weak_voltage;
 	int			trkl_current;
 	int			weak_current;
+	int			vin_min;
 };
 
 static int charging_disabled;
@@ -345,6 +346,26 @@
 	return pm_chg_masked_write(chip, CHG_VBAT_DET, PM8921_CHG_V_MASK, temp);
 }
 
+#define PM8921_CHG_VINMIN_MIN_MV	3800
+#define PM8921_CHG_VINMIN_STEP_MV	100
+#define PM8921_CHG_VINMIN_USABLE_MAX	6500
+#define PM8921_CHG_VINMIN_USABLE_MIN	4300
+#define PM8921_CHG_VINMIN_MASK		0x1F
+static int pm_chg_vinmin_set(struct pm8921_chg_chip *chip, int voltage)
+{
+	u8 temp;
+
+	if (voltage < PM8921_CHG_VINMIN_USABLE_MIN
+			|| voltage > PM8921_CHG_VINMIN_USABLE_MAX) {
+		pr_err("bad mV=%d asked to set\n", voltage);
+		return -EINVAL;
+	}
+	temp = (voltage - PM8921_CHG_VINMIN_MIN_MV) / PM8921_CHG_VINMIN_STEP_MV;
+	pr_debug("voltage=%d setting %02x\n", voltage, temp);
+	return pm_chg_masked_write(chip, CHG_VIN_MIN, PM8921_CHG_VINMIN_MASK,
+									temp);
+}
+
 #define PM8921_CHG_IBATMAX_MIN	325
 #define PM8921_CHG_IBATMAX_MAX	2000
 #define PM8921_CHG_I_MIN_MA	225
@@ -1046,6 +1067,15 @@
 }
 EXPORT_SYMBOL(pm8921_disable_source_current);
 
+int pm8921_regulate_input_voltage(int voltage)
+{
+	if (!the_chip) {
+		pr_err("called before init\n");
+		return -EINVAL;
+	}
+	return pm_chg_vinmin_set(the_chip, voltage);
+}
+
 bool pm8921_is_battery_charging(int *source)
 {
 	int fsm_state, is_charging, dc_present, usb_present;
@@ -1698,6 +1728,15 @@
 		}
 	}
 
+	if (chip->vin_min != 0) {
+		rc = pm_chg_vinmin_set(chip, chip->vin_min);
+		if (rc) {
+			pr_err("Failed to set vin min to %d mV rc=%d\n",
+							chip->vin_min, rc);
+			return rc;
+		}
+	}
+
 	rc = pm_chg_disable_wd(chip);
 	if (rc) {
 		pr_err("Failed to disable wd rc=%d\n", rc);
@@ -1957,6 +1996,7 @@
 	chip->weak_voltage = pdata->weak_voltage;
 	chip->trkl_current = pdata->trkl_current;
 	chip->weak_current = pdata->weak_current;
+	chip->vin_min = pdata->vin_min;
 
 	rc = pm8921_chg_hw_init(chip);
 	if (rc) {