linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836
@ 2014-04-23 14:50 Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 1/6] charger: max14577: Add support for MAX77836 charger Krzysztof Kozlowski
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski

Hi,


This is second part of patches adding support for MAX77836 device
to the max14577 drivers.

The first part [1] was applied by Lee Jones [2][3] and this patchset *depends*
on it.

This patchset changes the max14577 charger and regulator drivers
and documents Device Tree bindings.

The patches 1 to 3 depends on each other so they should be pulled at once.
Patches 4, 5 and 6 can be applied independently. However still the
smoothest way to apply this would be through one tree after obtaining
necessary acks from maintainers.

I need acks from power (patches: 1, 3, 4) and regulator (patch 5) trees.


Changes since v4 (for this second part only)
============================================
1. Updated Kconfig entries mentioning MAX77836.
2. Added patch 5/6 (regulator: max14577: Implement SUSPEND mode for
   MAX77836 LDO-s)
3. Charger: Require a charger subnode in DTS with charger settings.
   Previously the charger driver didn't use any properties from DTS.
   Now it needs a subnode with settings because it supports different
   devices with different charging characteristics.
4. Rebased on 3.15-rc2.

Changes since v3
================
1. Applied minor fixes (pointed by Lee Jones).
2. Added one ACK (Lee Jones) and Review-by (Tomasz Figa).
3. Patch 14/charger: Minor change in parsing EOC value from DTS.
4. Rebased on next-20140224.

Changes since v2
================
1. Added ACK-s.
2. Applied minor checkpatch fixes (pointed by Lee Jones).
3. Rebased on next-20140217.

Changes since v1
================
1. Added ACK-s, reviews and tested-by tags.
2. Removed applied patches (they were merged to the linux-next tree).
3. Applied comments from review (Lee Jones) to 5/15 (detection of device type)
   and 8/15 (add max77836 support to max14577).
4. Rebased on next tree.
5. Added patch 13 and 14 (pointed by Jenny Tc):
   - regulator/mfd: max14577: Export symbols for calculating charger current
   - charger: max14577: Configure battery-dependent settings from DTS
6. Updated bindings documentation with new charger bindings.


References
==========
[1] http://thread.gmane.org/gmane.linux.kernel/1682503
[2] http://www.spinics.net/lists/kernel/msg1728274.html
[3] https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=ib-mfd-extcon-3.16

Previous, full v4 patchset can be found here:
http://thread.gmane.org/gmane.linux.kernel/1654267


Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (6):
  charger: max14577: Add support for MAX77836 charger
  regulator/mfd: max14577: Export symbols for calculating charger
    current
  charger: max14577: Configure battery-dependent settings from DTS
  power: max17040: Add ID for MAX77836 Fuel Gauge block
  regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
  devicetree: mfd: max14577: Add device tree bindings document

 Documentation/devicetree/bindings/mfd/max14577.txt | 152 +++++++++++
 drivers/mfd/max14577.c                             | 100 ++++++-
 drivers/power/Kconfig                              |   4 +-
 drivers/power/max14577_charger.c                   | 291 ++++++++++++++++++---
 drivers/power/max17040_battery.c                   |   1 +
 drivers/regulator/max14577.c                       | 139 +++++-----
 include/linux/mfd/max14577-private.h               |  92 +++++--
 include/linux/mfd/max14577.h                       |  31 +++
 8 files changed, 673 insertions(+), 137 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt

-- 
1.9.1


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

* [PATCH part2 1/6] charger: max14577: Add support for MAX77836 charger
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current Krzysztof Kozlowski
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski

Add support for MAX77836 charger to the max14577 driver. The MAX77836
charger is almost the same as 14577 model except:
 - No dead-battery detection;
 - Support for special charger (like in MAX77693);
 - Support for DX over-voltage protection (like in MAX77693);
 - Lower values of charging current (two times lower current for
   slow/fast charge, much lower EOC current);
 - Slightly different values in ChgTyp field of STATUS2 register. On
   MAX14577 0x6 is reserved and 0x7 dead battery. On the MAX77836 the
   0x6 means special charger and 0x7 is reserved. Regardless of these
   differences the driver maps them to one enum max14577_muic_charger_type.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/power/Kconfig                |  4 +-
 drivers/power/max14577_charger.c     | 77 +++++++++++++++++++++++++++++-------
 include/linux/mfd/max14577-private.h | 54 ++++++++++++++++++-------
 3 files changed, 104 insertions(+), 31 deletions(-)

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index ba6975123071..94086a5238c6 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -318,11 +318,11 @@ config CHARGER_MANAGER
           with help of suspend_again support.
 
 config CHARGER_MAX14577
-	tristate "Maxim MAX14577 MUIC battery charger driver"
+	tristate "Maxim MAX14577/77836 battery charger driver"
 	depends on MFD_MAX14577
 	help
 	  Say Y to enable support for the battery charger control sysfs and
-	  platform data of MAX14577 MUICs.
+	  platform data of MAX14577/77836 MUICs.
 
 config CHARGER_MAX8997
 	tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
diff --git a/drivers/power/max14577_charger.c b/drivers/power/max14577_charger.c
index fad2a75b3604..19c8f42abf24 100644
--- a/drivers/power/max14577_charger.c
+++ b/drivers/power/max14577_charger.c
@@ -1,7 +1,7 @@
 /*
- * Battery charger driver for the Maxim 14577
+ * max14577_charger.c - Battery charger driver for the Maxim 14577/77836
  *
- * Copyright (C) 2013 Samsung Electronics
+ * Copyright (C) 2013,2014 Samsung Electronics
  * Krzysztof Kozlowski <k.kozlowski@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,10 +25,35 @@ struct max14577_charger {
 	struct max14577	*max14577;
 	struct power_supply	charger;
 
-	unsigned int	charging_state;
-	unsigned int	battery_state;
+	unsigned int		charging_state;
+	unsigned int		battery_state;
 };
 
+/*
+ * Helper function for mapping values of STATUS2/CHGTYP register on max14577
+ * and max77836 chipsets to enum maxim_muic_charger_type.
+ */
+static enum max14577_muic_charger_type maxim_get_charger_type(
+		enum maxim_device_type dev_type, u8 val) {
+	switch (val) {
+	case MAX14577_CHARGER_TYPE_NONE:
+	case MAX14577_CHARGER_TYPE_USB:
+	case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
+	case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
+	case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
+	case MAX14577_CHARGER_TYPE_SPECIAL_1A:
+		return val;
+	case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
+	case MAX14577_CHARGER_TYPE_RESERVED:
+		if (dev_type == MAXIM_DEVICE_TYPE_MAX77836)
+			val |= 0x8;
+		return val;
+	default:
+		WARN_ONCE(1, "max14577: Unsupported chgtyp register value 0x%02x", val);
+		return val;
+	}
+}
+
 static int max14577_get_charger_state(struct max14577_charger *chg)
 {
 	struct regmap *rmap = chg->max14577->regmap;
@@ -89,19 +114,23 @@ static int max14577_get_online(struct max14577_charger *chg)
 {
 	struct regmap *rmap = chg->max14577->regmap;
 	u8 reg_data;
+	enum max14577_muic_charger_type chg_type;
 
 	max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, &reg_data);
 	reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT);
-	switch (reg_data) {
+	chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data);
+	switch (chg_type) {
 	case MAX14577_CHARGER_TYPE_USB:
 	case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
 	case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
 	case MAX14577_CHARGER_TYPE_SPECIAL_1A:
 	case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
+	case MAX77836_CHARGER_TYPE_SPECIAL_BIAS:
 		return 1;
 	case MAX14577_CHARGER_TYPE_NONE:
 	case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
 	case MAX14577_CHARGER_TYPE_RESERVED:
+	case MAX77836_CHARGER_TYPE_RESERVED:
 	default:
 		return 0;
 	}
@@ -118,10 +147,12 @@ static int max14577_get_battery_health(struct max14577_charger *chg)
 	struct regmap *rmap = chg->max14577->regmap;
 	int state = POWER_SUPPLY_HEALTH_GOOD;
 	u8 reg_data;
+	enum max14577_muic_charger_type chg_type;
 
 	max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, &reg_data);
 	reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT);
-	if (reg_data == MAX14577_CHARGER_TYPE_DEAD_BATTERY) {
+	chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data);
+	if (chg_type == MAX14577_CHARGER_TYPE_DEAD_BATTERY) {
 		state = POWER_SUPPLY_HEALTH_DEAD;
 		goto state_set;
 	}
@@ -167,7 +198,7 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
 			CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK,
 			reg_data);
 
-	/* Battery Fast-Charge Timer, from SM-V700: 6hrs */
+	/* Battery Fast-Charge Timer, set to: 6hrs */
 	reg_data = 0x3 << CHGCTRL1_TCHW_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL1, reg_data);
 
