All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-01 18:50 ` Vinay Simha BN
  0 siblings, 0 replies; 8+ messages in thread
From: Vinay Simha BN @ 2017-08-01 18:50 UTC (permalink / raw)
  Cc: Vinay Simha BN, John Stultz, Sumit Semwal, Jonghwa Lee,
	Chanwoo Choi, Myungjoo Ham, Sebastian Reichel, Rob Herring,
	Mark Rutland, open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Summit microelectronics' SMB358 charger chip has
almost the same register map and functionality.
voltage and current table are only differed.

SMB345 charger IC tested in nexus7

Cc: John Stultz <john.stultz@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Jonghwa Lee <jonghwa3.lee@samsung.com>
Cc: Chanwoo Choi <cw00.choi@samsung.com>
Cc: Myungjoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Vinay Simha BN <simhavcs@gmail.com>

---
v2:
* incorporated code review from Rob Herring
  gpio line added for Enable charging control,
  documentation bindings (vendor prefixes and unit suffixes)
---
 .../bindings/power/supply/smb347_charger.txt       |  73 +++++
 drivers/power/supply/smb347-charger.c              | 334 +++++++++++++--------
 include/linux/power/smb347-charger.h               |   4 +-
 3 files changed, 283 insertions(+), 128 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/supply/smb347_charger.txt

diff --git a/Documentation/devicetree/bindings/power/supply/smb347_charger.txt b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
new file mode 100644
index 0000000..45da4ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
@@ -0,0 +1,73 @@
+smb347_charger bindings
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+[Required porperties]
+- compatible : "summit,smb345"
+	       "summit,smb347"
+- reg : Slave address for i2c interface
+# At least one of following should be set
+  - enable-usb-charging
+  - enable-otg-charging
+  - enable-mains-charging
+
+[Optional properties]
+- interrupt-parent : The phandle for the interrupt controller
+- interrupts : Interrupt line index for mapping
+- en-gpio : Enable charging control
+	  : If this is not specified it will use SW (i2c interface)
+
+# Charging constraints
+- max-chg-curr : microamps for charging Maximum current
+- max-chg-volt : microvolts for charging Maximum voltage
+- pre-chg-curr : microamps for Pre-charging current
+- term-curr : microamps for Charging cycle termination current
+- fast-volt-thershold : microvolts for Voltage threshold to transit to fast charge mode
+- mains-curr-limit : micromaps for Maximum input current from AC/DC input
+- usb-curr-limit : microamps for Maximum input current from USB input
+
+# Related thermometer monitoring (Degrees Celsius)
+- chip-temp-threshold : Chip temperature for thermal regulaton.   <100, 130>
+- soft-cold-temp-limit : Cold battery temperature for soft alarm. <0, 15>*
+- soft-hot-temp-limit : Hot battery temperature for soft alarm.   <40, 55>
+- hard-cold-temp-limit : Cold battery temperature for hard alarm. <0, 15>*
+- hard-hot-temp-limit : Hot battery temperature for hard alarm.   <55, 65>
+(* The written temperature has +5'C offset. 0'C -> -5'C, 15'C -> 10'C)
+- soft-comp-method : Soft temperature limit compensation method
+	(Not defined) : Use default setting
+		<0> : Compensation none
+		<1> : Charge current compensation
+		<2> : Voltage compensation
+
+Example:
+	smb345@6a {
+		compatible = "summit,smb345";
+		reg = <0x6a>;
+		status = "okay";
+		interrupt-parent = <&tlmm_pinmux>;
+		interrupts = <23 IRQ_TYPE_EDGE_BOTH>;
+
+		max-chg-curr = <1800000>;
+		usb-curr-limit = <450000>;
+
+		chip-temp-thershold = <110>; /* celsius */
+
+		enable-usb-charging;
+		enable-otg-charging;
+	};
+
+	smb347@7f {
+		compatible = "summit,smb347";
+		reg = <0x7f>;
+		status = "okay";
+
+		max-chg-curr = <1800000>;
+		mains-curr-limit = <2000000>;
+		usb-curr-limit = <450000>;
+
+		chip-temp-thershold = <110>; /* celsius */
+
+		en-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_HIGH>;
+
+		enable-usb-charging;
+		enable-mains-charging;
+	};
diff --git a/drivers/power/supply/smb347-charger.c b/drivers/power/supply/smb347-charger.c
index 072c518..28666ab 100644
--- a/drivers/power/supply/smb347-charger.c
+++ b/drivers/power/supply/smb347-charger.c
@@ -124,6 +124,7 @@
 
 /**
  * struct smb347_charger - smb347 charger instance
+ * @id: smb charger id
  * @lock: protects concurrent access to online variables
  * @dev: pointer to device
  * @regmap: pointer to driver regmap
@@ -136,7 +137,8 @@
  * @pdata: pointer to platform data
  */
 struct smb347_charger {
-	struct mutex		lock;
+	int                     id;
+	struct mutex		lock; /* protects concurrent access */
 	struct device		*dev;
 	struct regmap		*regmap;
 	struct power_supply	*mains;
@@ -145,61 +147,49 @@ struct smb347_charger {
 	bool			mains_online;
 	bool			usb_online;
 	bool			charging_enabled;
-	const struct smb347_charger_platform_data *pdata;
+	struct smb347_charger_platform_data *pdata;
+};
+
+enum smb_charger_chipid {
+	SMB345,
+	SMB347,
+	NUM_CHIP_TYPES,
 };
 
 /* Fast charge current in uA */
-static const unsigned int fcc_tbl[] = {
-	700000,
-	900000,
-	1200000,
-	1500000,
-	1800000,
-	2000000,
-	2200000,
-	2500000,
+static const unsigned int fcc_tbl[NUM_CHIP_TYPES][8] = {
+	[SMB345] = { 200000, 450000, 600000, 900000,
+			1300000, 1500000, 1800000, 2000000 },
+	[SMB347] = { 700000, 900000, 1200000, 1500000,
+			1800000, 2000000, 2200000, 2500000 },
 };
 
 /* Pre-charge current in uA */
-static const unsigned int pcc_tbl[] = {
-	100000,
-	150000,
-	200000,
-	250000,
+static const unsigned int pcc_tbl[NUM_CHIP_TYPES][4] = {
+	[SMB345] = { 150000, 250000, 350000, 450000 },
+	[SMB347] = { 100000, 150000, 200000, 250000 },
 };
 
 /* Termination current in uA */
-static const unsigned int tc_tbl[] = {
-	37500,
-	50000,
-	100000,
-	150000,
-	200000,
-	250000,
-	500000,
-	600000,
+static const unsigned int tc_tbl[NUM_CHIP_TYPES][8] = {
+	[SMB345] = { 30000, 40000, 60000, 80000,
+			100000, 125000, 150000, 200000 },
+	[SMB347] = { 37500, 50000, 100000, 150000,
+			200000, 250000, 500000, 600000 },
 };
 
 /* Input current limit in uA */
-static const unsigned int icl_tbl[] = {
-	300000,
-	500000,
-	700000,
-	900000,
-	1200000,
-	1500000,
-	1800000,
-	2000000,
-	2200000,
-	2500000,
+static const unsigned int icl_tbl[NUM_CHIP_TYPES][10] = {
+	[SMB345] = { 300000, 500000, 700000, 1000000, 1500000,
+			1800000, 2000000, 2000000, 2000000, 2000000 },
+	[SMB347] = { 300000, 500000, 700000, 900000, 1200000,
+			1500000, 1800000, 2000000, 2200000, 2500000 },
 };
 
 /* Charge current compensation in uA */
-static const unsigned int ccc_tbl[] = {
-	250000,
-	700000,
-	900000,
-	1200000,
+static const unsigned int ccc_tbl[NUM_CHIP_TYPES][4] = {
+	[SMB345] = { 200000, 450000, 600000, 900000 },
+	[SMB347] = { 250000, 700000, 900000, 1200000 },
 };
 
 /* Convert register value to current using lookup table */
@@ -354,10 +344,10 @@ static int smb347_start_stop_charging(struct smb347_charger *smb)
 
 static int smb347_set_charge_current(struct smb347_charger *smb)
 {
-	int ret;
+	int ret, id = smb->id;
 
 	if (smb->pdata->max_charge_current) {
-		ret = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl),
+		ret = current_to_hw(fcc_tbl[id], ARRAY_SIZE(fcc_tbl[id]),
 				    smb->pdata->max_charge_current);
 		if (ret < 0)
 			return ret;
@@ -370,7 +360,7 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->pre_charge_current) {
-		ret = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl),
+		ret = current_to_hw(pcc_tbl[id], ARRAY_SIZE(pcc_tbl[id]),
 				    smb->pdata->pre_charge_current);
 		if (ret < 0)
 			return ret;
@@ -383,7 +373,7 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->termination_current) {
-		ret = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl),
+		ret = current_to_hw(tc_tbl[id], ARRAY_SIZE(tc_tbl[id]),
 				    smb->pdata->termination_current);
 		if (ret < 0)
 			return ret;
@@ -399,10 +389,10 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 
 static int smb347_set_current_limits(struct smb347_charger *smb)
 {
-	int ret;
+	int ret, id = smb->id;
 
 	if (smb->pdata->mains_current_limit) {
-		ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
+		ret = current_to_hw(icl_tbl[id], ARRAY_SIZE(icl_tbl[id]),
 				    smb->pdata->mains_current_limit);
 		if (ret < 0)
 			return ret;
@@ -415,7 +405,7 @@ static int smb347_set_current_limits(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->usb_hc_current_limit) {
-		ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
+		ret = current_to_hw(icl_tbl[id], ARRAY_SIZE(icl_tbl[id]),
 				    smb->pdata->usb_hc_current_limit);
 		if (ret < 0)
 			return ret;
@@ -440,9 +430,10 @@ static int smb347_set_voltage_limits(struct smb347_charger *smb)
 		ret = clamp_val(ret, 2400000, 3000000) - 2400000;
 		ret /= 200000;
 
-		ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE,
-				CFG_FLOAT_VOLTAGE_THRESHOLD_MASK,
-				ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_FLOAT_VOLTAGE,
+			 CFG_FLOAT_VOLTAGE_THRESHOLD_MASK,
+			 ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
@@ -467,7 +458,7 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 {
 	bool enable_therm_monitor = false;
 	int ret = 0;
-	int val;
+	int val, id = smb->id;
 
 	if (smb->pdata->chip_temp_threshold) {
 		val = smb->pdata->chip_temp_threshold;
@@ -565,8 +556,9 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->suspend_on_hard_temp_limit) {
-		ret = regmap_update_bits(smb->regmap, CFG_SYSOK,
-				 CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_SYSOK,
+			 CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0);
 		if (ret < 0)
 			return ret;
 	}
@@ -575,28 +567,31 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 	    SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) {
 		val = smb->pdata->soft_temp_limit_compensation & 0x3;
 
-		ret = regmap_update_bits(smb->regmap, CFG_THERM,
-				 CFG_THERM_SOFT_HOT_COMPENSATION_MASK,
-				 val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_THERM,
+			 CFG_THERM_SOFT_HOT_COMPENSATION_MASK,
+			 val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 
-		ret = regmap_update_bits(smb->regmap, CFG_THERM,
-				 CFG_THERM_SOFT_COLD_COMPENSATION_MASK,
-				 val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_THERM,
+			 CFG_THERM_SOFT_COLD_COMPENSATION_MASK,
+			 val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
 
 	if (smb->pdata->charge_current_compensation) {
-		val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl),
+		val = current_to_hw(ccc_tbl[id], ARRAY_SIZE(ccc_tbl[id]),
 				    smb->pdata->charge_current_compensation);
 		if (val < 0)
 			return val;
 
-		ret = regmap_update_bits(smb->regmap, CFG_OTG,
-				CFG_OTG_CC_COMPENSATION_MASK,
-				(val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_OTG,
+			 CFG_OTG_CC_COMPENSATION_MASK,
+			 (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
@@ -662,7 +657,8 @@ static int smb347_hw_init(struct smb347_charger *smb)
 	 * support for driving VBUS. Otherwise we disable it.
 	 */
 	ret = regmap_update_bits(smb->regmap, CFG_OTHER, CFG_OTHER_RID_MASK,
-		smb->pdata->use_usb_otg ? CFG_OTHER_RID_ENABLED_AUTO_OTG : 0);
+				 smb->pdata->use_usb_otg ?
+				 CFG_OTHER_RID_ENABLED_AUTO_OTG : 0);
 	if (ret < 0)
 		goto fail;
 
@@ -723,10 +719,12 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
 		return IRQ_NONE;
 	}
 
-	ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d);
-	if (ret < 0) {
-		dev_warn(smb->dev, "reading IRQSTAT_D failed\n");
-		return IRQ_NONE;
+	if (smb->id != SMB345) {
+		ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d);
+		if (ret < 0) {
+			dev_warn(smb->dev, "reading IRQSTAT_D failed\n");
+			return IRQ_NONE;
+		}
 	}
 
 	ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e);
@@ -761,13 +759,15 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
 	 * If we got a charger timeout INT that means the charge
 	 * full is not detected with in charge timeout value.
 	 */
-	if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) {
-		dev_dbg(smb->dev, "total Charge Timeout INT received\n");
+	if (smb->id != SMB345) {
+		if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) {
+			dev_dbg(smb->dev, "total Charge Timeout INT received\n");
 
-		if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT)
-			dev_warn(smb->dev, "charging stopped due to timeout\n");
-		power_supply_changed(smb->battery);
-		handled = true;
+			if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT)
+				dev_warn(smb->dev, "charging stopped due to timeout\n");
+			power_supply_changed(smb->battery);
+			handled = true;
+		}
 	}
 
 	/*
@@ -809,7 +809,7 @@ static int smb347_irq_set(struct smb347_charger *smb, bool enable)
 		goto fail;
 
 	ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff,
-			enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER |
+				 enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER |
 					CFG_STATUS_IRQ_CHARGE_TIMEOUT) : 0);
 	if (ret < 0)
 		goto fail;
@@ -834,22 +834,22 @@ static inline int smb347_irq_disable(struct smb347_charger *smb)
 static int smb347_irq_init(struct smb347_charger *smb,
 			   struct i2c_client *client)
 {
-	const struct smb347_charger_platform_data *pdata = smb->pdata;
-	int ret, irq = gpio_to_irq(pdata->irq_gpio);
+	int ret;
+	unsigned long irqflags;
 
-	ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
-	if (ret < 0)
-		goto fail;
+	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
+
+	ret = devm_request_threaded_irq(smb->dev, client->irq, NULL,
+					smb347_interrupt, irqflags |
+					IRQF_ONESHOT,
+					client->name, smb);
 
-	ret = request_threaded_irq(irq, NULL, smb347_interrupt,
-				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-				   client->name, smb);
 	if (ret < 0)
-		goto fail_gpio;
+		goto out;
 
 	ret = smb347_set_writable(smb, true);
 	if (ret < 0)
-		goto fail_irq;
+		goto out;
 
 	/*
 	 * Configure the STAT output to be suitable for interrupts: disable
@@ -859,20 +859,10 @@ static int smb347_irq_init(struct smb347_charger *smb,
 				 CFG_STAT_ACTIVE_HIGH | CFG_STAT_DISABLED,
 				 CFG_STAT_DISABLED);
 	if (ret < 0)
-		goto fail_readonly;
-
-	smb347_set_writable(smb, false);
-	client->irq = irq;
-	return 0;
+		client->irq = 0;
 
-fail_readonly:
 	smb347_set_writable(smb, false);
-fail_irq:
-	free_irq(irq, smb);
-fail_gpio:
-	gpio_free(pdata->irq_gpio);
-fail:
-	client->irq = 0;
+out:
 	return ret;
 }
 
@@ -882,7 +872,7 @@ static int smb347_irq_init(struct smb347_charger *smb,
  */
 static int get_const_charge_current(struct smb347_charger *smb)
 {
-	int ret, intval;
+	int ret, intval, id = smb->id;
 	unsigned int v;
 
 	if (!smb347_is_ps_online(smb))
@@ -897,10 +887,12 @@ static int get_const_charge_current(struct smb347_charger *smb)
 	 * and we can detect which table to use from bit 5.
 	 */
 	if (v & 0x20) {
-		intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), v & 7);
+		intval = hw_to_current(fcc_tbl[id],
+				       ARRAY_SIZE(fcc_tbl[id]), v & 7);
 	} else {
 		v >>= 3;
-		intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), v & 7);
+		intval = hw_to_current(pcc_tbl[id],
+				       ARRAY_SIZE(pcc_tbl[id]), v & 7);
 	}
 
 	return intval;
@@ -947,16 +939,14 @@ static int smb347_mains_get_property(struct power_supply *psy,
 		ret = get_const_charge_voltage(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 		ret = get_const_charge_current(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	default:
@@ -988,16 +978,14 @@ static int smb347_usb_get_property(struct power_supply *psy,
 		ret = get_const_charge_voltage(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 		ret = get_const_charge_current(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	default:
@@ -1026,7 +1014,7 @@ static int smb347_get_charging_status(struct smb347_charger *smb)
 		return ret;
 
 	if ((val & STAT_C_CHARGER_ERROR) ||
-			(val & STAT_C_HOLDOFF_STAT)) {
+	    (val & STAT_C_HOLDOFF_STAT)) {
 		/*
 		 * set to NOT CHARGING upon charger error
 		 * or charging has stopped.
@@ -1049,7 +1037,7 @@ static int smb347_get_charging_status(struct smb347_charger *smb)
 		} else {
 			/*
 			 * in this case no charger error or termination
-			 * occured but charging is not in progress!!!
+			 * occurred but charging is not in progress!!!
 			 */
 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 		}
@@ -1178,6 +1166,75 @@ static bool smb347_readable_reg(struct device *dev, unsigned int reg)
 	return smb347_volatile_reg(dev, reg);
 }
 
+static void smb347_dt_parse_pdata(struct device_node *np,
+				  struct smb347_charger_platform_data *pdata)
+{
+	/* Charing constraints */
+	of_property_read_u32(np, "max-chg-curr", &pdata->max_charge_current);
+	of_property_read_u32(np, "max-chg-volt", &pdata->max_charge_voltage);
+	of_property_read_u32(np, "pre-chg-curr", &pdata->pre_charge_current);
+	of_property_read_u32(np, "term-curr", &pdata->termination_current);
+	of_property_read_u32(np, "fast-volt-threshold",
+			     &pdata->pre_to_fast_voltage);
+	of_property_read_u32(np, "mains-curr-limit",
+			     &pdata->mains_current_limit);
+	of_property_read_u32(np, "usb-curr-limit",
+			     &pdata->usb_hc_current_limit);
+
+	/* For thermometer monitoring */
+	of_property_read_u32(np, "chip-temp-threshold",
+			     &pdata->chip_temp_threshold);
+	if (of_property_read_u32(np, "soft-cold-temp-limit",
+				 &pdata->soft_cold_temp_limit))
+		pdata->soft_cold_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "soft-hot-temp-limit",
+				 &pdata->soft_hot_temp_limit))
+		pdata->soft_hot_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "hard-cold-temp-limit",
+				 &pdata->hard_cold_temp_limit))
+		pdata->hard_cold_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "hard-hot-temp-limit",
+				 &pdata->hard_hot_temp_limit))
+		pdata->hard_hot_temp_limit = SMB347_TEMP_USE_DEFAULT;
+
+	/* Suspend when battery temperature is outside hard limits */
+	if ((pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) ||
+	    (pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT))
+		pdata->suspend_on_hard_temp_limit = true;
+
+	if (of_property_read_u32(np, "soft-comp-method",
+				 &pdata->soft_temp_limit_compensation))
+		pdata->soft_temp_limit_compensation =
+				SMB347_SOFT_TEMP_COMPENSATE_DEFAULT;
+
+	of_property_read_u32(np, "chg-curr-comp",
+			     &pdata->charge_current_compensation);
+
+	/* Supported charging mode */
+	pdata->use_mains = of_property_read_bool(np, "enable-mains-charging");
+	pdata->use_usb = of_property_read_bool(np, "enable-usb-charging");
+	pdata->use_usb_otg = of_property_read_bool(np, "enable-otg-charging");
+
+	/* If IRQ is enabled or not */
+	if (!of_get_property(np, "interrupts", NULL))
+		pdata->irq_gpio = -1;
+}
+
+static struct smb347_charger_platform_data
+			*smb347_get_platdata(struct device *dev)
+{
+	struct smb347_charger_platform_data *pdata = NULL;
+
+	if (dev->of_node) {
+		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+		smb347_dt_parse_pdata(dev->of_node, pdata);
+	} else {
+		pdata = dev_get_platdata(dev);
+	}
+
+	return pdata;
+}
+
 static const struct regmap_config smb347_regmap = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
@@ -1210,32 +1267,34 @@ static const struct power_supply_desc smb347_battery_desc = {
 	.num_properties	= ARRAY_SIZE(smb347_battery_properties),
 };
 
+static char *battery[] = {
+	"smb347-battery",
+};
+
 static int smb347_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	static char *battery[] = { "smb347-battery" };
-	const struct smb347_charger_platform_data *pdata;
 	struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
 	struct device *dev = &client->dev;
 	struct smb347_charger *smb;
 	int ret;
 
-	pdata = dev->platform_data;
-	if (!pdata)
-		return -EINVAL;
-
-	if (!pdata->use_mains && !pdata->use_usb)
-		return -EINVAL;
-
 	smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
 	if (!smb)
 		return -ENOMEM;
 
+	smb->pdata = smb347_get_platdata(dev);
+	if (IS_ERR_OR_NULL(smb->pdata))
+		return -ENODEV;
+
+	if (!smb->pdata->use_mains && !smb->pdata->use_usb)
+		return -EINVAL;
+
 	i2c_set_clientdata(client, smb);
 
 	mutex_init(&smb->lock);
+	smb->id = id->driver_data;
 	smb->dev = &client->dev;
-	smb->pdata = pdata;
 
 	smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
 	if (IS_ERR(smb->regmap))
@@ -1277,10 +1336,24 @@ static int smb347_probe(struct i2c_client *client,
 	}
 
 	/*
+	 * EN - enable input can be controlled by i2c or gpio.
+	 */
+	smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
+	if (IS_ERR(smb->pdata->en_gpio)) {
+		ret = PTR_ERR(smb->pdata->en_gpio);
+		dev_err(dev, "cannot get en-gpio %d\n", ret);
+		dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
+
+		smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
+	} else {
+		smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
+	}
+
+	/*
 	 * Interrupt pin is optional. If it is connected, we setup the
 	 * interrupt support here.
 	 */
-	if (pdata->irq_gpio >= 0) {
+	if (smb->pdata->irq_gpio >= 0) {
 		ret = smb347_irq_init(smb, client);
 		if (ret < 0) {
 			dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
@@ -1297,11 +1370,8 @@ static int smb347_remove(struct i2c_client *client)
 {
 	struct smb347_charger *smb = i2c_get_clientdata(client);
 
-	if (client->irq) {
+	if (client->irq)
 		smb347_irq_disable(smb);
-		free_irq(client->irq, smb);
-		gpio_free(smb->pdata->irq_gpio);
-	}
 
 	power_supply_unregister(smb->battery);
 	if (smb->pdata->use_usb)
@@ -1312,14 +1382,24 @@ static int smb347_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id smb347_id[] = {
-	{ "smb347", 0 },
+	{ "smb345", SMB345 },
+	{ "smb347", SMB347 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, smb347_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_smb347_ids[] = {
+	{ .compatible = "summit,smb345" },
+	{ .compatible = "summit,smb347" },
+	{},
+};
+#endif
+
 static struct i2c_driver smb347_driver = {
 	.driver = {
 		.name = "smb347",
+		.of_match_table = of_match_ptr(of_smb347_ids),
 	},
 	.probe        = smb347_probe,
 	.remove       = smb347_remove,
diff --git a/include/linux/power/smb347-charger.h b/include/linux/power/smb347-charger.h
index b3cb20d..7bdc709 100644
--- a/include/linux/power/smb347-charger.h
+++ b/include/linux/power/smb347-charger.h
@@ -47,7 +47,7 @@ enum smb347_chg_enable {
  * @pre_charge_current: current (in uA) to use in pre-charging phase
  * @termination_current: current (in uA) used to determine when the
  *			 charging cycle terminates
- * @pre_to_fast_voltage: voltage (in uV) treshold used for transitioning to
+ * @pre_to_fast_voltage: voltage (in uV) threshold used for transitioning to
  *			 pre-charge to fast charge mode
  * @mains_current_limit: maximum input current drawn from AC/DC input (in uA)
  * @usb_hc_current_limit: maximum input high current (in uA) drawn from USB
@@ -71,6 +71,7 @@ enum smb347_chg_enable {
  * @use_usb: USB input can be used
  * @use_usb_otg: USB OTG output can be used (not implemented yet)
  * @irq_gpio: GPIO number used for interrupts (%-1 if not used)
+ * @en_gpio: GPIO used for Enable input
  * @enable_control: how charging enable/disable is controlled
  *		    (driver/pin controls)
  *
@@ -111,6 +112,7 @@ struct smb347_charger_platform_data {
 	bool		use_usb;
 	bool		use_usb_otg;
 	int		irq_gpio;
+	struct gpio_desc *en_gpio;
 	enum smb347_chg_enable enable_control;
 };
 
-- 
2.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-01 18:50 ` Vinay Simha BN
  0 siblings, 0 replies; 8+ messages in thread
