qcom-charger: smb-lib: support input limited state property

Add support to indicate if the switcher is acting in input limited state.
Switcher running in high duty cycle (HDC) mode should also be indicated as
input limited condition.
HDC is a 5uS pulse and sw reading the real time status register may not
indicate that it is active. Basically the presence of the pulses and the
interrupts indicate HDC and conversely their absence indicates no
HDC. Set a flag in the interrupt and clear it in a delayed work queue in
20mS. As long as the interrupts happen this flag will remain set,
indicating HDC.

Change-Id: Ia2e2d02240c36ba982f9e190b88b822b5f1b90f1
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index ee4f654..21b3301 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -988,6 +988,21 @@
 	return 0;
 }
 
+int smblib_get_prop_input_current_limited(struct smb_charger *chg,
+				union power_supply_propval *val)
+{
+	u8 stat;
+	int rc;
+
+	rc = smblib_read(chg, AICL_STATUS_REG, &stat);
+	if (rc < 0) {
+		dev_err(chg->dev, "Couldn't read AICL_STATUS rc=%d\n", rc);
+		return rc;
+	}
+	val->intval = (stat & SOFT_ILIMIT_BIT) || chg->is_hdc;
+	return 0;
+}
+
 /***********************
  * BATTERY PSY SETTERS *
  ***********************/
@@ -1965,6 +1980,17 @@
 	return IRQ_HANDLED;
 }
 
+irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data)
+{
+	struct smb_irq_data *irq_data = data;
+	struct smb_charger *chg = irq_data->parent_data;
+
+	chg->is_hdc = true;
+	schedule_delayed_work(&chg->clear_hdc_work, msecs_to_jiffies(60));
+
+	return IRQ_HANDLED;
+}
+
 /***************
  * Work Queues *
  ***************/
@@ -2054,6 +2080,14 @@
 	vote(chg->awake_votable, PL_VOTER, false, 0);
 }
 
+static void clear_hdc_work(struct work_struct *work)
+{
+	struct smb_charger *chg = container_of(work, struct smb_charger,
+						clear_hdc_work.work);
+
+	chg->is_hdc = 0;
+}
+
 static int smblib_create_votables(struct smb_charger *chg)
 {
 	int rc = 0;
@@ -2194,6 +2228,7 @@
 	INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work);
 	INIT_DELAYED_WORK(&chg->pl_taper_work, smblib_pl_taper_work);
 	INIT_DELAYED_WORK(&chg->step_soc_req_work, step_soc_req_work);
+	INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work);
 	chg->fake_capacity = -EINVAL;
 
 	switch (chg->mode) {