@@ -179,19 +210,22 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
 	reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data);
 
-	/* Battery-Charger Constant Voltage (CV) Mode, from SM-V700: 4.35V */
+	/* Battery-Charger Constant Voltage (CV) Mode, set to: 4.35V */
 	reg_data = 0xf << CHGCTRL3_MBCCVWRC_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL3, reg_data);
 
 	/*
-	 * Fast Battery-Charge Current Low, default 200-950mA
-	 * Fast Battery-Charge Current High, from SM-V700: 450mA
+	 * Fast Battery-Charge Current Low,
+	 * default 200-950mA (max14577) / 100-475mA (max77836)
+	 *
+	 * Fast Battery-Charge Current High,
+	 * set to 450mA (max14577) / 225mA (max77836)
 	 */
 	reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
 	reg_data |= 0x5 << CHGCTRL4_MBCICHWRCH_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL4, reg_data);
 
-	/* End-of-Charge Current, from SM-V700: 50mA */
+	/* End-of-Charge Current, set to 50mA (max14577) / 7.5mA (max77836) */
 	reg_data = 0x0 << CHGCTRL5_EOCS_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL5, reg_data);
 
@@ -199,7 +233,7 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
 	reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data);
 
-	/* Overvoltage-Protection Threshold, from SM-V700: 6.5V */
+	/* Overvoltage-Protection Threshold, set to 6.5V */
 	reg_data = 0x2 << CHGCTRL7_OTPCGHCVS_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data);
 }