From: Vinay Simha BN @ 2017-08-01 18:50 UTC (permalink / raw)
  Cc: Vinay Simha BN, John Stultz, Sumit Semwal, Jonghwa Lee,
	Chanwoo Choi, Myungjoo Ham, Sebastian Reichel, Rob Herring,
	Mark Rutland, open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

Summit microelectronics' SMB358 charger chip has
almost the same register map and functionality.
voltage and current table are only differed.

SMB345 charger IC tested in nexus7

Cc: John Stultz <john.stultz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sumit Semwal <sumit.semwal-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Jonghwa Lee <jonghwa3.lee-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Cc: Chanwoo Choi <cw00.choi-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Cc: Myungjoo Ham <myungjoo.ham-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Vinay Simha BN <simhavcs-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

---
v2:
* incorporated code review from Rob Herring
  gpio line added for Enable charging control,
  documentation bindings (vendor prefixes and unit suffixes)
---
 .../bindings/power/supply/smb347_charger.txt       |  73 +++++
 drivers/power/supply/smb347-charger.c              | 334 +++++++++++++--------
 include/linux/power/smb347-charger.h               |   4 +-
 3 files changed, 283 insertions(+), 128 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/supply/smb347_charger.txt

diff --git a/Documentation/devicetree/bindings/power/supply/smb347_charger.txt b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
new file mode 100644
index 0000000..45da4ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
@@ -0,0 +1,73 @@
+smb347_charger bindings
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+[Required porperties]
+- compatible : "summit,smb345"
+	       "summit,smb347"
+- reg : Slave address for i2c interface
+# At least one of following should be set
+  - enable-usb-charging
+  - enable-otg-charging
+  - enable-mains-charging
+
+[Optional properties]
+- interrupt-parent : The phandle for the interrupt controller
+- interrupts : Interrupt line index for mapping
+- en-gpio : Enable charging control
+	  : If this is not specified it will use SW (i2c interface)
+
+# Charging constraints
+- max-chg-curr : microamps for charging Maximum current
+- max-chg-volt : microvolts for charging Maximum voltage
+- pre-chg-curr : microamps for Pre-charging current
+- term-curr : microamps for Charging cycle termination current
+- fast-volt-thershold : microvolts for Voltage threshold to transit to fast charge mode
+- mains-curr-limit : micromaps for Maximum input current from AC/DC input
+- usb-curr-limit : microamps for Maximum input current from USB input
+
+# Related thermometer monitoring (Degrees Celsius)
+- chip-temp-threshold : Chip temperature for thermal regulaton.   <100, 130>
+- soft-cold-temp-limit : Cold battery temperature for soft alarm. <0, 15>*
+- soft-hot-temp-limit : Hot battery temperature for soft alarm.   <40, 55>
+- hard-cold-temp-limit : Cold battery temperature for hard alarm. <0, 15>*
+- hard-hot-temp-limit : Hot battery temperature for hard alarm.   <55, 65>
+(* The written temperature has +5'C offset. 0'C -> -5'C, 15'C -> 10'C)
+- soft-comp-method : Soft temperature limit compensation method
+	(Not defined) : Use default setting
+		<0> : Compensation none
+		<1> : Charge current compensation
+		<2> : Voltage compensation
+
+Example:
+	smb345@6a {
+		compatible = "summit,smb345";
+		reg = <0x6a>;
+		status = "okay";
+		interrupt-parent = <&tlmm_pinmux>;
+		interrupts = <23 IRQ_TYPE_EDGE_BOTH>;
+
+		max-chg-curr = <1800000>;
+		usb-curr-limit = <450000>;
+
+		chip-temp-thershold = <110>; /* celsius */
+
+		enable-usb-charging;
+		enable-otg-charging;
+	};
+
+	smb347@7f {
+		compatible = "summit,smb347";
+		reg = <0x7f>;
+		status = "okay";
+
+		max-chg-curr = <1800000>;
+		mains-curr-limit = <2000000>;
+		usb-curr-limit = <450000>;
+
+		chip-temp-thershold = <110>; /* celsius */
+
+		en-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_HIGH>;
+
+		enable-usb-charging;
+		enable-mains-charging;
+	};
diff --git a/drivers/power/supply/smb347-charger.c b/drivers/power/supply/smb347-charger.c
index 072c518..28666ab 100644
--- a/drivers/power/supply/smb347-charger.c
+++ b/drivers/power/supply/smb347-charger.c
@@ -124,6 +124,7 @@
 
 /**
  * struct smb347_charger - smb347 charger instance
+ * @id: smb charger id
  * @lock: protects concurrent access to online variables
  * @dev: pointer to device
  * @regmap: pointer to driver regmap
@@ -136,7 +137,8 @@
  * @pdata: pointer to platform data
  */
 struct smb347_charger {
-	struct mutex		lock;
+	int                     id;
+	struct mutex		lock; /* protects concurrent access */
 	struct device		*dev;
 	struct regmap		*regmap;
 	struct power_supply	*mains;
@@ -145,61 +147,49 @@ struct smb347_charger {
 	bool			mains_online;
 	bool			usb_online;
 	bool			charging_enabled;
-	const struct smb347_charger_platform_data *pdata;
+	struct smb347_charger_platform_data *pdata;
+};
+
+enum smb_charger_chipid {
+	SMB345,
+	SMB347,
+	NUM_CHIP_TYPES,
 };
 
 /* Fast charge current in uA */
-static const unsigned int fcc_tbl[] = {
-	700000,
-	900000,
-	1200000,
-	1500000,
-	1800000,
-	2000000,
-	2200000,
-	2500000,
+static const unsigned int fcc_tbl[NUM_CHIP_TYPES][8] = {
+	[SMB345] = { 200000, 450000, 600000, 900000,
+			1300000, 1500000, 1800000, 2000000 },
+	[SMB347] = { 700000, 900000, 1200000, 1500000,
+			1800000, 2000000, 2200000, 2500000 },
 };
 
 /* Pre-charge current in uA */
-static const unsigned int pcc_tbl[] = {
-	100000,
-	150000,
-	200000,
-	250000,
+static const unsigned int pcc_tbl[NUM_CHIP_TYPES][4] = {
+	[SMB345] = { 150000, 250000, 350000, 450000 },
+	[SMB347] = { 100000, 150000, 200000, 250000 },
 };
 
 /* Termination current in uA */
-static const unsigned int tc_tbl[] = {
-	37500,
-	50000,
-	100000,
-	150000,
-	200000,
-	250000,
-	500000,
-	600000,
+static const unsigned int tc_tbl[NUM_CHIP_TYPES][8] = {
+	[SMB345] = { 30000, 40000, 60000, 80000,
+			100000, 125000, 150000, 200000 },
+	[SMB347] = { 37500, 50000, 100000, 150000,
+			200000, 250000, 500000, 600000 },
 };
 
 /* Input current limit in uA */
-static const unsigned int icl_tbl[] = {
-	300000,
-	500000,
-	700000,
-	900000,
-	1200000,
-	1500000,
-	1800000,
-	2000000,
-	2200000,
-	2500000,
+static const unsigned int icl_tbl[NUM_CHIP_TYPES][10] = {
+	[SMB345] = { 300000, 500000, 700000, 1000000, 1500000,
+			1800000, 2000000, 2000000, 2000000, 2000000 },
+	[SMB347] = { 300000, 500000, 700000, 900000, 1200000,
+			1500000, 1800000, 2000000, 2200000, 2500000 },
 };
 
 /* Charge current compensation in uA */
-static const unsigned int ccc_tbl[] = {
-	250000,
-	700000,
-	900000,
-	1200000,
+static const unsigned int ccc_tbl[NUM_CHIP_TYPES][4] = {
+	[SMB345] = { 200000, 450000, 600000, 900000 },
+	[SMB347] = { 250000, 700000, 900000, 1200000 },
 };
 
 /* Convert register value to current using lookup table */
@@ -354,10 +344,10 @@ static int smb347_start_stop_charging(struct smb347_charger *smb)
 
 static int smb347_set_charge_current(struct smb347_charger *smb)
 {
-	int ret;
+	int ret, id = smb->id;
 
 	if (smb->pdata->max_charge_current) {
-		ret = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl),
+		ret = current_to_hw(fcc_tbl[id], ARRAY_SIZE(fcc_tbl[id]),
 				    smb->pdata->max_charge_current);
 		if (ret < 0)
 			return ret;
@@ -370,7 +360,7 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->pre_charge_current) {
-		ret = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl),
+		ret = current_to_hw(pcc_tbl[id], ARRAY_SIZE(pcc_tbl[id]),
 				    smb->pdata->pre_charge_current);
 		if (ret < 0)
 			return ret;
@@ -383,7 +373,7 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->termination_current) {
-		ret = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl),
+		ret = current_to_hw(tc_tbl[id], ARRAY_SIZE(tc_tbl[id]),
 				    smb->pdata->termination_current);
 		if (ret < 0)
 			return ret;
@@ -399,10 +389,10 @@ static int smb347_set_charge_current(struct smb347_charger *smb)
 
 static int smb347_set_current_limits(struct smb347_charger *smb)
 {
-	int ret;
+	int ret, id = smb->id;
 
 	if (smb->pdata->mains_current_limit) {
-		ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
+		ret = current_to_hw(icl_tbl[id], ARRAY_SIZE(icl_tbl[id]),
 				    smb->pdata->mains_current_limit);
 		if (ret < 0)
 			return ret;
@@ -415,7 +405,7 @@ static int smb347_set_current_limits(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->usb_hc_current_limit) {
-		ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
+		ret = current_to_hw(icl_tbl[id], ARRAY_SIZE(icl_tbl[id]),
 				    smb->pdata->usb_hc_current_limit);
 		if (ret < 0)
 			return ret;
@@ -440,9 +430,10 @@ static int smb347_set_voltage_limits(struct smb347_charger *smb)
 		ret = clamp_val(ret, 2400000, 3000000) - 2400000;
 		ret /= 200000;
 
-		ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE,
-				CFG_FLOAT_VOLTAGE_THRESHOLD_MASK,
-				ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_FLOAT_VOLTAGE,
+			 CFG_FLOAT_VOLTAGE_THRESHOLD_MASK,
+			 ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
@@ -467,7 +458,7 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 {
 	bool enable_therm_monitor = false;
 	int ret = 0;
-	int val;
+	int val, id = smb->id;
 
 	if (smb->pdata->chip_temp_threshold) {
 		val = smb->pdata->chip_temp_threshold;
@@ -565,8 +556,9 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 	}
 
 	if (smb->pdata->suspend_on_hard_temp_limit) {
-		ret = regmap_update_bits(smb->regmap, CFG_SYSOK,
-				 CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_SYSOK,
+			 CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0);
 		if (ret < 0)
 			return ret;
 	}
@@ -575,28 +567,31 @@ static int smb347_set_temp_limits(struct smb347_charger *smb)
 	    SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) {
 		val = smb->pdata->soft_temp_limit_compensation & 0x3;
 
-		ret = regmap_update_bits(smb->regmap, CFG_THERM,
-				 CFG_THERM_SOFT_HOT_COMPENSATION_MASK,
-				 val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_THERM,
+			 CFG_THERM_SOFT_HOT_COMPENSATION_MASK,
+			 val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 
-		ret = regmap_update_bits(smb->regmap, CFG_THERM,
-				 CFG_THERM_SOFT_COLD_COMPENSATION_MASK,
-				 val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_THERM,
+			 CFG_THERM_SOFT_COLD_COMPENSATION_MASK,
+			 val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
 
 	if (smb->pdata->charge_current_compensation) {
-		val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl),
+		val = current_to_hw(ccc_tbl[id], ARRAY_SIZE(ccc_tbl[id]),
 				    smb->pdata->charge_current_compensation);
 		if (val < 0)
 			return val;
 
-		ret = regmap_update_bits(smb->regmap, CFG_OTG,
-				CFG_OTG_CC_COMPENSATION_MASK,
-				(val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT);
+		ret = regmap_update_bits
+			(smb->regmap, CFG_OTG,
+			 CFG_OTG_CC_COMPENSATION_MASK,
+			 (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT);
 		if (ret < 0)
 			return ret;
 	}
@@ -662,7 +657,8 @@ static int smb347_hw_init(struct smb347_charger *smb)
 	 * support for driving VBUS. Otherwise we disable it.
 	 */
 	ret = regmap_update_bits(smb->regmap, CFG_OTHER, CFG_OTHER_RID_MASK,
-		smb->pdata->use_usb_otg ? CFG_OTHER_RID_ENABLED_AUTO_OTG : 0);
+				 smb->pdata->use_usb_otg ?
+				 CFG_OTHER_RID_ENABLED_AUTO_OTG : 0);
 	if (ret < 0)
 		goto fail;
 
@@ -723,10 +719,12 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
 		return IRQ_NONE;
 	}
 
-	ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d);
-	if (ret < 0) {
-		dev_warn(smb->dev, "reading IRQSTAT_D failed\n");
-		return IRQ_NONE;
+	if (smb->id != SMB345) {
+		ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d);
+		if (ret < 0) {
+			dev_warn(smb->dev, "reading IRQSTAT_D failed\n");
+			return IRQ_NONE;
+		}
 	}
 
 	ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e);
@@ -761,13 +759,15 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
 	 * If we got a charger timeout INT that means the charge
 	 * full is not detected with in charge timeout value.
 	 */
-	if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) {
-		dev_dbg(smb->dev, "total Charge Timeout INT received\n");
+	if (smb->id != SMB345) {
+		if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) {
+			dev_dbg(smb->dev, "total Charge Timeout INT received\n");
 
-		if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT)
-			dev_warn(smb->dev, "charging stopped due to timeout\n");
-		power_supply_changed(smb->battery);
-		handled = true;
+			if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT)
+				dev_warn(smb->dev, "charging stopped due to timeout\n");
+			power_supply_changed(smb->battery);
+			handled = true;
+		}
 	}
 
 	/*
@@ -809,7 +809,7 @@ static int smb347_irq_set(struct smb347_charger *smb, bool enable)
 		goto fail;
 
 	ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff,
-			enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER |
+				 enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER |
 					CFG_STATUS_IRQ_CHARGE_TIMEOUT) : 0);
 	if (ret < 0)
 		goto fail;
@@ -834,22 +834,22 @@ static inline int smb347_irq_disable(struct smb347_charger *smb)
 static int smb347_irq_init(struct smb347_charger *smb,
 			   struct i2c_client *client)
 {
-	const struct smb347_charger_platform_data *pdata = smb->pdata;
-	int ret, irq = gpio_to_irq(pdata->irq_gpio);
+	int ret;
+	unsigned long irqflags;
 
-	ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
-	if (ret < 0)
-		goto fail;
+	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
+
+	ret = devm_request_threaded_irq(smb->dev, client->irq, NULL,
+					smb347_interrupt, irqflags |
+					IRQF_ONESHOT,
+					client->name, smb);
 
-	ret = request_threaded_irq(irq, NULL, smb347_interrupt,
-				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-				   client->name, smb);
 	if (ret < 0)
-		goto fail_gpio;
+		goto out;
 
 	ret = smb347_set_writable(smb, true);
 	if (ret < 0)
-		goto fail_irq;
+		goto out;
 
 	/*
 	 * Configure the STAT output to be suitable for interrupts: disable
@@ -859,20 +859,10 @@ static int smb347_irq_init(struct smb347_charger *smb,
 				 CFG_STAT_ACTIVE_HIGH | CFG_STAT_DISABLED,
 				 CFG_STAT_DISABLED);
 	if (ret < 0)
-		goto fail_readonly;
-
-	smb347_set_writable(smb, false);
-	client->irq = irq;
-	return 0;
+		client->irq = 0;
 
-fail_readonly:
 	smb347_set_writable(smb, false);
-fail_irq:
-	free_irq(irq, smb);
-fail_gpio:
-	gpio_free(pdata->irq_gpio);
-fail:
-	client->irq = 0;
+out:
 	return ret;
 }
 
@@ -882,7 +872,7 @@ static int smb347_irq_init(struct smb347_charger *smb,
  */
 static int get_const_charge_current(struct smb347_charger *smb)
 {
-	int ret, intval;
+	int ret, intval, id = smb->id;
 	unsigned int v;
 
 	if (!smb347_is_ps_online(smb))
@@ -897,10 +887,12 @@ static int get_const_charge_current(struct smb347_charger *smb)
 	 * and we can detect which table to use from bit 5.
 	 */
 	if (v & 0x20) {
-		intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), v & 7);
+		intval = hw_to_current(fcc_tbl[id],
+				       ARRAY_SIZE(fcc_tbl[id]), v & 7);
 	} else {
 		v >>= 3;
-		intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), v & 7);
+		intval = hw_to_current(pcc_tbl[id],
+				       ARRAY_SIZE(pcc_tbl[id]), v & 7);
 	}
 
 	return intval;
@@ -947,16 +939,14 @@ static int smb347_mains_get_property(struct power_supply *psy,
 		ret = get_const_charge_voltage(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 		ret = get_const_charge_current(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	default:
@@ -988,16 +978,14 @@ static int smb347_usb_get_property(struct power_supply *psy,
 		ret = get_const_charge_voltage(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 		ret = get_const_charge_current(smb);
 		if (ret < 0)
 			return ret;
-		else
-			val->intval = ret;
+		val->intval = ret;
 		break;
 
 	default:
@@ -1026,7 +1014,7 @@ static int smb347_get_charging_status(struct smb347_charger *smb)
 		return ret;
 
 	if ((val & STAT_C_CHARGER_ERROR) ||
-			(val & STAT_C_HOLDOFF_STAT)) {
+	    (val & STAT_C_HOLDOFF_STAT)) {
 		/*
 		 * set to NOT CHARGING upon charger error
 		 * or charging has stopped.
@@ -1049,7 +1037,7 @@ static int smb347_get_charging_status(struct smb347_charger *smb)
 		} else {
 			/*
 			 * in this case no charger error or termination
-			 * occured but charging is not in progress!!!
+			 * occurred but charging is not in progress!!!
 			 */
 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 		}
@@ -1178,6 +1166,75 @@ static bool smb347_readable_reg(struct device *dev, unsigned int reg)
 	return smb347_volatile_reg(dev, reg);
 }
 
+static void smb347_dt_parse_pdata(struct device_node *np,
+				  struct smb347_charger_platform_data *pdata)
+{
+	/* Charing constraints */
+	of_property_read_u32(np, "max-chg-curr", &pdata->max_charge_current);
+	of_property_read_u32(np, "max-chg-volt", &pdata->max_charge_voltage);
+	of_property_read_u32(np, "pre-chg-curr", &pdata->pre_charge_current);
+	of_property_read_u32(np, "term-curr", &pdata->termination_current);
+	of_property_read_u32(np, "fast-volt-threshold",
+			     &pdata->pre_to_fast_voltage);
+	of_property_read_u32(np, "mains-curr-limit",
+			     &pdata->mains_current_limit);
+	of_property_read_u32(np, "usb-curr-limit",
+			     &pdata->usb_hc_current_limit);
+
+	/* For thermometer monitoring */
+	of_property_read_u32(np, "chip-temp-threshold",
+			     &pdata->chip_temp_threshold);
+	if (of_property_read_u32(np, "soft-cold-temp-limit",
+				 &pdata->soft_cold_temp_limit))
+		pdata->soft_cold_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "soft-hot-temp-limit",
+				 &pdata->soft_hot_temp_limit))
+		pdata->soft_hot_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "hard-cold-temp-limit",
+				 &pdata->hard_cold_temp_limit))
+		pdata->hard_cold_temp_limit = SMB347_TEMP_USE_DEFAULT;
+	if (of_property_read_u32(np, "hard-hot-temp-limit",
+				 &pdata->hard_hot_temp_limit))
+		pdata->hard_hot_temp_limit = SMB347_TEMP_USE_DEFAULT;
+
+	/* Suspend when battery temperature is outside hard limits */
+	if ((pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) ||
+	    (pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT))
+		pdata->suspend_on_hard_temp_limit = true;
+
+	if (of_property_read_u32(np, "soft-comp-method",
+				 &pdata->soft_temp_limit_compensation))
+		pdata->soft_temp_limit_compensation =
+				SMB347_SOFT_TEMP_COMPENSATE_DEFAULT;
+
+	of_property_read_u32(np, "chg-curr-comp",
+			     &pdata->charge_current_compensation);
+
+	/* Supported charging mode */
+	pdata->use_mains = of_property_read_bool(np, "enable-mains-charging");
+	pdata->use_usb = of_property_read_bool(np, "enable-usb-charging");
+	pdata->use_usb_otg = of_property_read_bool(np, "enable-otg-charging");
+
+	/* If IRQ is enabled or not */
+	if (!of_get_property(np, "interrupts", NULL))
+		pdata->irq_gpio = -1;
+}
+
+static struct smb347_charger_platform_data
+			*smb347_get_platdata(struct device *dev)
+{
+	struct smb347_charger_platform_data *pdata = NULL;
+
+	if (dev->of_node) {
+		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+		smb347_dt_parse_pdata(dev->of_node, pdata);
+	} else {
+		pdata = dev_get_platdata(dev);
+	}
+
+	return pdata;
+}
+
 static const struct regmap_config smb347_regmap = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
@@ -1210,32 +1267,34 @@ static const struct power_supply_desc smb347_battery_desc = {
 	.num_properties	= ARRAY_SIZE(smb347_battery_properties),
 };
 
+static char *battery[] = {
+	"smb347-battery",
+};
+
 static int smb347_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	static char *battery[] = { "smb347-battery" };
-	const struct smb347_charger_platform_data *pdata;
 	struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
 	struct device *dev = &client->dev;
 	struct smb347_charger *smb;
 	int ret;
 
-	pdata = dev->platform_data;
-	if (!pdata)
-		return -EINVAL;
-
-	if (!pdata->use_mains && !pdata->use_usb)
-		return -EINVAL;
-
 	smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
 	if (!smb)
 		return -ENOMEM;
 
+	smb->pdata = smb347_get_platdata(dev);
+	if (IS_ERR_OR_NULL(smb->pdata))
+		return -ENODEV;
+
+	if (!smb->pdata->use_mains && !smb->pdata->use_usb)
+		return -EINVAL;
+
 	i2c_set_clientdata(client, smb);
 
 	mutex_init(&smb->lock);
+	smb->id = id->driver_data;
 	smb->dev = &client->dev;
-	smb->pdata = pdata;
 
 	smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
 	if (IS_ERR(smb->regmap))
@@ -1277,10 +1336,24 @@ static int smb347_probe(struct i2c_client *client,
 	}
 
 	/*
+	 * EN - enable input can be controlled by i2c or gpio.
+	 */
+	smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
+	if (IS_ERR(smb->pdata->en_gpio)) {
+		ret = PTR_ERR(smb->pdata->en_gpio);
+		dev_err(dev, "cannot get en-gpio %d\n", ret);
+		dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
+
+		smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
+	} else {
+		smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
+	}
+
+	/*
 	 * Interrupt pin is optional. If it is connected, we setup the
 	 * interrupt support here.
 	 */
-	if (pdata->irq_gpio >= 0) {
+	if (smb->pdata->irq_gpio >= 0) {
 		ret = smb347_irq_init(smb, client);
 		if (ret < 0) {
 			dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
@@ -1297,11 +1370,8 @@ static int smb347_remove(struct i2c_client *client)
 {
 	struct smb347_charger *smb = i2c_get_clientdata(client);
 
-	if (client->irq) {
+	if (client->irq)
 		smb347_irq_disable(smb);
-		free_irq(client->irq, smb);
-		gpio_free(smb->pdata->irq_gpio);
-	}
 
 	power_supply_unregister(smb->battery);
 	if (smb->pdata->use_usb)
@@ -1312,14 +1382,24 @@ static int smb347_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id smb347_id[] = {
-	{ "smb347", 0 },
+	{ "smb345", SMB345 },
+	{ "smb347", SMB347 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, smb347_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_smb347_ids[] = {
+	{ .compatible = "summit,smb345" },
+	{ .compatible = "summit,smb347" },
+	{},
+};
+#endif
+
 static struct i2c_driver smb347_driver = {
 	.driver = {
 		.name = "smb347",
+		.of_match_table = of_match_ptr(of_smb347_ids),
 	},
 	.probe        = smb347_probe,
 	.remove       = smb347_remove,
diff --git a/include/linux/power/smb347-charger.h b/include/linux/power/smb347-charger.h
index b3cb20d..7bdc709 100644
--- a/include/linux/power/smb347-charger.h
+++ b/include/linux/power/smb347-charger.h
@@ -47,7 +47,7 @@ enum smb347_chg_enable {
  * @pre_charge_current: current (in uA) to use in pre-charging phase
  * @termination_current: current (in uA) used to determine when the
  *			 charging cycle terminates
- * @pre_to_fast_voltage: voltage (in uV) treshold used for transitioning to
+ * @pre_to_fast_voltage: voltage (in uV) threshold used for transitioning to
  *			 pre-charge to fast charge mode
  * @mains_current_limit: maximum input current drawn from AC/DC input (in uA)
  * @usb_hc_current_limit: maximum input high current (in uA) drawn from USB
@@ -71,6 +71,7 @@ enum smb347_chg_enable {
  * @use_usb: USB input can be used
  * @use_usb_otg: USB OTG output can be used (not implemented yet)
  * @irq_gpio: GPIO number used for interrupts (%-1 if not used)
+ * @en_gpio: GPIO used for Enable input
  * @enable_control: how charging enable/disable is controlled
  *		    (driver/pin controls)
  *
@@ -111,6 +112,7 @@ struct smb347_charger_platform_data {
 	bool		use_usb;
 	bool		use_usb_otg;
 	int		irq_gpio;
+	struct gpio_desc *en_gpio;
 	enum smb347_chg_enable enable_control;
 };
 
-- 
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-02 21:58   ` kbuild test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kbuild test robot @ 2017-08-02 21:58 UTC (permalink / raw)
  To: Vinay Simha BN
  Cc: kbuild-all, Vinay Simha BN, John Stultz, Sumit Semwal,
	Jonghwa Lee, Chanwoo Choi, Myungjoo Ham, Sebastian Reichel,
	Rob Herring, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

[-- Attachment #1: Type: text/plain, Size: 4668 bytes --]

Hi Vinay,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.13-rc3 next-20170802]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Vinay-Simha-BN/power-smb347-charger-Summit-SMB358-charger-IC/20170802-054147
config: x86_64-randconfig-b0-08030519 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/power/supply/smb347-charger.c: In function 'smb347_probe':
>> drivers/power/supply/smb347-charger.c:1341:24: error: implicit declaration of function 'devm_gpiod_get' [-Werror=implicit-function-declaration]
     smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
                           ^~~~~~~~~~~~~~
>> drivers/power/supply/smb347-charger.c:1341:50: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function)
     smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
                                                     ^~~~~~~~~~~~~~
   drivers/power/supply/smb347-charger.c:1341:50: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors

vim +/devm_gpiod_get +1341 drivers/power/supply/smb347-charger.c

  1273	
  1274	static int smb347_probe(struct i2c_client *client,
  1275				const struct i2c_device_id *id)
  1276	{
  1277		struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
  1278		struct device *dev = &client->dev;
  1279		struct smb347_charger *smb;
  1280		int ret;
  1281	
  1282		smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
  1283		if (!smb)
  1284			return -ENOMEM;
  1285	
  1286		smb->pdata = smb347_get_platdata(dev);
  1287		if (IS_ERR_OR_NULL(smb->pdata))
  1288			return -ENODEV;
  1289	
  1290		if (!smb->pdata->use_mains && !smb->pdata->use_usb)
  1291			return -EINVAL;
  1292	
  1293		i2c_set_clientdata(client, smb);
  1294	
  1295		mutex_init(&smb->lock);
  1296		smb->id = id->driver_data;
  1297		smb->dev = &client->dev;
  1298	
  1299		smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
  1300		if (IS_ERR(smb->regmap))
  1301			return PTR_ERR(smb->regmap);
  1302	
  1303		ret = smb347_hw_init(smb);
  1304		if (ret < 0)
  1305			return ret;
  1306	
  1307		mains_usb_cfg.supplied_to = battery;
  1308		mains_usb_cfg.num_supplicants = ARRAY_SIZE(battery);
  1309		mains_usb_cfg.drv_data = smb;
  1310		if (smb->pdata->use_mains) {
  1311			smb->mains = power_supply_register(dev, &smb347_mains_desc,
  1312							   &mains_usb_cfg);
  1313			if (IS_ERR(smb->mains))
  1314				return PTR_ERR(smb->mains);
  1315		}
  1316	
  1317		if (smb->pdata->use_usb) {
  1318			smb->usb = power_supply_register(dev, &smb347_usb_desc,
  1319							 &mains_usb_cfg);
  1320			if (IS_ERR(smb->usb)) {
  1321				if (smb->pdata->use_mains)
  1322					power_supply_unregister(smb->mains);
  1323				return PTR_ERR(smb->usb);
  1324			}
  1325		}
  1326	
  1327		battery_cfg.drv_data = smb;
  1328		smb->battery = power_supply_register(dev, &smb347_battery_desc,
  1329						     &battery_cfg);
  1330		if (IS_ERR(smb->battery)) {
  1331			if (smb->pdata->use_usb)
  1332				power_supply_unregister(smb->usb);
  1333			if (smb->pdata->use_mains)
  1334				power_supply_unregister(smb->mains);
  1335			return PTR_ERR(smb->battery);
  1336		}
  1337	
  1338		/*
  1339		 * EN - enable input can be controlled by i2c or gpio.
  1340		 */
> 1341		smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
  1342		if (IS_ERR(smb->pdata->en_gpio)) {
  1343			ret = PTR_ERR(smb->pdata->en_gpio);
  1344			dev_err(dev, "cannot get en-gpio %d\n", ret);
  1345			dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
  1346	
  1347			smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
  1348		} else {
  1349			smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
  1350		}
  1351	
  1352		/*
  1353		 * Interrupt pin is optional. If it is connected, we setup the
  1354		 * interrupt support here.
  1355		 */
  1356		if (smb->pdata->irq_gpio >= 0) {
  1357			ret = smb347_irq_init(smb, client);
  1358			if (ret < 0) {
  1359				dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
  1360				dev_warn(dev, "disabling IRQ support\n");
  1361			} else {
  1362				smb347_irq_enable(smb);
  1363			}
  1364		}
  1365	
  1366		return 0;
  1367	}
  1368	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23788 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-02 21:58   ` kbuild test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kbuild test robot @ 2017-08-02 21:58 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, Vinay Simha BN, John Stultz,
	Sumit Semwal, Jonghwa Lee, Chanwoo Choi, Myungjoo Ham,
	Sebastian Reichel, Rob Herring, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

[-- Attachment #1: Type: text/plain, Size: 4668 bytes --]

Hi Vinay,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.13-rc3 next-20170802]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Vinay-Simha-BN/power-smb347-charger-Summit-SMB358-charger-IC/20170802-054147
config: x86_64-randconfig-b0-08030519 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/power/supply/smb347-charger.c: In function 'smb347_probe':
>> drivers/power/supply/smb347-charger.c:1341:24: error: implicit declaration of function 'devm_gpiod_get' [-Werror=implicit-function-declaration]
     smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
                           ^~~~~~~~~~~~~~
>> drivers/power/supply/smb347-charger.c:1341:50: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function)
     smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
                                                     ^~~~~~~~~~~~~~
   drivers/power/supply/smb347-charger.c:1341:50: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors

vim +/devm_gpiod_get +1341 drivers/power/supply/smb347-charger.c

  1273	
  1274	static int smb347_probe(struct i2c_client *client,
  1275				const struct i2c_device_id *id)
  1276	{
  1277		struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
  1278		struct device *dev = &client->dev;
  1279		struct smb347_charger *smb;
  1280		int ret;
  1281	
  1282		smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
  1283		if (!smb)
  1284			return -ENOMEM;
  1285	
  1286		smb->pdata = smb347_get_platdata(dev);
  1287		if (IS_ERR_OR_NULL(smb->pdata))
  1288			return -ENODEV;
  1289	
  1290		if (!smb->pdata->use_mains && !smb->pdata->use_usb)
  1291			return -EINVAL;
  1292	
  1293		i2c_set_clientdata(client, smb);
  1294	
  1295		mutex_init(&smb->lock);
  1296		smb->id = id->driver_data;
  1297		smb->dev = &client->dev;
  1298	
  1299		smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
  1300		if (IS_ERR(smb->regmap))
  1301			return PTR_ERR(smb->regmap);
  1302	
  1303		ret = smb347_hw_init(smb);
  1304		if (ret < 0)
  1305			return ret;
  1306	
  1307		mains_usb_cfg.supplied_to = battery;
  1308		mains_usb_cfg.num_supplicants = ARRAY_SIZE(battery);
  1309		mains_usb_cfg.drv_data = smb;
  1310		if (smb->pdata->use_mains) {
  1311			smb->mains = power_supply_register(dev, &smb347_mains_desc,
  1312							   &mains_usb_cfg);
  1313			if (IS_ERR(smb->mains))
  1314				return PTR_ERR(smb->mains);
  1315		}
  1316	
  1317		if (smb->pdata->use_usb) {
  1318			smb->usb = power_supply_register(dev, &smb347_usb_desc,
  1319							 &mains_usb_cfg);
  1320			if (IS_ERR(smb->usb)) {
  1321				if (smb->pdata->use_mains)
  1322					power_supply_unregister(smb->mains);
  1323				return PTR_ERR(smb->usb);
  1324			}
  1325		}
  1326	
  1327		battery_cfg.drv_data = smb;
  1328		smb->battery = power_supply_register(dev, &smb347_battery_desc,
  1329						     &battery_cfg);
  1330		if (IS_ERR(smb->battery)) {
  1331			if (smb->pdata->use_usb)
  1332				power_supply_unregister(smb->usb);
  1333			if (smb->pdata->use_mains)
  1334				power_supply_unregister(smb->mains);
  1335			return PTR_ERR(smb->battery);
  1336		}
  1337	
  1338		/*
  1339		 * EN - enable input can be controlled by i2c or gpio.
  1340		 */
> 1341		smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
  1342		if (IS_ERR(smb->pdata->en_gpio)) {
  1343			ret = PTR_ERR(smb->pdata->en_gpio);
  1344			dev_err(dev, "cannot get en-gpio %d\n", ret);
  1345			dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
  1346	
  1347			smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
  1348		} else {
  1349			smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
  1350		}
  1351	
  1352		/*
  1353		 * Interrupt pin is optional. If it is connected, we setup the
  1354		 * interrupt support here.
  1355		 */
  1356		if (smb->pdata->irq_gpio >= 0) {
  1357			ret = smb347_irq_init(smb, client);
  1358			if (ret < 0) {
  1359				dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
  1360				dev_warn(dev, "disabling IRQ support\n");
  1361			} else {
  1362				smb347_irq_enable(smb);
  1363			}
  1364		}
  1365	
  1366		return 0;
  1367	}
  1368	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23788 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
  2017-08-02 21:58   ` kbuild test robot
@ 2017-08-07  6:52     ` Vinay Simha B N
  -1 siblings, 0 replies; 8+ messages in thread
From: Vinay Simha B N @ 2017-08-07  6:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, John Stultz, Sumit Semwal, Jonghwa Lee, Chanwoo Choi,
	Myungjoo Ham, Sebastian Reichel, Rob Herring, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

In the config attached. CONFIG_GPIOLIB is not set. please set and recompile

fyi,
devm_gpiod_get() declared in drivers/gpio/devres.c -> CONFIG_GPIOLIB

On Thu, Aug 3, 2017 at 3:28 AM, kbuild test robot <lkp@intel.com> wrote:
>
> Hi Vinay,
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.13-rc3 next-20170802]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Vinay-Simha-BN/power-smb347-charger-Summit-SMB358-charger-IC/20170802-054147
> config: x86_64-randconfig-b0-08030519 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    drivers/power/supply/smb347-charger.c: In function 'smb347_probe':
> >> drivers/power/supply/smb347-charger.c:1341:24: error: implicit declaration of function 'devm_gpiod_get' [-Werror=implicit-function-declaration]
>      smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>                            ^~~~~~~~~~~~~~
> >> drivers/power/supply/smb347-charger.c:1341:50: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function)
>      smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>                                                      ^~~~~~~~~~~~~~
>    drivers/power/supply/smb347-charger.c:1341:50: note: each undeclared identifier is reported only once for each function it appears in
>    cc1: some warnings being treated as errors
>
> vim +/devm_gpiod_get +1341 drivers/power/supply/smb347-charger.c
>
>   1273
>   1274  static int smb347_probe(struct i2c_client *client,
>   1275                          const struct i2c_device_id *id)
>   1276  {
>   1277          struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
>   1278          struct device *dev = &client->dev;
>   1279          struct smb347_charger *smb;
>   1280          int ret;
>   1281
>   1282          smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
>   1283          if (!smb)
>   1284                  return -ENOMEM;
>   1285
>   1286          smb->pdata = smb347_get_platdata(dev);
>   1287          if (IS_ERR_OR_NULL(smb->pdata))
>   1288                  return -ENODEV;
>   1289
>   1290          if (!smb->pdata->use_mains && !smb->pdata->use_usb)
>   1291                  return -EINVAL;
>   1292
>   1293          i2c_set_clientdata(client, smb);
>   1294
>   1295          mutex_init(&smb->lock);
>   1296          smb->id = id->driver_data;
>   1297          smb->dev = &client->dev;
>   1298
>   1299          smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
>   1300          if (IS_ERR(smb->regmap))
>   1301                  return PTR_ERR(smb->regmap);
>   1302
>   1303          ret = smb347_hw_init(smb);
>   1304          if (ret < 0)
>   1305                  return ret;
>   1306
>   1307          mains_usb_cfg.supplied_to = battery;
>   1308          mains_usb_cfg.num_supplicants = ARRAY_SIZE(battery);
>   1309          mains_usb_cfg.drv_data = smb;
>   1310          if (smb->pdata->use_mains) {
>   1311                  smb->mains = power_supply_register(dev, &smb347_mains_desc,
>   1312                                                     &mains_usb_cfg);
>   1313                  if (IS_ERR(smb->mains))
>   1314                          return PTR_ERR(smb->mains);
>   1315          }
>   1316
>   1317          if (smb->pdata->use_usb) {
>   1318                  smb->usb = power_supply_register(dev, &smb347_usb_desc,
>   1319                                                   &mains_usb_cfg);
>   1320                  if (IS_ERR(smb->usb)) {
>   1321                          if (smb->pdata->use_mains)
>   1322                                  power_supply_unregister(smb->mains);
>   1323                          return PTR_ERR(smb->usb);
>   1324                  }
>   1325          }
>   1326
>   1327          battery_cfg.drv_data = smb;
>   1328          smb->battery = power_supply_register(dev, &smb347_battery_desc,
>   1329                                               &battery_cfg);
>   1330          if (IS_ERR(smb->battery)) {
>   1331                  if (smb->pdata->use_usb)
>   1332                          power_supply_unregister(smb->usb);
>   1333                  if (smb->pdata->use_mains)
>   1334                          power_supply_unregister(smb->mains);
>   1335                  return PTR_ERR(smb->battery);
>   1336          }
>   1337
>   1338          /*
>   1339           * EN - enable input can be controlled by i2c or gpio.
>   1340           */
> > 1341          smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>   1342          if (IS_ERR(smb->pdata->en_gpio)) {
>   1343                  ret = PTR_ERR(smb->pdata->en_gpio);
>   1344                  dev_err(dev, "cannot get en-gpio %d\n", ret);
>   1345                  dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
>   1346
>   1347                  smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
>   1348          } else {
>   1349                  smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
>   1350          }
>   1351
>   1352          /*
>   1353           * Interrupt pin is optional. If it is connected, we setup the
>   1354           * interrupt support here.
>   1355           */
>   1356          if (smb->pdata->irq_gpio >= 0) {
>   1357                  ret = smb347_irq_init(smb, client);
>   1358                  if (ret < 0) {
>   1359                          dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
>   1360                          dev_warn(dev, "disabling IRQ support\n");
>   1361                  } else {
>   1362                          smb347_irq_enable(smb);
>   1363                  }
>   1364          }
>   1365
>   1366          return 0;
>   1367  }
>   1368
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation




-- 
regards,
vinaysimha

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-07  6:52     ` Vinay Simha B N
  0 siblings, 0 replies; 8+ messages in thread
From: Vinay Simha B N @ 2017-08-07  6:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, John Stultz, Sumit Semwal, Jonghwa Lee, Chanwoo Choi,
	Myungjoo Ham, Sebastian Reichel, Rob Herring, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

In the config attached. CONFIG_GPIOLIB is not set. please set and recompile

fyi,
devm_gpiod_get() declared in drivers/gpio/devres.c -> CONFIG_GPIOLIB

On Thu, Aug 3, 2017 at 3:28 AM, kbuild test robot <lkp@intel.com> wrote:
>
> Hi Vinay,
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.13-rc3 next-20170802]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Vinay-Simha-BN/power-smb347-charger-Summit-SMB358-charger-IC/20170802-054147
> config: x86_64-randconfig-b0-08030519 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    drivers/power/supply/smb347-charger.c: In function 'smb347_probe':
> >> drivers/power/supply/smb347-charger.c:1341:24: error: implicit declaration of function 'devm_gpiod_get' [-Werror=implicit-function-declaration]
>      smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>                            ^~~~~~~~~~~~~~
> >> drivers/power/supply/smb347-charger.c:1341:50: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function)
>      smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>                                                      ^~~~~~~~~~~~~~
>    drivers/power/supply/smb347-charger.c:1341:50: note: each undeclared identifier is reported only once for each function it appears in
>    cc1: some warnings being treated as errors
>
> vim +/devm_gpiod_get +1341 drivers/power/supply/smb347-charger.c
>
>   1273
>   1274  static int smb347_probe(struct i2c_client *client,
>   1275                          const struct i2c_device_id *id)
>   1276  {
>   1277          struct power_supply_config mains_usb_cfg = {}, battery_cfg = {};
>   1278          struct device *dev = &client->dev;
>   1279          struct smb347_charger *smb;
>   1280          int ret;
>   1281
>   1282          smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
>   1283          if (!smb)
>   1284                  return -ENOMEM;
>   1285
>   1286          smb->pdata = smb347_get_platdata(dev);
>   1287          if (IS_ERR_OR_NULL(smb->pdata))
>   1288                  return -ENODEV;
>   1289
>   1290          if (!smb->pdata->use_mains && !smb->pdata->use_usb)
>   1291                  return -EINVAL;
>   1292
>   1293          i2c_set_clientdata(client, smb);
>   1294
>   1295          mutex_init(&smb->lock);
>   1296          smb->id = id->driver_data;
>   1297          smb->dev = &client->dev;
>   1298
>   1299          smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
>   1300          if (IS_ERR(smb->regmap))
>   1301                  return PTR_ERR(smb->regmap);
>   1302
>   1303          ret = smb347_hw_init(smb);
>   1304          if (ret < 0)
>   1305                  return ret;
>   1306
>   1307          mains_usb_cfg.supplied_to = battery;
>   1308          mains_usb_cfg.num_supplicants = ARRAY_SIZE(battery);
>   1309          mains_usb_cfg.drv_data = smb;
>   1310          if (smb->pdata->use_mains) {
>   1311                  smb->mains = power_supply_register(dev, &smb347_mains_desc,
>   1312                                                     &mains_usb_cfg);
>   1313                  if (IS_ERR(smb->mains))
>   1314                          return PTR_ERR(smb->mains);
>   1315          }
>   1316
>   1317          if (smb->pdata->use_usb) {
>   1318                  smb->usb = power_supply_register(dev, &smb347_usb_desc,
>   1319                                                   &mains_usb_cfg);
>   1320                  if (IS_ERR(smb->usb)) {
>   1321                          if (smb->pdata->use_mains)
>   1322                                  power_supply_unregister(smb->mains);
>   1323                          return PTR_ERR(smb->usb);
>   1324                  }
>   1325          }
>   1326
>   1327          battery_cfg.drv_data = smb;
>   1328          smb->battery = power_supply_register(dev, &smb347_battery_desc,
>   1329                                               &battery_cfg);
>   1330          if (IS_ERR(smb->battery)) {
>   1331                  if (smb->pdata->use_usb)
>   1332                          power_supply_unregister(smb->usb);
>   1333                  if (smb->pdata->use_mains)
>   1334                          power_supply_unregister(smb->mains);
>   1335                  return PTR_ERR(smb->battery);
>   1336          }
>   1337
>   1338          /*
>   1339           * EN - enable input can be controlled by i2c or gpio.
>   1340           */
> > 1341          smb->pdata->en_gpio = devm_gpiod_get(dev, "en", GPIOD_OUT_HIGH);
>   1342          if (IS_ERR(smb->pdata->en_gpio)) {
>   1343                  ret = PTR_ERR(smb->pdata->en_gpio);
>   1344                  dev_err(dev, "cannot get en-gpio %d\n", ret);
>   1345                  dev_dbg(smb->dev, "charging enable/disable in SW enabled\n");
>   1346
>   1347                  smb->pdata->enable_control = SMB347_CHG_ENABLE_SW;
>   1348          } else {
>   1349                  smb->pdata->enable_control = SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH;
>   1350          }
>   1351
>   1352          /*
>   1353           * Interrupt pin is optional. If it is connected, we setup the
>   1354           * interrupt support here.
>   1355           */
>   1356          if (smb->pdata->irq_gpio >= 0) {
>   1357                  ret = smb347_irq_init(smb, client);
>   1358                  if (ret < 0) {
>   1359                          dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
>   1360                          dev_warn(dev, "disabling IRQ support\n");
>   1361                  } else {
>   1362                          smb347_irq_enable(smb);
>   1363                  }
>   1364          }
>   1365
>   1366          return 0;
>   1367  }
>   1368
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation




-- 
regards,
vinaysimha

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
  2017-08-01 18:50 ` Vinay Simha BN
@ 2017-08-10 15:30   ` Rob Herring
  -1 siblings, 0 replies; 8+ messages in thread
From: Rob Herring @ 2017-08-10 15:30 UTC (permalink / raw)
  To: Vinay Simha BN
  Cc: John Stultz, Sumit Semwal, Jonghwa Lee, Chanwoo Choi,
	Myungjoo Ham, Sebastian Reichel, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Wed, Aug 02, 2017 at 12:20:26AM +0530, Vinay Simha BN wrote:
> Summit microelectronics' SMB358 charger chip has
> almost the same register map and functionality.
> voltage and current table are only differed.
> 
> SMB345 charger IC tested in nexus7
> 
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Jonghwa Lee <jonghwa3.lee@samsung.com>
> Cc: Chanwoo Choi <cw00.choi@samsung.com>
> Cc: Myungjoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Vinay Simha BN <simhavcs@gmail.com>
> 
> ---
> v2:
> * incorporated code review from Rob Herring
>   gpio line added for Enable charging control,
>   documentation bindings (vendor prefixes and unit suffixes)
> ---
>  .../bindings/power/supply/smb347_charger.txt       |  73 +++++

Please split binding to a separate patch.

>  drivers/power/supply/smb347-charger.c              | 334 +++++++++++++--------
>  include/linux/power/smb347-charger.h               |   4 +-
>  3 files changed, 283 insertions(+), 128 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/smb347_charger.txt b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> new file mode 100644
> index 0000000..45da4ee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> @@ -0,0 +1,73 @@
> +smb347_charger bindings
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +[Required porperties]
> +- compatible : "summit,smb345"
> +	       "summit,smb347"
> +- reg : Slave address for i2c interface
> +# At least one of following should be set
> +  - enable-usb-charging
> +  - enable-otg-charging
> +  - enable-mains-charging

As I wrote last time, I don't think these belong in DT.

> +
> +[Optional properties]
> +- interrupt-parent : The phandle for the interrupt controller
> +- interrupts : Interrupt line index for mapping
> +- en-gpio : Enable charging control

enable-gpios

> +	  : If this is not specified it will use SW (i2c interface)
> +
> +# Charging constraints
> +- max-chg-curr : microamps for charging Maximum current
> +- max-chg-volt : microvolts for charging Maximum voltage
> +- pre-chg-curr : microamps for Pre-charging current
> +- term-curr : microamps for Charging cycle termination current
> +- fast-volt-thershold : microvolts for Voltage threshold to transit to fast charge mode
> +- mains-curr-limit : micromaps for Maximum input current from AC/DC input
> +- usb-curr-limit : microamps for Maximum input current from USB input

These are all properties of the battery, not the charger. See 
.../power/supply/battery.txt.

> +
> +# Related thermometer monitoring (Degrees Celsius)
> +- chip-temp-threshold : Chip temperature for thermal regulaton.   <100, 130>
> +- soft-cold-temp-limit : Cold battery temperature for soft alarm. <0, 15>*
> +- soft-hot-temp-limit : Hot battery temperature for soft alarm.   <40, 55>
> +- hard-cold-temp-limit : Cold battery temperature for hard alarm. <0, 15>*
> +- hard-hot-temp-limit : Hot battery temperature for hard alarm.   <55, 65>
> +(* The written temperature has +5'C offset. 0'C -> -5'C, 15'C -> 10'C)

These too should probably be common. If not they need vendor prefix and 
unit suffix. See property-units.txt.

> +- soft-comp-method : Soft temperature limit compensation method
> +	(Not defined) : Use default setting
> +		<0> : Compensation none
> +		<1> : Charge current compensation
> +		<2> : Voltage compensation
> +
> +Example:
> +	smb345@6a {
> +		compatible = "summit,smb345";
> +		reg = <0x6a>;
> +		status = "okay";
> +		interrupt-parent = <&tlmm_pinmux>;
> +		interrupts = <23 IRQ_TYPE_EDGE_BOTH>;
> +
> +		max-chg-curr = <1800000>;
> +		usb-curr-limit = <450000>;
> +
> +		chip-temp-thershold = <110>; /* celsius */
> +
> +		enable-usb-charging;
> +		enable-otg-charging;
> +	};
> +
> +	smb347@7f {

Isn't one example sufficient?

> +		compatible = "summit,smb347";
> +		reg = <0x7f>;
> +		status = "okay";
> +
> +		max-chg-curr = <1800000>;
> +		mains-curr-limit = <2000000>;
> +		usb-curr-limit = <450000>;
> +
> +		chip-temp-thershold = <110>; /* celsius */
> +
> +		en-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_HIGH>;
> +
> +		enable-usb-charging;
> +		enable-mains-charging;
> +	};

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] power: smb347-charger: Summit SMB358 charger IC
@ 2017-08-10 15:30   ` Rob Herring
  0 siblings, 0 replies; 8+ messages in thread
From: Rob Herring @ 2017-08-10 15:30 UTC (permalink / raw)
  To: Vinay Simha BN
  Cc: John Stultz, Sumit Semwal, Jonghwa Lee, Chanwoo Choi,
	Myungjoo Ham, Sebastian Reichel, Mark Rutland,
	open list:POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list

On Wed, Aug 02, 2017 at 12:20:26AM +0530, Vinay Simha BN wrote:
> Summit microelectronics' SMB358 charger chip has
> almost the same register map and functionality.
> voltage and current table are only differed.
> 
> SMB345 charger IC tested in nexus7
> 
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Jonghwa Lee <jonghwa3.lee@samsung.com>
> Cc: Chanwoo Choi <cw00.choi@samsung.com>
> Cc: Myungjoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Vinay Simha BN <simhavcs@gmail.com>
> 
> ---
> v2:
> * incorporated code review from Rob Herring
>   gpio line added for Enable charging control,
>   documentation bindings (vendor prefixes and unit suffixes)
> ---
>  .../bindings/power/supply/smb347_charger.txt       |  73 +++++

Please split binding to a separate patch.

>  drivers/power/supply/smb347-charger.c              | 334 +++++++++++++--------
>  include/linux/power/smb347-charger.h               |   4 +-
>  3 files changed, 283 insertions(+), 128 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/smb347_charger.txt b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> new file mode 100644
> index 0000000..45da4ee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/smb347_charger.txt
> @@ -0,0 +1,73 @@
> +smb347_charger bindings
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +[Required porperties]
> +- compatible : "summit,smb345"
> +	       "summit,smb347"
> +- reg : Slave address for i2c interface
> +# At least one of following should be set
> +  - enable-usb-charging
> +  - enable-otg-charging
> +  - enable-mains-charging

As I wrote last time, I don't think these belong in DT.

> +
> +[Optional properties]
> +- interrupt-parent : The phandle for the interrupt controller
> +- interrupts : Interrupt line index for mapping
> +- en-gpio : Enable charging control

enable-gpios

> +	  : If this is not specified it will use SW (i2c interface)
> +
> +# Charging constraints
> +- max-chg-curr : microamps for charging Maximum current
> +- max-chg-volt : microvolts for charging Maximum voltage
> +- pre-chg-curr : microamps for Pre-charging current
> +- term-curr : microamps for Charging cycle termination current
> +- fast-volt-thershold : microvolts for Voltage threshold to transit to fast charge mode
> +- mains-curr-limit : micromaps for Maximum input current from AC/DC input
> +- usb-curr-limit : microamps for Maximum input current from USB input

These are all properties of the battery, not the charger. See 
.../power/supply/battery.txt.

> +
> +# Related thermometer monitoring (Degrees Celsius)
> +- chip-temp-threshold : Chip temperature for thermal regulaton.   <100, 130>
> +- soft-cold-temp-limit : Cold battery temperature for soft alarm. <0, 15>*
> +- soft-hot-temp-limit : Hot battery temperature for soft alarm.   <40, 55>
> +- hard-cold-temp-limit : Cold battery temperature for hard alarm. <0, 15>*
> +- hard-hot-temp-limit : Hot battery temperature for hard alarm.   <55, 65>
> +(* The written temperature has +5'C offset. 0'C -> -5'C, 15'C -> 10'C)

These too should probably be common. If not they need vendor prefix and 
unit suffix. See property-units.txt.

> +- soft-comp-method : Soft temperature limit compensation method
> +	(Not defined) : Use default setting
> +		<0> : Compensation none
> +		<1> : Charge current compensation
> +		<2> : Voltage compensation
> +
> +Example:
> +	smb345@6a {
> +		compatible = "summit,smb345";
> +		reg = <0x6a>;
> +		status = "okay";
> +		interrupt-parent = <&tlmm_pinmux>;
> +		interrupts = <23 IRQ_TYPE_EDGE_BOTH>;
> +
> +		max-chg-curr = <1800000>;
> +		usb-curr-limit = <450000>;
> +
> +		chip-temp-thershold = <110>; /* celsius */
> +
> +		enable-usb-charging;
> +		enable-otg-charging;
> +	};
> +
> +	smb347@7f {

Isn't one example sufficient?

> +		compatible = "summit,smb347";
> +		reg = <0x7f>;
> +		status = "okay";
> +
> +		max-chg-curr = <1800000>;
> +		mains-curr-limit = <2000000>;
> +		usb-curr-limit = <450000>;
> +
> +		chip-temp-thershold = <110>; /* celsius */
> +
> +		en-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_HIGH>;
> +
> +		enable-usb-charging;
> +		enable-mains-charging;
> +	};

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-08-10 15:30 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-01 18:50 [PATCH] power: smb347-charger: Summit SMB358 charger IC Vinay Simha BN
2017-08-01 18:50 ` Vinay Simha BN
2017-08-02 21:58 ` kbuild test robot
2017-08-02 21:58   ` kbuild test robot
2017-08-07  6:52   ` Vinay Simha B N
2017-08-07  6:52     ` Vinay Simha B N
2017-08-10 15:30 ` Rob Herring
2017-08-10 15:30   ` Rob Herring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.