Merge "leds: qti-flash: Add flash active property"
diff --git a/drivers/leds/leds-qti-flash.c b/drivers/leds/leds-qti-flash.c
index b0ca27b..4457cf6 100644
--- a/drivers/leds/leds-qti-flash.c
+++ b/drivers/leds/leds-qti-flash.c
@@ -859,6 +859,51 @@
 	return scnprintf(buf, PAGE_SIZE, "%d\n", snode->led->max_current);
 }
 
+static int qti_flash_led_regulator_control(struct led_classdev *led_cdev,
+					int options)
+{
+	struct flash_switch_data *snode;
+	union power_supply_propval ret = {0, };
+	int rc = 0;
+
+	snode = container_of(led_cdev, struct flash_switch_data, cdev);
+
+	if (snode->led->data->pmic_type != PM2250)
+		return 0;
+
+	rc = is_main_psy_available(snode->led);
+	if (rc < 0)
+		return rc;
+
+	if (options & ENABLE_REGULATOR) {
+		ret.intval = 1;
+		rc = power_supply_set_property(snode->led->main_psy,
+				POWER_SUPPLY_PROP_FLASH_ACTIVE,
+				&ret);
+		if (rc < 0) {
+			pr_err("Failed to set FLASH_ACTIVE on charger rc=%d\n",
+							rc);
+			return rc;
+		}
+
+		pr_debug("FLASH_ACTIVE = 1\n");
+	} else if (options & DISABLE_REGULATOR) {
+		ret.intval = 0;
+		rc = power_supply_set_property(snode->led->main_psy,
+				POWER_SUPPLY_PROP_FLASH_ACTIVE,
+				&ret);
+		if (rc < 0) {
+			pr_err("Failed to set FLASH_ACTIVE on charger rc=%d\n",
+							rc);
+			return rc;
+		}
+
+		pr_debug("FLASH_ACTIVE = 0\n");
+	}
+
+	return 0;
+}
+
 int qti_flash_led_prepare(struct led_trigger *trig, int options,
 				int *max_current)
 {
@@ -901,18 +946,42 @@
 		return 0;
 	}
 
-	if (options & ENABLE_REGULATOR)
-		return 0;
+	rc = qti_flash_led_regulator_control(led_cdev, options);
+	if (rc < 0)
+		pr_err("Failed to set flash control options\n");
 
-	if (options & DISABLE_REGULATOR)
-		return 0;
-
-	return -EINVAL;
+	return rc;
 }
 EXPORT_SYMBOL(qti_flash_led_prepare);
 
+static ssize_t qti_flash_led_prepare_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int rc, options;
+	u32 val;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+	rc = kstrtouint(buf, 0, &val);
+	if (rc < 0)
+		return rc;
+
+	if (val != 0 && val != 1)
+		return count;
+
+	options = val ? ENABLE_REGULATOR : DISABLE_REGULATOR;
+
+	rc = qti_flash_led_regulator_control(led_cdev, options);
+	if (rc < 0) {
+		pr_err("failed to query led regulator\n");
+		return rc;
+	}
+
+	return count;
+}
+
 static struct device_attribute qti_flash_led_attrs[] = {
 	__ATTR(max_current, 0664, qti_flash_led_max_current_show, NULL),
+	__ATTR(enable, 0664, NULL, qti_flash_led_prepare_store),
 };
 
 static int qti_flash_brightness_set_blocking(
diff --git a/drivers/power/supply/qcom/qpnp-smblite.c b/drivers/power/supply/qcom/qpnp-smblite.c
index 5f8c714..f0d5ece 100644
--- a/drivers/power/supply/qcom/qpnp-smblite.c
+++ b/drivers/power/supply/qcom/qpnp-smblite.c
@@ -433,9 +433,6 @@
 	case POWER_SUPPLY_PROP_SCOPE:
 		rc = smblite_lib_get_prop_scope(chg, val);
 		break;
-	case POWER_SUPPLY_PROP_FLASH_TRIGGER:
-		rc = schgm_flashlite_get_vreg_ok(chg, &val->intval);
-		break;
 	default:
 		pr_err("get prop %d is not supported in usb\n", psp);
 		rc = -EINVAL;
@@ -530,6 +527,7 @@
 	POWER_SUPPLY_PROP_FCC_DELTA,
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_FLASH_TRIGGER,
+	POWER_SUPPLY_PROP_FLASH_ACTIVE,
 };
 
 static int smblite_usb_main_get_prop(struct power_supply *psy,
@@ -564,6 +562,12 @@
 	case POWER_SUPPLY_PROP_CURRENT_MAX:
 		rc = smblite_lib_get_icl_current(chg, &val->intval);
 		break;
+	case POWER_SUPPLY_PROP_FLASH_TRIGGER:
+		rc = schgm_flashlite_get_vreg_ok(chg, &val->intval);
+		break;
+	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
+		val->intval = chg->flash_active;
+		break;
 	default:
 		pr_debug("get prop %d is not supported in usb-main\n", psp);
 		rc = -EINVAL;
@@ -582,6 +586,7 @@
 	struct smblite *chip = power_supply_get_drvdata(psy);
 	struct smb_charger *chg = &chip->chg;
 	int rc = 0;
+	union power_supply_propval pval = {0, };
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
@@ -595,6 +600,21 @@
 	case POWER_SUPPLY_PROP_CURRENT_MAX:
 		rc = smblite_lib_set_icl_current(chg, val->intval);
 		break;
+	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
+		if (chg->flash_active != val->intval) {
+			chg->flash_active = val->intval;
+
+			rc = smblite_lib_get_prop_usb_present(chg, &pval);
+			if (rc < 0)
+				pr_err("Failed to get USB present status rc=%d\n",
+						rc);
+			if (!pval.intval) {
+				/* vote 100ma when usb is not present*/
+				vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER,
+							true, USBIN_100UA);
+			}
+		}
+		break;
 	default:
 		pr_err("set prop %d is not supported\n", psp);
 		rc = -EINVAL;