@@ -215,7 +249,11 @@ static enum power_supply_property max14577_charger_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static const char *model_name = "MAX14577";
+static const char * const model_names[] = {
+	[MAXIM_DEVICE_TYPE_UNKNOWN]	= "MAX14577-like",
+	[MAXIM_DEVICE_TYPE_MAX14577]	= "MAX14577",
+	[MAXIM_DEVICE_TYPE_MAX77836]	= "MAX77836",
+};
 static const char *manufacturer = "Maxim Integrated";
 
 static int max14577_charger_get_property(struct power_supply *psy,
@@ -244,7 +282,8 @@ static int max14577_charger_get_property(struct power_supply *psy,
 		val->intval = max14577_get_online(chg);
 		break;
 	case POWER_SUPPLY_PROP_MODEL_NAME:
-		val->strval = model_name;
+		BUILD_BUG_ON(ARRAY_SIZE(model_names) != MAXIM_DEVICE_TYPE_NUM);
+		val->strval = model_names[chg->max14577->dev_type];
 		break;
 	case POWER_SUPPLY_PROP_MANUFACTURER:
 		val->strval = manufacturer;
@@ -296,6 +335,13 @@ static int max14577_charger_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id max14577_charger_id[] = {
+	{ "max14577-charger", MAXIM_DEVICE_TYPE_MAX14577, },
+	{ "max77836-charger", MAXIM_DEVICE_TYPE_MAX77836, },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, max14577_regulator_id);
+
 static struct platform_driver max14577_charger_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
@@ -303,9 +349,10 @@ static struct platform_driver max14577_charger_driver = {
 	},
 	.probe		= max14577_charger_probe,
 	.remove		= max14577_charger_remove,
+	.id_table	= max14577_charger_id,
 };
 module_platform_driver(max14577_charger_driver);
 
 MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>");
-MODULE_DESCRIPTION("MAXIM 14577 charger driver");
+MODULE_DESCRIPTION("Maxim 14577/77836 charger driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index 499253604026..d6f321699b89 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -72,15 +72,33 @@ enum max14577_muic_reg {
 	MAX14577_MUIC_REG_END,
 };
 
+/*
+ * Combined charger types for max14577 and max77836.
+ *
+ * On max14577 three lower bits map to STATUS2/CHGTYP field.
+ * However the max77836 has different two last values of STATUS2/CHGTYP.
+ * To indicate the difference enum has two additional values for max77836.
+ * These values are just a register value bitwise OR with 0x8.
+ */
 enum max14577_muic_charger_type {
-	MAX14577_CHARGER_TYPE_NONE = 0,
-	MAX14577_CHARGER_TYPE_USB,
-	MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT,
-	MAX14577_CHARGER_TYPE_DEDICATED_CHG,
-	MAX14577_CHARGER_TYPE_SPECIAL_500MA,
-	MAX14577_CHARGER_TYPE_SPECIAL_1A,
-	MAX14577_CHARGER_TYPE_RESERVED,
-	MAX14577_CHARGER_TYPE_DEAD_BATTERY = 7,
+	MAX14577_CHARGER_TYPE_NONE		= 0x0,
+	MAX14577_CHARGER_TYPE_USB		= 0x1,
+	MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT	= 0x2,
+	MAX14577_CHARGER_TYPE_DEDICATED_CHG	= 0x3,
+	MAX14577_CHARGER_TYPE_SPECIAL_500MA	= 0x4,
+	/* Special 1A or 2A charger */
+	MAX14577_CHARGER_TYPE_SPECIAL_1A	= 0x5,
+	/* max14577: reserved, used on max77836 */
+	MAX14577_CHARGER_TYPE_RESERVED		= 0x6,
+	/* max14577: dead-battery charing with maximum current 100mA */
+	MAX14577_CHARGER_TYPE_DEAD_BATTERY	= 0x7,
+	/*
+	 * max77836: special charger (bias on D+/D-),
+	 * matches register value of 0x6
+	 */
+	MAX77836_CHARGER_TYPE_SPECIAL_BIAS	= 0xe,
+	/* max77836: reserved, register value 0x7 */
+	MAX77836_CHARGER_TYPE_RESERVED		= 0xf,
 };
 
 /* MAX14577 interrupts */
@@ -121,13 +139,15 @@ enum max14577_muic_charger_type {
 #define STATUS2_CHGTYP_SHIFT		0
 #define STATUS2_CHGDETRUN_SHIFT		3
 #define STATUS2_DCDTMR_SHIFT		4
-#define STATUS2_DBCHG_SHIFT		5
+#define MAX14577_STATUS2_DBCHG_SHIFT	5
+#define MAX77836_STATUS2_DXOVP_SHIFT	5
 #define STATUS2_VBVOLT_SHIFT		6
 #define MAX77836_STATUS2_VIDRM_SHIFT	7
 #define STATUS2_CHGTYP_MASK		(0x7 << STATUS2_CHGTYP_SHIFT)
 #define STATUS2_CHGDETRUN_MASK		BIT(STATUS2_CHGDETRUN_SHIFT)
 #define STATUS2_DCDTMR_MASK		BIT(STATUS2_DCDTMR_SHIFT)
-#define STATUS2_DBCHG_MASK		BIT(STATUS2_DBCHG_SHIFT)
+#define MAX14577_STATUS2_DBCHG_MASK	BIT(MAX14577_STATUS2_DBCHG_SHIFT)
+#define MAX77836_STATUS2_DXOVP_MASK	BIT(MAX77836_STATUS2_DXOVP_SHIFT)
 #define STATUS2_VBVOLT_MASK		BIT(STATUS2_VBVOLT_SHIFT)
 #define MAX77836_STATUS2_VIDRM_MASK	BIT(MAX77836_STATUS2_VIDRM_SHIFT)
 
@@ -177,9 +197,11 @@ enum max14577_muic_charger_type {
 #define CTRL3_JIGSET_SHIFT		0
 #define CTRL3_BOOTSET_SHIFT		2
 #define CTRL3_ADCDBSET_SHIFT		4
+#define CTRL3_WBTH_SHIFT		6
 #define CTRL3_JIGSET_MASK		(0x3 << CTRL3_JIGSET_SHIFT)
 #define CTRL3_BOOTSET_MASK		(0x3 << CTRL3_BOOTSET_SHIFT)
 #define CTRL3_ADCDBSET_MASK		(0x3 << CTRL3_ADCDBSET_SHIFT)
+#define CTRL3_WBTH_MASK			(0x3 << CTRL3_WBTH_SHIFT)
 
 /* Slave addr = 0x4A: Charger */
 enum max14577_charger_reg {
@@ -210,16 +232,20 @@ enum max14577_charger_reg {
 #define CDETCTRL1_CHGTYPMAN_SHIFT	1
 #define CDETCTRL1_DCDEN_SHIFT		2
 #define CDETCTRL1_DCD2SCT_SHIFT		3
-#define CDETCTRL1_DCHKTM_SHIFT		4
-#define CDETCTRL1_DBEXIT_SHIFT		5
+#define MAX14577_CDETCTRL1_DCHKTM_SHIFT	4
+#define MAX77836_CDETCTRL1_CDLY_SHIFT	4
+#define MAX14577_CDETCTRL1_DBEXIT_SHIFT	5
+#define MAX77836_CDETCTRL1_DCDCPL_SHIFT	5
 #define CDETCTRL1_DBIDLE_SHIFT		6
 #define CDETCTRL1_CDPDET_SHIFT		7
 #define CDETCTRL1_CHGDETEN_MASK		BIT(CDETCTRL1_CHGDETEN_SHIFT)
 #define CDETCTRL1_CHGTYPMAN_MASK	BIT(CDETCTRL1_CHGTYPMAN_SHIFT)
 #define CDETCTRL1_DCDEN_MASK		BIT(CDETCTRL1_DCDEN_SHIFT)
 #define CDETCTRL1_DCD2SCT_MASK		BIT(CDETCTRL1_DCD2SCT_SHIFT)
-#define CDETCTRL1_DCHKTM_MASK		BIT(CDETCTRL1_DCHKTM_SHIFT)
-#define CDETCTRL1_DBEXIT_MASK		BIT(CDETCTRL1_DBEXIT_SHIFT)
+#define MAX14577_CDETCTRL1_DCHKTM_MASK	BIT(MAX14577_CDETCTRL1_DCHKTM_SHIFT)
+#define MAX77836_CDETCTRL1_CDDLY_MASK	BIT(MAX77836_CDETCTRL1_CDDLY_SHIFT)
+#define MAX14577_CDETCTRL1_DBEXIT_MASK	BIT(MAX14577_CDETCTRL1_DBEXIT_SHIFT)
+#define MAX77836_CDETCTRL1_DCDCPL_MASK	BIT(MAX77836_CDETCTRL1_DCDCPL_SHIFT)
 #define CDETCTRL1_DBIDLE_MASK		BIT(CDETCTRL1_DBIDLE_SHIFT)
 #define CDETCTRL1_CDPDET_MASK		BIT(CDETCTRL1_CDPDET_SHIFT)
 
-- 
1.9.1


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

* [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 1/6] charger: max14577: Add support for MAX77836 charger Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-04-24 12:48   ` Mark Brown
  2014-04-23 14:50 ` [PATCH part2 3/6] charger: max14577: Configure battery-dependent settings from DTS Krzysztof Kozlowski
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski

This patch prepares for changing the max14577 charger driver to allow
configuring battery-dependent settings from DTS.

The patch moves from regulator driver to MFD core driver and exports:
 - function for calculating register value for charger's current;
 - table of limits for chargers (MAX14577, MAX77836).

Previously they were used only by the max14577 regulator driver. In next
patch the charger driver will use them as well. Exporting them will
reduce unnecessary code duplication.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Mark Brown <broonie@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/max14577.c               | 95 ++++++++++++++++++++++++++++++++++++
 drivers/regulator/max14577.c         | 80 ++----------------------------
 include/linux/mfd/max14577-private.h | 22 ++++-----
 include/linux/mfd/max14577.h         | 23 +++++++++
 4 files changed, 133 insertions(+), 87 deletions(-)

diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index 484d372a4892..cef2149ac096 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -26,6 +26,87 @@
 #include <linux/mfd/max14577.h>
 #include <linux/mfd/max14577-private.h>
 
+/*
+ * Table of valid charger currents for different Maxim chipsets.
+ * It is placed here because it is used by both charger and regulator driver.
+ */
+const struct maxim_charger_current maxim_charger_currents[] = {
+	[MAXIM_DEVICE_TYPE_UNKNOWN] = { 0, 0, 0, 0 },
+	[MAXIM_DEVICE_TYPE_MAX14577] = {
+		.min		= MAX14577_CHARGER_CURRENT_LIMIT_MIN,
+		.high_start	= MAX14577_CHARGER_CURRENT_LIMIT_HIGH_START,
+		.high_step	= MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP,
+		.max		= MAX14577_CHARGER_CURRENT_LIMIT_MAX,
+	},
+	[MAXIM_DEVICE_TYPE_MAX77836] = {
+		.min		= MAX77836_CHARGER_CURRENT_LIMIT_MIN,
+		.high_start	= MAX77836_CHARGER_CURRENT_LIMIT_HIGH_START,
+		.high_step	= MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP,
+		.max		= MAX77836_CHARGER_CURRENT_LIMIT_MAX,
+	},
+};
+EXPORT_SYMBOL_GPL(maxim_charger_currents);
+
+/*
+ * maxim_charger_calc_reg_current - Calculate register value for current
+ * @limits:	constraints for charger, matching the MBCICHWRC register
+ * @min_ua:	minimal requested current, micro Amps
+ * @max_ua:	maximum requested current, micro Amps
+ * @dst:	destination to store calculated register value
+ *
+ * Calculates the value of MBCICHWRC (Fast Battery Charge Current) register
+ * for given current and stores it under pointed 'dst'. The stored value
+ * combines low bit (MBCICHWRCL) and high bits (MBCICHWRCH). It is also
+ * properly shifted.
+ *
+ * The calculated register value matches the current which:
+ *  - is always between <limits.min, limits.max>;
+ *  - is always less or equal to max_ua;
+ *  - is the highest possible value;
+ *  - may be lower than min_ua.
+ *
+ * On success returns 0. On error returns -EINVAL (requested min/max current
+ * is outside of given charger limits) and 'dst' is not set.
+ */
+int maxim_charger_calc_reg_current(const struct maxim_charger_current *limits,
+		unsigned int min_ua, unsigned int max_ua, u8 *dst)
+{
+	unsigned int current_bits = 0xf;
+
+	if (min_ua > max_ua)
+		return -EINVAL;
+
+	if (min_ua > limits->max || max_ua < limits->min)
+		return -EINVAL;
+
+	if (max_ua < limits->high_start) {
+		/*
+		 * Less than high_start, so set the minimal current
+		 * (turn Low Bit off, 0 as high bits).
+		 */
+		*dst = 0x0;
+		return 0;
+	}
+
+	/* max_ua is in range: <high_start, infinite>, cut it to limits.max */
+	max_ua = min(limits->max, max_ua);
+	max_ua -= limits->high_start;
+	/*
+	 * There is no risk of overflow 'max_ua' here because:
+	 *  - max_ua >= limits.high_start
+	 *  - BUILD_BUG checks that 'limits' are: max >= high_start + high_step
+	 */
+	current_bits = max_ua / limits->high_step;
+
+	/* Turn Low Bit on (use range <limits.high_start, limits.max>) ... */
+	*dst = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
+	/* and set proper High Bits */
+	*dst |= current_bits << CHGCTRL4_MBCICHWRCH_SHIFT;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(maxim_charger_calc_reg_current);
+
 static struct mfd_cell max14577_devs[] = {
 	{
 		.name = "max14577-muic",
@@ -465,6 +546,20 @@ static int __init max14577_i2c_init(void)
 	BUILD_BUG_ON(ARRAY_SIZE(max14577_i2c_id) != MAXIM_DEVICE_TYPE_NUM);
 	BUILD_BUG_ON(ARRAY_SIZE(max14577_dt_match) != MAXIM_DEVICE_TYPE_NUM);
 
+	/* Valid charger current values must be provided for each chipset */
+	BUILD_BUG_ON(ARRAY_SIZE(maxim_charger_currents) != MAXIM_DEVICE_TYPE_NUM);
+
+	/* Check for valid values for charger */
+	BUILD_BUG_ON(MAX14577_CHARGER_CURRENT_LIMIT_HIGH_START +
+			MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP * 0xf !=
+			MAX14577_CHARGER_CURRENT_LIMIT_MAX);
+	BUILD_BUG_ON(MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP == 0);
+
+	BUILD_BUG_ON(MAX77836_CHARGER_CURRENT_LIMIT_HIGH_START +
+			MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP * 0xf !=
+			MAX77836_CHARGER_CURRENT_LIMIT_MAX);
+	BUILD_BUG_ON(MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP == 0);
+
 	return i2c_add_driver(&max14577_i2c_driver);
 }
 subsys_initcall(max14577_i2c_init);
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c
index 5d9c605cf534..0ff5a20ac958 100644
--- a/drivers/regulator/max14577.c
+++ b/drivers/regulator/max14577.c
@@ -22,42 +22,6 @@
 #include <linux/mfd/max14577-private.h>
 #include <linux/regulator/of_regulator.h>
 
-/*
- * Valid limits of current for max14577 and max77836 chargers.
- * They must correspond to MBCICHWRCL and MBCICHWRCH fields in CHGCTRL4
- * register for given chipset.
- */
-struct maxim_charger_current {
-	/* Minimal current, set in CHGCTRL4/MBCICHWRCL, uA */
-	unsigned int min;
-	/*
-	 * Minimal current when high setting is active,
-	 * set in CHGCTRL4/MBCICHWRCH, uA
-	 */
-	unsigned int high_start;
-	/* Value of one step in high setting, uA */
-	unsigned int high_step;
-	/* Maximum current of high setting, uA */
-	unsigned int max;
-};
-
-/* Table of valid charger currents for different Maxim chipsets */
-static const struct maxim_charger_current maxim_charger_currents[] = {
-	[MAXIM_DEVICE_TYPE_UNKNOWN] = { 0, 0, 0, 0 },
-	[MAXIM_DEVICE_TYPE_MAX14577] = {
-		.min		= MAX14577_REGULATOR_CURRENT_LIMIT_MIN,
-		.high_start	= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START,
-		.high_step	= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP,
-		.max		= MAX14577_REGULATOR_CURRENT_LIMIT_MAX,
-	},
-	[MAXIM_DEVICE_TYPE_MAX77836] = {
-		.min		= MAX77836_REGULATOR_CURRENT_LIMIT_MIN,
-		.high_start	= MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_START,
-		.high_step	= MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_STEP,
-		.max		= MAX77836_REGULATOR_CURRENT_LIMIT_MAX,
-	},
-};
-
 static int max14577_reg_is_enabled(struct regulator_dev *rdev)
 {
 	int rid = rdev_get_id(rdev);
@@ -103,8 +67,8 @@ static int max14577_reg_get_current_limit(struct regulator_dev *rdev)
 static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
 		int min_uA, int max_uA)
 {
-	int i, current_bits = 0xf;
 	u8 reg_data;
+	int ret;
 	struct max14577 *max14577 = rdev_get_drvdata(rdev);
 	const struct maxim_charger_current *limits =
 		&maxim_charger_currents[max14577->dev_type];
@@ -112,35 +76,9 @@ static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
 	if (rdev_get_id(rdev) != MAX14577_CHARGER)
 		return -EINVAL;
 
-	if (min_uA > limits->max || max_uA < limits->min)
-		return -EINVAL;
-
-	if (max_uA < limits->high_start) {
-		/*
-		 * Less than high_start,
-		 * so set the minimal current (turn only Low Bit off)
-		 */
-		u8 reg_data = 0x0 << CHGCTRL4_MBCICHWRCL_SHIFT;
-		return max14577_update_reg(rdev->regmap,
-				MAX14577_CHG_REG_CHG_CTRL4,
-				CHGCTRL4_MBCICHWRCL_MASK, reg_data);
-	}
-
-	/*
-	 * max_uA is in range: <high_start, inifinite>, so search for
-	 * valid current starting from maximum current.
-	 */
-	for (i = limits->max; i >= limits->high_start; i -= limits->high_step) {
-		if (i <= max_uA)
-			break;
-		current_bits--;
-	}
-	BUG_ON(current_bits < 0); /* Cannot happen */
-
-	/* Turn Low Bit on (use range high_start-max)... */
-	reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
-	/* and set proper High Bits */
-	reg_data |= current_bits << CHGCTRL4_MBCICHWRCH_SHIFT;
+	ret = maxim_charger_calc_reg_current(limits, min_uA, max_uA, &reg_data);
+	if (ret)
+		return ret;
 
 	return max14577_update_reg(rdev->regmap, MAX14577_CHG_REG_CHG_CTRL4,
 			CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
@@ -442,16 +380,6 @@ static struct platform_driver max14577_regulator_driver = {
 
 static int __init max14577_regulator_init(void)
 {
-	/* Check for valid values for charger */
-	BUILD_BUG_ON(MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START +
-			MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP * 0xf !=
-			MAX14577_REGULATOR_CURRENT_LIMIT_MAX);
-	BUILD_BUG_ON(MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_START +
-			MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_STEP * 0xf !=
-			MAX77836_REGULATOR_CURRENT_LIMIT_MAX);
-	/* Valid charger current values must be provided for each chipset */
-	BUILD_BUG_ON(ARRAY_SIZE(maxim_charger_currents) != MAXIM_DEVICE_TYPE_NUM);
-
 	BUILD_BUG_ON(ARRAY_SIZE(max14577_supported_regulators) != MAX14577_REGULATOR_NUM);
 	BUILD_BUG_ON(ARRAY_SIZE(max77836_supported_regulators) != MAX77836_REGULATOR_NUM);
 
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index d6f321699b89..7d514839c764 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -281,17 +281,17 @@ enum max14577_charger_reg {
 #define CHGCTRL7_OTPCGHCVS_SHIFT	0
 #define CHGCTRL7_OTPCGHCVS_MASK		(0x3 << CHGCTRL7_OTPCGHCVS_SHIFT)
 
-/* MAX14577 regulator current limits (as in CHGCTRL4 register), uA */
-#define MAX14577_REGULATOR_CURRENT_LIMIT_MIN		 90000
-#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START	200000
-#define MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP	 50000
-#define MAX14577_REGULATOR_CURRENT_LIMIT_MAX		950000
-
-/* MAX77836 regulator current limits (as in CHGCTRL4 register), uA */
-#define MAX77836_REGULATOR_CURRENT_LIMIT_MIN		 45000
-#define MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_START	100000
-#define MAX77836_REGULATOR_CURRENT_LIMIT_HIGH_STEP	 25000
-#define MAX77836_REGULATOR_CURRENT_LIMIT_MAX		475000
+/* MAX14577 charger current limits (as in CHGCTRL4 register), uA */
+#define MAX14577_CHARGER_CURRENT_LIMIT_MIN		 90000U
+#define MAX14577_CHARGER_CURRENT_LIMIT_HIGH_START	200000U
+#define MAX14577_CHARGER_CURRENT_LIMIT_HIGH_STEP	 50000U
+#define MAX14577_CHARGER_CURRENT_LIMIT_MAX		950000U
+
+/* MAX77836 charger current limits (as in CHGCTRL4 register), uA */
+#define MAX77836_CHARGER_CURRENT_LIMIT_MIN		 45000U
+#define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_START	100000U
+#define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP	 25000U
+#define MAX77836_CHARGER_CURRENT_LIMIT_MAX		475000U
 
 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE		4900000
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
index c83fbed1c7b6..3c098d57b1d1 100644
--- a/include/linux/mfd/max14577.h
+++ b/include/linux/mfd/max14577.h
@@ -74,4 +74,27 @@ struct max14577_platform_data {
 	struct max14577_regulator_platform_data *regulators;
 };
 
+/*
+ * Valid limits of current for max14577 and max77836 chargers.
+ * They must correspond to MBCICHWRCL and MBCICHWRCH fields in CHGCTRL4
+ * register for given chipset.
+ */
+struct maxim_charger_current {
+	/* Minimal current, set in CHGCTRL4/MBCICHWRCL, uA */
+	unsigned int min;
+	/*
+	 * Minimal current when high setting is active,
+	 * set in CHGCTRL4/MBCICHWRCH, uA
+	 */
+	unsigned int high_start;
+	/* Value of one step in high setting, uA */
+	unsigned int high_step;
+	/* Maximum current of high setting, uA */
+	unsigned int max;
+};
+
+extern const struct maxim_charger_current maxim_charger_currents[];
+extern int maxim_charger_calc_reg_current(const struct maxim_charger_current *limits,
+		unsigned int min_ua, unsigned int max_ua, u8 *dst);
+
 #endif /* __MAX14577_H__ */
-- 
1.9.1


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

* [PATCH part2 3/6] charger: max14577: Configure battery-dependent settings from DTS
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 1/6] charger: max14577: Add support for MAX77836 charger Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 4/6] power: max17040: Add ID for MAX77836 Fuel Gauge block Krzysztof Kozlowski
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski, Jenny Tc

Remove hard-coded values for:
 - Fast Charge current,
 - End Of Charge current,
 - Fast Charge timer,
 - Overvoltage Protection Threshold,
 - Battery Constant Voltage,
and use DTS to configure them. This allows using the max14577 charger
driver with different batteries.

Now the charger driver requires valid configuration data from DTS. In
case of wrong configuration data it fails during probe. Patch adds
of_compatible to the charger mfd cell in MFD driver core.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Jenny Tc <jenny.tc@intel.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/max14577.c               |   5 +-
 drivers/power/max14577_charger.c     | 232 +++++++++++++++++++++++++++++++----
 include/linux/mfd/max14577-private.h |  16 +++
 include/linux/mfd/max14577.h         |   8 ++
 4 files changed, 233 insertions(+), 28 deletions(-)

diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index cef2149ac096..13030573a8ca 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -116,7 +116,10 @@ static struct mfd_cell max14577_devs[] = {
 		.name = "max14577-regulator",
 		.of_compatible = "maxim,max14577-regulator",
 	},
-	{ .name = "max14577-charger", },
+	{
+		.name = "max14577-charger",
+		.of_compatible = "maxim,max14577-charger",
+	},
 };
 
 static struct mfd_cell max77836_devs[] = {
diff --git a/drivers/power/max14577_charger.c b/drivers/power/max14577_charger.c
index 19c8f42abf24..f32f94a9a144 100644
--- a/drivers/power/max14577_charger.c
+++ b/drivers/power/max14577_charger.c
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 #include <linux/mfd/max14577-private.h>
+#include <linux/mfd/max14577.h>
 
 struct max14577_charger {
 	struct device *dev;
@@ -27,6 +28,8 @@ struct max14577_charger {
 
 	unsigned int		charging_state;
 	unsigned int		battery_state;
+
+	struct max14577_charger_platform_data	*pdata;
 };
 
 /*
@@ -178,15 +181,107 @@ static int max14577_get_present(struct max14577_charger *chg)
 	return 1;
 }
 
+static inline int max14577_init_constant_voltage(struct max14577_charger *chg,
+		unsigned int uvolt)
+{
+	u8 reg_data;
+
+	if (uvolt < MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN ||
+			uvolt > MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
+		return -EINVAL;
+
+	if (uvolt == 4200000)
+		reg_data = 0x0;
+	else if (uvolt == MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
+		reg_data = 0x1f;
+	else if (uvolt <= 4280000) {
+		unsigned int val = uvolt;
+
+		val -= MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN;
+		val /= MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP;
+		if (uvolt <= 4180000)
+			reg_data = 0x1 + val;
+		else
+			reg_data = val; /* Fix for gap between 4.18V and 4.22V */
+	} else
+		return -EINVAL;
+
+	reg_data <<= CHGCTRL3_MBCCVWRC_SHIFT;
+
+	return max14577_write_reg(chg->max14577->regmap,
+			MAX14577_CHG_REG_CHG_CTRL3, reg_data);
+}
+
+static inline int max14577_init_eoc(struct max14577_charger *chg,
+		unsigned int uamp)
+{
+	unsigned int current_bits = 0xf;
+	u8 reg_data;
+
+	switch (chg->max14577->dev_type) {
+	case MAXIM_DEVICE_TYPE_MAX77836:
+		if (uamp < 5000)
+			return -EINVAL; /* Requested current is too low */
+
+		if (uamp >= 7500 && uamp < 10000)
+			current_bits = 0x0;
+		else if (uamp <= 50000) {
+			/* <5000, 7499> and <10000, 50000> */
+			current_bits = uamp / 5000;
+		} else {
+			uamp = min(uamp, 100000U) - 50000U;
+			current_bits = 0xa + uamp / 10000;
+		}
+		break;
+
+	case MAXIM_DEVICE_TYPE_MAX14577:
+	default:
+		if (uamp < MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN)
+			return -EINVAL; /* Requested current is too low */
+
+		uamp = min(uamp, MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
+		uamp -= MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN;
+		current_bits = uamp / MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP;
+		break;
+	}
+
+	reg_data = current_bits << CHGCTRL5_EOCS_SHIFT;
+
+	return max14577_update_reg(chg->max14577->regmap,
+			MAX14577_CHG_REG_CHG_CTRL5, CHGCTRL5_EOCS_MASK,
+			reg_data);
+}
+
+static inline int max14577_init_fast_charge(struct max14577_charger *chg,
+		unsigned int uamp)
+{
+	u8 reg_data;
+	int ret;
+	const struct maxim_charger_current *limits =
+		&maxim_charger_currents[chg->max14577->dev_type];
+
+	ret = maxim_charger_calc_reg_current(limits, uamp, uamp, &reg_data);
+	if (ret) {
+		dev_err(chg->dev, "Wrong value for fast charge: %u\n", uamp);
+		return ret;
+	}
+
+	return max14577_update_reg(chg->max14577->regmap,
+			MAX14577_CHG_REG_CHG_CTRL4,
+			CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
+			reg_data);
+}
+
 /*
  * Sets charger registers to proper and safe default values.
  * Some of these values are equal to defaults in MAX14577E
  * data sheet but there are minor differences.
  */
-static void max14577_charger_reg_init(struct max14577_charger *chg)
+static int max14577_charger_reg_init(struct max14577_charger *chg)
 {
 	struct regmap *rmap = chg->max14577->regmap;
 	u8 reg_data;
+	int ret;
 
 	/*
 	 * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0)
@@ -198,10 +293,6 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
 			CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK,
 			reg_data);
 
-	/* Battery Fast-Charge Timer, set to: 6hrs */
-	reg_data = 0x3 << CHGCTRL1_TCHW_SHIFT;
-	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL1, reg_data);
-
 	/*
 	 * Wall-Adapter Rapid Charge, default on
 	 * Battery-Charger, default on
@@ -210,32 +301,57 @@ static void max14577_charger_reg_init(struct max14577_charger *chg)
 	reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data);
 
-	/* Battery-Charger Constant Voltage (CV) Mode, set to: 4.35V */
-	reg_data = 0xf << CHGCTRL3_MBCCVWRC_SHIFT;
-	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL3, reg_data);
-
-	/*
-	 * Fast Battery-Charge Current Low,
-	 * default 200-950mA (max14577) / 100-475mA (max77836)
-	 *
-	 * Fast Battery-Charge Current High,
-	 * set to 450mA (max14577) / 225mA (max77836)
-	 */
-	reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
-	reg_data |= 0x5 << CHGCTRL4_MBCICHWRCH_SHIFT;
-	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL4, reg_data);
-
-	/* End-of-Charge Current, set to 50mA (max14577) / 7.5mA (max77836) */
-	reg_data = 0x0 << CHGCTRL5_EOCS_SHIFT;
-	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL5, reg_data);
-
 	/* Auto Charging Stop, default off */
 	reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data);
 
-	/* Overvoltage-Protection Threshold, set to 6.5V */
-	reg_data = 0x2 << CHGCTRL7_OTPCGHCVS_SHIFT;
+	ret = max14577_init_constant_voltage(chg, chg->pdata->constant_uvolt);
+	if (ret)
+		return ret;
+
+	ret = max14577_init_eoc(chg, chg->pdata->eoc_uamp);
+	if (ret)
+		return ret;
+
+	ret = max14577_init_fast_charge(chg, chg->pdata->fast_charge_uamp);
+	if (ret)
+		return ret;
+
+	/* Initialize Battery Fast-Charge Timer */
+	switch (chg->pdata->fast_charge_timer) {
+	case 5 ... 7:
+		reg_data = chg->pdata->fast_charge_timer - 3;
+		break;
+	case 0:
+		/* Disable */
+		reg_data = 0x7;
+	default:
+		dev_err(chg->dev, "Wrong value for Fast-Charge Timer: %u\n",
+				chg->pdata->fast_charge_timer);
+		return -EINVAL;
+	}
+	reg_data <<= CHGCTRL1_TCHW_SHIFT;
+	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL1, reg_data);
+
+	/* Initialize Overvoltage-Protection Threshold */
+	switch (chg->pdata->ovp_uvolt) {
+	case 7500000:
+		reg_data = 0x0;
+		break;
+	case 6000000:
+	case 6500000:
+	case 7000000:
+		reg_data = 0x1 + (chg->pdata->ovp_uvolt - 6000000) / 500000;
+		break;
+	default:
+		dev_err(chg->dev, "Wrong value for OVP: %u\n",
+				chg->pdata->ovp_uvolt);
+		return -EINVAL;
+	}
+	reg_data <<= CHGCTRL7_OTPCGHCVS_SHIFT;
 	max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data);
+
+	return 0;
 }
 
 /* Support property from charger */
@@ -295,6 +411,58 @@ static int max14577_charger_get_property(struct power_supply *psy,
 	return ret;
 }
 
+#ifdef CONFIG_OF
+static struct max14577_charger_platform_data *max14577_charger_dt_init(
+		struct platform_device *pdev)
+{
+	struct max14577_charger_platform_data *pdata;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np) {
+		dev_err(&pdev->dev, "No charger OF node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Memory alloc for charger pdata failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = of_property_read_u32(np, "maxim,fast-charge-timer",
+			&pdata->fast_charge_timer);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "maxim,constant-uvolt",
+			&pdata->constant_uvolt);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "maxim,fast-charge-uamp",
+			&pdata->fast_charge_uamp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "maxim,eoc-uamp", &pdata->eoc_uamp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "maxim,ovp-uvolt", &pdata->ovp_uvolt);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+static struct max14577_charger_platform_data *max14577_charger_dt_init(
+		struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
 static int max14577_charger_probe(struct platform_device *pdev)
 {
 	struct max14577_charger *chg;
@@ -309,7 +477,13 @@ static int max14577_charger_probe(struct platform_device *pdev)
 	chg->dev = &pdev->dev;
 	chg->max14577 = max14577;
 
-	max14577_charger_reg_init(chg);
+	chg->pdata = max14577_charger_dt_init(pdev);
+	if (IS_ERR_OR_NULL(chg->pdata))
+		return PTR_ERR(chg->pdata);
+
+	ret = max14577_charger_reg_init(chg);
+	if (ret)
+		return ret;
 
 	chg->charger.name = "max14577-charger",
 	chg->charger.type = POWER_SUPPLY_TYPE_BATTERY,
@@ -323,6 +497,10 @@ static int max14577_charger_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* Check for valid values for charger */
+	BUILD_BUG_ON(MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN +
+			MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP * 0xf !=
+			MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
 	return 0;
 }
 
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index 7d514839c764..5c842f3b6da5 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -293,6 +293,22 @@ enum max14577_charger_reg {
 #define MAX77836_CHARGER_CURRENT_LIMIT_HIGH_STEP	 25000U
 #define MAX77836_CHARGER_CURRENT_LIMIT_MAX		475000U
 
+/*
+ * MAX14577 charger End-Of-Charge current limits
+ * (as in CHGCTRL5 register), uA
+ */
+#define MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN		50000U
+#define MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP		10000U
+#define MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX		200000U
+
+/*
+ * MAX14577/MAX77836 Battery Constant Voltage
+ * (as in CHGCTRL3 register), uV
+ */
+#define MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN		4000000U
+#define MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP		20000U
+#define MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX		4350000U
+
 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE		4900000
 
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
index 3c098d57b1d1..d068846a13cf 100644
--- a/include/linux/mfd/max14577.h
+++ b/include/linux/mfd/max14577.h
@@ -54,6 +54,14 @@ struct max14577_regulator_platform_data {
 	struct device_node *of_node;
 };
 
+struct max14577_charger_platform_data {
+	unsigned int fast_charge_timer;
+	unsigned int constant_uvolt;
+	unsigned int fast_charge_uamp;
+	unsigned int eoc_uamp;
+	unsigned int ovp_uvolt;
+};
+
 /*
  * MAX14577 MFD platform data
  */
-- 
1.9.1


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

* [PATCH part2 4/6] power: max17040: Add ID for MAX77836 Fuel Gauge block
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
                   ` (2 preceding siblings ...)
  2014-04-23 14:50 ` [PATCH part2 3/6] charger: max14577: Configure battery-dependent settings from DTS Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-04-23 14:50 ` [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s Krzysztof Kozlowski
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski

MAX77836 has the same Fuel Gauge as MAX17040/17048. The max17040 driver
can be safely re-used. The patch adds MAX77836 ID to array of
i2c_device_id.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
---
 drivers/power/max17040_battery.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c
index 0fbac861080d..165ffe381803 100644
--- a/drivers/power/max17040_battery.c
+++ b/drivers/power/max17040_battery.c
@@ -278,6 +278,7 @@ static SIMPLE_DEV_PM_OPS(max17040_pm_ops, max17040_suspend, max17040_resume);
 
 static const struct i2c_device_id max17040_id[] = {
 	{ "max17040", 0 },
+	{ "max77836-battery", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max17040_id);
-- 
1.9.1


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

* [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
                   ` (3 preceding siblings ...)
  2014-04-23 14:50 ` [PATCH part2 4/6] power: max17040: Add ID for MAX77836 Fuel Gauge block Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-04-28 11:14   ` Lee Jones
  2014-05-01 18:19   ` Mark Brown
  2014-04-23 14:50 ` [PATCH part2 6/6] devicetree: mfd: max14577: Add device tree bindings document Krzysztof Kozlowski
  2014-05-06  7:38 ` [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
  6 siblings, 2 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski

The MAX77836 LDO regulators support low power mode. In this mode the
maximum load current is 5 mA and the quiescent supply current is 1.5 uA.

This patch adds support for mode REGULATOR_MODE_STANDBY (and NORMAL) to
LDO regulators by implementing the set_mode() and get_mode() operations.
However the necessary regulator constraints (valid modes) are not parsed
by of_regulator_match() so the driver adds them manually to the
regulator init_data.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/regulator/max14577.c         | 61 ++++++++++++++++++++++++++++++++++--
 include/linux/mfd/max14577-private.h |  2 ++
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c
index 0ff5a20ac958..b7657d211a5b 100644
--- a/drivers/regulator/max14577.c
+++ b/drivers/regulator/max14577.c
@@ -18,9 +18,10 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/mfd/max14577.h>
 #include <linux/mfd/max14577-private.h>
-#include <linux/regulator/of_regulator.h>
 
 static int max14577_reg_is_enabled(struct regulator_dev *rdev)
 {
@@ -85,6 +86,45 @@ static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
 			reg_data);
 }
 
+static unsigned int max77836_reg_ldo_get_mode(struct regulator_dev *rdev)
+{
+	u8 reg_data;
+	int err;
+
+	err = max14577_read_reg(rdev->regmap, rdev->desc->enable_reg,
+			&reg_data);
+	if (err) {
+		dev_err(rdev_get_dev(rdev),
+				"Error reading control register for %d: %d\n",
+				rdev_get_id(rdev), err);
+		return REGULATOR_MODE_NORMAL;
+	}
+
+	reg_data &= rdev->desc->enable_mask;
+
+	if (reg_data == MAX77836_CNFG1_LDO_PWRMD_LOW_POWER)
+		return REGULATOR_MODE_STANDBY;
+
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int max77836_reg_ldo_set_mode(struct regulator_dev *rdev,
+		unsigned int mode)
+{
+	switch (mode) {
+	case REGULATOR_MODE_STANDBY:
+		return max14577_update_reg(rdev->regmap,
+				rdev->desc->enable_reg, rdev->desc->enable_mask,
+				MAX77836_CNFG1_LDO_PWRMD_LOW_POWER);
+
+	case REGULATOR_MODE_NORMAL:
+		return regulator_enable_regmap(rdev);
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static struct regulator_ops max14577_safeout_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
 	.enable			= regulator_enable_regmap,
@@ -131,7 +171,8 @@ static struct regulator_ops max77836_ldo_ops = {
 	.map_voltage		= regulator_map_voltage_linear,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
-	/* TODO: add .set_suspend_mode */
+	.get_mode		= max77836_reg_ldo_get_mode,
+	.set_mode		= max77836_reg_ldo_set_mode,
 };
 
 static const struct regulator_desc max77836_supported_regulators[] = {
@@ -198,6 +239,19 @@ static struct of_regulator_match max77836_regulator_matches[] = {
 	{ .name = "LDO2", },
 };
 
+static void
+max77836_regulator_init_constraints(struct of_regulator_match *matches)
+{
+	int i;
+	struct regulation_constraints *c;
+
+	for (i = MAX77836_LDO1; i <= MAX77836_LDO2; i++) {
+		c = &matches[i].init_data->constraints;
+		c->valid_modes_mask = REGULATOR_MODE_NORMAL
+			| REGULATOR_MODE_STANDBY;
+	}
+}
+
 static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
 		enum maxim_device_type dev_type)
 {
@@ -232,6 +286,9 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
 
 	of_node_put(np);
 
+	if (dev_type == MAXIM_DEVICE_TYPE_MAX77836)
+		max77836_regulator_init_constraints(regulator_matches);
+
 	return ret;
 }
 
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index 5c842f3b6da5..9b03506b76ff 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -357,6 +357,8 @@ enum max77836_pmic_reg {
 #define MAX77836_CNFG1_LDO_TV_SHIFT		0
 #define MAX77836_CNFG1_LDO_PWRMD_MASK		(0x3 << MAX77836_CNFG1_LDO_PWRMD_SHIFT)
 #define MAX77836_CNFG1_LDO_TV_MASK		(0x3f << MAX77836_CNFG1_LDO_TV_SHIFT)
+/* Value to write to CONFIG1/PWRMD field for enabling low power mode */
+#define MAX77836_CNFG1_LDO_PWRMD_LOW_POWER	BIT(MAX77836_CNFG1_LDO_PWRMD_SHIFT)
 
 /* LDO1/LDO2 CONFIG2 register */
 #define MAX77836_CNFG2_LDO_OVCLMPEN_SHIFT	7
-- 
1.9.1


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

* [PATCH part2 6/6] devicetree: mfd: max14577: Add device tree bindings document
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
                   ` (4 preceding siblings ...)
  2014-04-23 14:50 ` [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s Krzysztof Kozlowski
@ 2014-04-23 14:50 ` Krzysztof Kozlowski
  2014-05-06  7:38 ` [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
  6 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-23 14:50 UTC (permalink / raw)
  To: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, Mark Brown, linux-kernel
  Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Krzysztof Kozlowski, devicetree,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala

Add document describing device tree bindings for MAX14577 MFD
drivers: MFD core, extcon, regulator and charger.

Both MAX14577 and MAX77836 chipsets are documented.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Tomasz Figa <t.figa@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
---
 Documentation/devicetree/bindings/mfd/max14577.txt | 152 +++++++++++++++++++++
 1 file changed, 152 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt

diff --git a/Documentation/devicetree/bindings/mfd/max14577.txt b/Documentation/devicetree/bindings/mfd/max14577.txt
new file mode 100644
index 000000000000..b235250a7b41
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/max14577.txt
@@ -0,0 +1,152 @@
+Maxim MAX14577/77836 Multi-Function Device
+
+MAX14577 is a Multi-Function Device with Micro-USB Interface Circuit, Li+
+Battery Charger and SFOUT LDO output for powering USB devices. It is
+interfaced to host controller using I2C.
+
+MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
+
+
+Required properties:
+- compatible : Must be "maxim,max14577" or "maxim,max77836".
+- reg : I2C slave address for the max14577 chip (0x25 for max14577/max77836)
+- interrupts : IRQ line for the chip.
+- interrupt-parent :  The parent interrupt controller.
+
+
+Required nodes:
+ - charger :
+	Node for configuring the charger driver.
+	Required properties:
+		- compatible : "maxim,max14577-charger"
+			or "maxim,max77836-charger"
+		- maxim,fast-charge-timer : Timer in hours to trigger the
+			INT3/MBCCHGERR interrupt; Valid values:
+			- 5, 6 or 7 (hours),
+			- 0 to disable.
+		- maxim,fast-charge-uamp : Current in uA for Fast Charge;
+			Valid values:
+			- for max14577: 90000 - 950000;
+			- for max77836: 45000 - 475000;
+		- maxim,eoc-uamp : Current in uA for End-Of-Charge mode;
+			Valid values:
+			- for max14577: 50000 - 200000;
+			- for max77836: 5000 - 100000;
+		- maxim,ovp-uvolt : OverVoltage Protection Threshold in uV;
+			In an overvoltage condition, INT asserts and charging
+			stops. Valid values:
+			- 6000000, 6500000, 7000000, 7500000;
+		- maxim,constant-uvolt : Battery Constant Voltage in uV;
+			Valid values:
+			- 4000000 - 4280000 (step by 20000);
+			- 4350000;
+
+
+Optional nodes:
+- max14577-muic/max77836-muic :
+	Node used only by extcon consumers.
+	Required properties:
+		- compatible : "maxim,max14577-muic" or "maxim,max77836-muic"
+
+- regulators :
+	Required properties:
+		- compatible : "maxim,max14577-regulator"
+			or "maxim,max77836-regulator"
+
+	May contain a sub-node per regulator from the list below. Each
+	sub-node should contain the constraints and initialization information
+	for that regulator. See regulator.txt for a description of standard
+	properties for these sub-nodes.
+
+	List of valid regulator names:
+	- for max14577: CHARGER, SAFEOUT.
+	- for max77836: CHARGER, SAFEOUT, LDO1, LDO2.
+
+	The SAFEOUT is a fixed voltage regulator so there is no need to specify
+	voltages for it.
+
+
+Example:
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+max14577@25 {
+	compatible = "maxim,max14577";
+	reg = <0x25>;
+	interrupt-parent = <&gpx1>;
+	interrupts = <5 IRQ_TYPE_NONE>;
+
+	muic: max14577-muic {
+		compatible = "maxim,max14577-muic";
+	};
+
+	regulators {
+		compatible = "maxim,max14577-regulator";
+
+		SAFEOUT {
+			regulator-name = "SAFEOUT";
+		};
+		CHARGER {
+			regulator-name = "CHARGER";
+			regulator-min-microamp = <90000>;
+			regulator-max-microamp = <950000>;
+			regulator-boot-on;
+		};
+	};
+
+	charger {
+		compatible = "maxim,max14577-charger";
+
+		maxim,fast-charge-timer = <6>;
+		maxim,constant-uvolt = <4350000>;
+		maxim,fast-charge-uamp = <450000>;
+		maxim,eoc-uamp = <50000>;
+		maxim,ovp-uvolt = <6500000>;
+	};
+};
+
+
+max77836@25 {
+	compatible = "maxim,max77836";
+	reg = <0x25>;
+	interrupt-parent = <&gpx1>;
+	interrupts = <5 IRQ_TYPE_NONE>;
+
+	muic: max77836-muic {
+		compatible = "maxim,max77836-muic";
+	};
+
+	regulators {
+		compatible = "maxim,max77836-regulator";
+
+		SAFEOUT {
+			regulator-name = "SAFEOUT";
+		};
+		CHARGER {
+			regulator-name = "CHARGER";
+			regulator-min-microamp = <90000>;
+			regulator-max-microamp = <950000>;
+			regulator-boot-on;
+		};
+		LDO1 {
+			regulator-name = "LDO1";
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <2700000>;
+		};
+		LDO2 {
+			regulator-name = "LDO2";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+	};
+
+	charger {
+		compatible = "maxim,max77836-charger";
+
+		maxim,fast-charge-timer = <6>;
+		maxim,constant-uvolt = <4350000>;
+		maxim,fast-charge-uamp = <225000>;
+		maxim,eoc-uamp = <7500>;
+		maxim,ovp-uvolt = <6500000>;
+	};
+};
-- 
1.9.1


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

* Re: [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current
  2014-04-23 14:50 ` [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current Krzysztof Kozlowski
@ 2014-04-24 12:48   ` Mark Brown
  2014-04-25 13:45     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2014-04-24 12:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

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

On Wed, Apr 23, 2014 at 04:50:36PM +0200, Krzysztof Kozlowski wrote:
> This patch prepares for changing the max14577 charger driver to allow
> configuring battery-dependent settings from DTS.

Acked-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current
  2014-04-24 12:48   ` Mark Brown
@ 2014-04-25 13:45     ` Krzysztof Kozlowski
  2014-04-25 14:16       ` Mark Brown
  0 siblings, 1 reply; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-04-25 13:45 UTC (permalink / raw)
  To: Mark Brown
  Cc: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

On czw, 2014-04-24 at 13:48 +0100, Mark Brown wrote:
> On Wed, Apr 23, 2014 at 04:50:36PM +0200, Krzysztof Kozlowski wrote:
> > This patch prepares for changing the max14577 charger driver to allow
> > configuring battery-dependent settings from DTS.
> 
> Acked-by: Mark Brown <broonie@linaro.org>

Hi Mark,

Thanks for the ack, however this patch already got it:
https://lkml.org/lkml/2014/2/7/640

I need your ack on the fifth patch:
 * [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for
   MAX77836 LDO-s

Best regards,
Krzysztof




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

* Re: [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current
  2014-04-25 13:45     ` Krzysztof Kozlowski
@ 2014-04-25 14:16       ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2014-04-25 14:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

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

On Fri, Apr 25, 2014 at 03:45:31PM +0200, Krzysztof Kozlowski wrote:

> Thanks for the ack, however this patch already got it:
> https://lkml.org/lkml/2014/2/7/640

If something has already been reviewed or acked you should be including
that in reposts, otherwise nobody is going to remember that the review
happened.

> I need your ack on the fifth patch:
>  * [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for
>    MAX77836 LDO-s

I'll get to it at some point.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
  2014-04-23 14:50 ` [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s Krzysztof Kozlowski
@ 2014-04-28 11:14   ` Lee Jones
  2014-05-01 18:19   ` Mark Brown
  1 sibling, 0 replies; 14+ messages in thread
From: Lee Jones @ 2014-04-28 11:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Samuel Ortiz, Dmitry Eremin-Solenikov, David Woodhouse,
	Liam Girdwood, Mark Brown, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

On Wed, 23 Apr 2014, Krzysztof Kozlowski wrote:

> The MAX77836 LDO regulators support low power mode. In this mode the
> maximum load current is 5 mA and the quiescent supply current is 1.5 uA.
> 
> This patch adds support for mode REGULATOR_MODE_STANDBY (and NORMAL) to
> LDO regulators by implementing the set_mode() and get_mode() operations.
> However the necessary regulator constraints (valid modes) are not parsed
> by of_regulator_match() so the driver adds them manually to the
> regulator init_data.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/regulator/max14577.c         | 61 ++++++++++++++++++++++++++++++++++--
>  include/linux/mfd/max14577-private.h |  2 ++

For the MFD changes:
  Acked-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
  2014-04-23 14:50 ` [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s Krzysztof Kozlowski
  2014-04-28 11:14   ` Lee Jones
@ 2014-05-01 18:19   ` Mark Brown
  2014-05-05  8:47     ` Krzysztof Kozlowski
  1 sibling, 1 reply; 14+ messages in thread
From: Mark Brown @ 2014-05-01 18:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

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

On Wed, Apr 23, 2014 at 04:50:39PM +0200, Krzysztof Kozlowski wrote:

> This patch adds support for mode REGULATOR_MODE_STANDBY (and NORMAL) to
> LDO regulators by implementing the set_mode() and get_mode() operations.
> However the necessary regulator constraints (valid modes) are not parsed
> by of_regulator_match() so the driver adds them manually to the
> regulator init_data.

No, that's not the idea here.  The reason that the modes need to be
explicitly enabled is that there's an element of board design in
determining if a given mode can satisfy the required current demand for
the board with sufficient quality (usually the lower power modes have
both a lower maximum current and poorer regulation accuracy especially
as the current rises).  Doing it unconditionally isn't in general
reliable.

The reason that the modes aren't supported by DT is that defining a
binding is hard - it's not clear what exactly a "mode" means since it's
basically a Linux internal thing.  We probably need to explicitly add
definitions of the modes to the bindings for individual devices
unfortunately (ie, saying "mode X maps to Y in the datasheet", possibly
using the datasheet modes in the binding for ease of use and having that
translation in the driver).

Ideally we'd be able to have the automatic mode setting working for
devices but in practice nobody wants to publish the numbers and working
out how much the board needs can also be hard so that isn't really
practical.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
  2014-05-01 18:19   ` Mark Brown
@ 2014-05-05  8:47     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-05-05  8:47 UTC (permalink / raw)
  To: Mark Brown
  Cc: Samuel Ortiz, Lee Jones, Dmitry Eremin-Solenikov,
	David Woodhouse, Liam Girdwood, linux-kernel, Kyungmin Park,
	Marek Szyprowski, Bartlomiej Zolnierkiewicz, Tomasz Figa,
	Anton Vorontsov

On czw, 2014-05-01 at 11:19 -0700, Mark Brown wrote:
> On Wed, Apr 23, 2014 at 04:50:39PM +0200, Krzysztof Kozlowski wrote:
> 
> > This patch adds support for mode REGULATOR_MODE_STANDBY (and NORMAL) to
> > LDO regulators by implementing the set_mode() and get_mode() operations.
> > However the necessary regulator constraints (valid modes) are not parsed
> > by of_regulator_match() so the driver adds them manually to the
> > regulator init_data.
> 
> No, that's not the idea here.  The reason that the modes need to be
> explicitly enabled is that there's an element of board design in
> determining if a given mode can satisfy the required current demand for
> the board with sufficient quality (usually the lower power modes have
> both a lower maximum current and poorer regulation accuracy especially
> as the current rises).  Doing it unconditionally isn't in general
> reliable.
> 
> The reason that the modes aren't supported by DT is that defining a
> binding is hard - it's not clear what exactly a "mode" means since it's
> basically a Linux internal thing.  We probably need to explicitly add
> definitions of the modes to the bindings for individual devices
> unfortunately (ie, saying "mode X maps to Y in the datasheet", possibly
> using the datasheet modes in the binding for ease of use and having that
> translation in the driver).
> 
> Ideally we'd be able to have the automatic mode setting working for
> devices but in practice nobody wants to publish the numbers and working
> out how much the board needs can also be hard so that isn't really
> practical.

I understand. Lets skip this patch now. I will prepare in the future a
version of this patch with own DT binding for max77836 suspend mode.

Best regards,
Krzysztof


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

* Re: [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836
  2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
                   ` (5 preceding siblings ...)
  2014-04-23 14:50 ` [PATCH part2 6/6] devicetree: mfd: max14577: Add device tree bindings document Krzysztof Kozlowski
@ 2014-05-06  7:38 ` Krzysztof Kozlowski
  6 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2014-05-06  7:38 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov, David Woodhouse
  Cc: Lee Jones, Liam Girdwood, Mark Brown, linux-kernel,
	Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
	Tomasz Figa, Anton Vorontsov, Samuel Ortiz

Hi Dmitry, David,


I need acks or reviews from power supply subsystem maintainers for
patches:
 - 1/6: charger: max14577: Add support for MAX77836 charger
 - 3/6: charger: max14577: Configure battery-dependent settings from DTS
 - 4/6: power: max17040: Add ID for MAX77836 Fuel Gauge block
These patches were published for the first time around February 2014.


Could you look at them?


Best regards,
Krzysztof


On śro, 2014-04-23 at 16:50 +0200, Krzysztof Kozlowski wrote:
> Hi,
> 
> 
> This is second part of patches adding support for MAX77836 device
> to the max14577 drivers.
> 
> The first part [1] was applied by Lee Jones [2][3] and this patchset *depends*
> on it.
> 
> This patchset changes the max14577 charger and regulator drivers
> and documents Device Tree bindings.
> 
> The patches 1 to 3 depends on each other so they should be pulled at once.
> Patches 4, 5 and 6 can be applied independently. However still the
> smoothest way to apply this would be through one tree after obtaining
> necessary acks from maintainers.
> 
> I need acks from power (patches: 1, 3, 4) and regulator (patch 5) trees.
> 
> 
> Changes since v4 (for this second part only)
> ============================================
> 1. Updated Kconfig entries mentioning MAX77836.
> 2. Added patch 5/6 (regulator: max14577: Implement SUSPEND mode for
>    MAX77836 LDO-s)
> 3. Charger: Require a charger subnode in DTS with charger settings.
>    Previously the charger driver didn't use any properties from DTS.
>    Now it needs a subnode with settings because it supports different
>    devices with different charging characteristics.
> 4. Rebased on 3.15-rc2.
> 
> Changes since v3
> ================
> 1. Applied minor fixes (pointed by Lee Jones).
> 2. Added one ACK (Lee Jones) and Review-by (Tomasz Figa).
> 3. Patch 14/charger: Minor change in parsing EOC value from DTS.
> 4. Rebased on next-20140224.
> 
> Changes since v2
> ================
> 1. Added ACK-s.
> 2. Applied minor checkpatch fixes (pointed by Lee Jones).
> 3. Rebased on next-20140217.
> 
> Changes since v1
> ================
> 1. Added ACK-s, reviews and tested-by tags.
> 2. Removed applied patches (they were merged to the linux-next tree).
> 3. Applied comments from review (Lee Jones) to 5/15 (detection of device type)
>    and 8/15 (add max77836 support to max14577).
> 4. Rebased on next tree.
> 5. Added patch 13 and 14 (pointed by Jenny Tc):
>    - regulator/mfd: max14577: Export symbols for calculating charger current
>    - charger: max14577: Configure battery-dependent settings from DTS
> 6. Updated bindings documentation with new charger bindings.
> 
> 
> References
> ==========
> [1] http://thread.gmane.org/gmane.linux.kernel/1682503
> [2] http://www.spinics.net/lists/kernel/msg1728274.html
> [3] https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=ib-mfd-extcon-3.16
> 
> Previous, full v4 patchset can be found here:
> http://thread.gmane.org/gmane.linux.kernel/1654267
> 
> 
> Best regards,
> Krzysztof Kozlowski
> 
> 
> Krzysztof Kozlowski (6):
>   charger: max14577: Add support for MAX77836 charger
>   regulator/mfd: max14577: Export symbols for calculating charger
>     current
>   charger: max14577: Configure battery-dependent settings from DTS
>   power: max17040: Add ID for MAX77836 Fuel Gauge block
>   regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s
>   devicetree: mfd: max14577: Add device tree bindings document
> 
>  Documentation/devicetree/bindings/mfd/max14577.txt | 152 +++++++++++
>  drivers/mfd/max14577.c                             | 100 ++++++-
>  drivers/power/Kconfig                              |   4 +-
>  drivers/power/max14577_charger.c                   | 291 ++++++++++++++++++---
>  drivers/power/max17040_battery.c                   |   1 +
>  drivers/regulator/max14577.c                       | 139 +++++-----
>  include/linux/mfd/max14577-private.h               |  92 +++++--
>  include/linux/mfd/max14577.h                       |  31 +++
>  8 files changed, 673 insertions(+), 137 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt
> 


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

end of thread, other threads:[~2014-05-06  7:38 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-23 14:50 [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski
2014-04-23 14:50 ` [PATCH part2 1/6] charger: max14577: Add support for MAX77836 charger Krzysztof Kozlowski
2014-04-23 14:50 ` [PATCH part2 2/6] regulator/mfd: max14577: Export symbols for calculating charger current Krzysztof Kozlowski
2014-04-24 12:48   ` Mark Brown
2014-04-25 13:45     ` Krzysztof Kozlowski
2014-04-25 14:16       ` Mark Brown
2014-04-23 14:50 ` [PATCH part2 3/6] charger: max14577: Configure battery-dependent settings from DTS Krzysztof Kozlowski
2014-04-23 14:50 ` [PATCH part2 4/6] power: max17040: Add ID for MAX77836 Fuel Gauge block Krzysztof Kozlowski
2014-04-23 14:50 ` [PATCH part2 5/6] regulator: max14577: Implement SUSPEND mode for MAX77836 LDO-s Krzysztof Kozlowski
2014-04-28 11:14   ` Lee Jones
2014-05-01 18:19   ` Mark Brown
2014-05-05  8:47     ` Krzysztof Kozlowski
2014-04-23 14:50 ` [PATCH part2 6/6] devicetree: mfd: max14577: Add device tree bindings document Krzysztof Kozlowski
2014-05-06  7:38 ` [PATCH part2 0/6] charger/mfd: max14577: Part 2 of adding support for MAX77836 Krzysztof Kozlowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).