~postmarketos/upstreaming

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
13 3

[PATCH v3 00/10] power: supply: max77693: Toggle charging/OTG based on extcon status

Details
Message ID
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com>
DKIM signature
pass
Download raw message
This patchset does the following:

- Add CURRENT_MAX and INPUT_CURRENT_MAX power supply properties to
  expose the "fast charge current" (maximum current from charger to
  battery) and "CHGIN input current limit" (maximum current from
  external supply to charger).

- Add functions for toggling charging and OTG modes.

- Add an extcon-based handler that enables charging or OTG depending
  on the cable type plugged in. The extcon device to use for cable
  detection can be specified in the device tree, and is entirely
  optional.

The extcon listener implementation is inspired by the rt5033 charger
driver (commit 8242336dc8a8 ("power: supply: rt5033_charger: Add cable
detection and USB OTG supply")).

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
v3 no longer uses the CHARGER regulator to manage the power status, and
that's for two reasons:

- Regulator enable/disable behavior was interfering with how the power
  supply driver worked (we occasionally got "unbalanced disables"
  errors when switching charging state, despite checking for the
  regulator status with regulator_is_enabled() - the CHARGER reg would
  report as enabled despite the enable count being 0).
  This broke OTG insertion if the OTG cable was plugged in first, and
  sometimes caused warnings on unsuspend.

- Changing the charging values directly in the power supply driver is
  less opaque and lets us avoid bringing in a dependency on regulators.

It also splits the current limits back into two properties:
INPUT_CURRENT_LIMIT and CONSTANT_CHARGE_CURRENT_MAX. Again, there are
two reasons for this split:

- They are two separate current controls, one for USB->charger and one
  for charger->battery, and they have different limits (0-2.1A for CC
  vs 60mA-2.58A for input). Given that the power supply core has the
  properties for both values separately, it's more logical to present
  them as such.

- It's safer to keep these separate; CONSTANT_CHARGE_CURRENT_MAX is
  pretty explicitly only set *once* - at probe time with a safe value
  specified in the DT. This way, INPUT_CURRENT_LIMIT is safer to modify
  since in the event of an invalid value the CC current will hold back
  the extra current thus preventing damage to the battery.

The latter is relevant as I'm working on a follow-up patchset that
allows for controlling the charging parameters using power supply
properties/sysfs properties rather than the CHARGER regulator.

Note that the CHARGER regulator gets disabled automatically if it's
not used, which will disable charging if it was auto-enabled by the
extcon code. This can be worked around by re-attaching the cable, or
more properly by removing the CHARGER regulator from DT for devices
that use the extcon-based charger management, as has been done in the
Galaxy Tab 3 8.0 DTSI.

See v1 for old description:

https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com
---
Changes in v3:
- Drop uses of CHARGER regulator, manage registers directly in power
  supply driver instead
- Link to v2: https://lore.kernel.org/r/20240715-max77693-charger-extcon-v2-0-0838ffbb18c3@gmail.com

Changes in v2:
- Changed to use monitored-battery for charge current value
- Both current limit variables are now set by the CHARGER regulator
- Link to v1: https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com

---
Artur Weber (10):
      dt-bindings: power: supply: max77693: Add monitored-battery property
      dt-bindings: power: supply: max77693: Add maxim,usb-connector property
      power: supply: max77693: Expose input current limit and CC current properties
      power: supply: max77693: Set charge current limits during init
      power: supply: max77693: Add USB extcon detection for enabling charging
      power: supply: max77693: Add support for detecting and enabling OTG
      power: supply: max77693: Set up charge/input current according to cable type
      ARM: dts: samsung: exynos4212-tab3: Add battery node with charge current value
      ARM: dts: samsung: exynos4212-tab3: Add USB connector node
      ARM: dts: exynos4212-tab3: Drop CHARGER regulator

 .../bindings/power/supply/maxim,max77693.yaml      |  15 +
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi     |  22 +-
 drivers/power/supply/Kconfig                       |   1 +
 drivers/power/supply/max77693_charger.c            | 302 ++++++++++++++++++++-
 include/linux/mfd/max77693-private.h               |  12 +
 5 files changed, 337 insertions(+), 15 deletions(-)
---
base-commit: 0c3836482481200ead7b416ca80c68a29cfdaabd
change-id: 20240525-max77693-charger-extcon-9ebb7bad83ce

Best regards,
-- 
Artur Weber <aweber.kernel@gmail.com>

[PATCH v3 01/10] dt-bindings: power: supply: max77693: Add monitored-battery property

Details
Message ID
<20240729-max77693-charger-extcon-v3-1-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +9 -0
Add the monitored-battery property, so that its constant charge current
property can be used to specify the current limit to use for fast charge
(when plugged into a wall charger).

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v2:
- Switched to monitored-battery property from separate fast charge
  current property
---
 .../devicetree/bindings/power/supply/maxim,max77693.yaml         | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
index f5fd53debbc8..2f4437dafdc0 100644
--- a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
@@ -16,10 +16,19 @@ description: |
  See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for
  additional information and example.

allOf:
  - $ref: power-supply.yaml#

properties:
  compatible:
    const: maxim,max77693-charger

  monitored-battery:
    description:
      Phandle to "simple-battery"-compatible battery node.
      The constant-charge-current-max-microamps property of the battery
      node is used to specify the fast charge current.

  maxim,constant-microvolt:
    description: |
      Battery constant voltage in uV. The charger will operate in fast

-- 
2.45.2

[PATCH v3 02/10] dt-bindings: power: supply: max77693: Add maxim,usb-connector property

Details
Message ID
<20240729-max77693-charger-extcon-v3-2-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +6 -0
Allow for specifying a USB connector to use for charger type/OTG cable
detection.

The way this is done is inspired by the rt5033-charger implementation.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
 Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
index 2f4437dafdc0..b70c171bd4b9 100644
--- a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
@@ -73,6 +73,12 @@ properties:
    enum: [4300000, 4700000, 4800000, 4900000]
    default: 4300000

  maxim,usb-connector:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      USB connector to use for charger type/OTG cable detection. Phandle
      to a USB connector according to usb-connector.yaml.

required:
  - compatible


-- 
2.45.2

[PATCH v3 03/10] power: supply: max77693: Expose input current limit and CC current properties

Details
Message ID
<20240729-max77693-charger-extcon-v3-3-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +57 -0
There are two charger current limit registers:

- Fast charge current limit (which controls current going from the
  charger to the battery);
- CHGIN input current limit (which controls current going into the
  charger through the cable).

Add the necessary functions to retrieve the CHGIN input limit (from CHARGER
regulator) and maximum fast charge current values, and expose them as power
supply properties.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Dropped CHARGER reg reference in favor of managing the registers
  directly
- Changed to use CONSTANT_CHARGE_CURRENT_MAX instead of CURRENT_MAX
  for fast charge/CC current property

Changes in v2:
- Adapted to both current limits being managed in the CHARGER regulator
---
 drivers/power/supply/max77693_charger.c | 52 +++++++++++++++++++++++++++++++++
 include/linux/mfd/max77693-private.h    |  5 ++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 2001e12c9f7d..4caac142c428 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -197,12 +197,58 @@ static int max77693_get_online(struct regmap *regmap, int *val)
	return 0;
}

/*
 * There are *two* current limit registers:
 * - CHGIN limit, which limits the input current from the external charger;
 * - Fast charge current limit, which limits the current going to the battery.
 */

static int max77693_get_input_current_limit(struct regmap *regmap, int *val)
{
	unsigned int data;
	int ret;

	ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_09, &data);
	if (ret < 0)
		return ret;

	data &= CHG_CNFG_09_CHGIN_ILIM_MASK;
	data >>= CHG_CNFG_09_CHGIN_ILIM_SHIFT;

	if (data <= 0x03)
		/* The first four values (0x00..0x03) are 60mA */
		*val = 60000;
	else
		*val = data * 20000; /* 20mA steps */

	return 0;
}

static int max77693_get_fast_charge_current(struct regmap *regmap, int *val)
{
	unsigned int data;
	int ret;

	ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_02, &data);
	if (ret < 0)
		return ret;

	data &= CHG_CNFG_02_CC_MASK;
	data >>= CHG_CNFG_02_CC_SHIFT;

	*val = data * 33300; /* 33.3mA steps */

	return 0;
}

static enum power_supply_property max77693_charger_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_CHARGE_TYPE,
	POWER_SUPPLY_PROP_HEALTH,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_MANUFACTURER,
};
@@ -231,6 +277,12 @@ static int max77693_charger_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_ONLINE:
		ret = max77693_get_online(regmap, &val->intval);
		break;
	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
		ret = max77693_get_input_current_limit(regmap, &val->intval);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		ret = max77693_get_fast_charge_current(regmap, &val->intval);
		break;
	case POWER_SUPPLY_PROP_MODEL_NAME:
		val->strval = max77693_charger_model;
		break;
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 54444ff2a5de..20c5e02ed9da 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -217,6 +217,10 @@ enum max77693_charger_battery_state {
#define CHG_CNFG_01_CHGRSTRT_MASK	(0x3 << CHG_CNFG_01_CHGRSTRT_SHIFT)
#define CHG_CNFG_01_PQEN_MAKS		BIT(CHG_CNFG_01_PQEN_SHIFT)

/* MAX77693_CHG_REG_CHG_CNFG_02 register */
#define CHG_CNFG_02_CC_SHIFT		0
#define CHG_CNFG_02_CC_MASK		0x3F

/* MAX77693_CHG_REG_CHG_CNFG_03 register */
#define CHG_CNFG_03_TOITH_SHIFT		0
#define CHG_CNFG_03_TOTIME_SHIFT	3
@@ -244,6 +248,7 @@ enum max77693_charger_battery_state {
#define CHG_CNFG_12_VCHGINREG_MASK	(0x3 << CHG_CNFG_12_VCHGINREG_SHIFT)

/* MAX77693 CHG_CNFG_09 Register */
#define CHG_CNFG_09_CHGIN_ILIM_SHIFT	0
#define CHG_CNFG_09_CHGIN_ILIM_MASK	0x7F

/* MAX77693 CHG_CTRL Register */

-- 
2.45.2

[PATCH v3 04/10] power: supply: max77693: Set charge current limits during init

Details
Message ID
<20240729-max77693-charger-extcon-v3-4-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +73 -11
There are two charger current limit registers:

- Fast charge current limit (which controls current going from the
  charger to the battery);
- CHGIN input current limit (which controls current going into the
  charger through the cable).

Add functions for setting both of the values, and set them to a
safe default value of 500mA at initialization.

The value for the fast charge current limit can be modified by setting
the constant-charge-current-max-ua DT property of the battery node
specified in the monitored-battery charger DT property; the CHGIN input
current limit will be set up later in the charger detection mechanism
(in the future, the INPUT_CURRENT_LIMIT property could also be made
writeable for userspace control of the current limit, while keeping
the actual current limit from the charger to the battery intact
so that users don't accidentally blow up their batteries with a bad
value).

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Dropped CHARGER reg in favor of managing the registers directly

Changes in v2:
- Squashed mfd include register additions into this commit
- Changed from custom fast charge current property to monitored-battery
  (devm_power_supply_register call has been moved up as it is needed by
  the DT init function now)
- Changed to adapt to both current limit values being managed by the
  CHARGER regulator
---
 drivers/power/supply/max77693_charger.c | 82 ++++++++++++++++++++++++++++-----
 include/linux/mfd/max77693-private.h    |  2 +
 2 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 4caac142c428..17975ec69a6a 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -26,6 +26,7 @@ struct max77693_charger {
	u32 min_system_volt;
	u32 thermal_regulation_temp;
	u32 batttery_overcurrent;
	u32 fast_charge_current;
	u32 charge_input_threshold_volt;
};

@@ -596,6 +597,48 @@ static int max77693_set_batttery_overcurrent(struct max77693_charger *chg,
			CHG_CNFG_12_B2SOVRC_MASK, data);
}

static int max77693_set_input_current_limit(struct max77693_charger *chg,
		unsigned int uamp)
{
	unsigned int data;

	if (uamp < 60000 || uamp > 2540000) {
		dev_err(chg->dev, "Wrong value for input current limit");
		return -EINVAL;
	};

	data = uamp / 20000; /* 20mA steps */

	data <<= CHG_CNFG_09_CHGIN_ILIM_SHIFT;

	dev_dbg(chg->dev, "Input current limit: %u (0x%x)\n", uamp, data);

	return regmap_update_bits(chg->max77693->regmap,
			MAX77693_CHG_REG_CHG_CNFG_09,
			CHG_CNFG_09_CHGIN_ILIM_MASK, data);
}

static int max77693_set_fast_charge_current(struct max77693_charger *chg,
		unsigned int uamp)
{
	unsigned int data;

	if (uamp > 2100000) {
		dev_err(chg->dev, "Wrong value for fast charge current\n");
		return -EINVAL;
	}

	data = uamp / 33300; /* 0.1A/3 steps */

	data <<= CHG_CNFG_02_CC_SHIFT;

	dev_dbg(chg->dev, "Fast charge current: %u (0x%x)\n", uamp, data);

	return regmap_update_bits(chg->max77693->regmap,
			MAX77693_CHG_REG_CHG_CNFG_02,
			CHG_CNFG_02_CC_MASK, data);
}

static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg,
		unsigned int uvolt)
{
@@ -673,6 +716,15 @@ static int max77693_reg_init(struct max77693_charger *chg)
	if (ret)
		return ret;

	ret = max77693_set_fast_charge_current(chg, chg->fast_charge_current);
	if (ret)
		return ret;

	ret = max77693_set_input_current_limit(chg,
				DEFAULT_FAST_CHARGE_CURRENT);
	if (ret)
		return ret;

	return max77693_set_charge_input_threshold_volt(chg,
			chg->charge_input_threshold_volt);
}
@@ -681,6 +733,7 @@ static int max77693_reg_init(struct max77693_charger *chg)
static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
{
	struct device_node *np = dev->of_node;
	struct power_supply_battery_info *battery_info;

	if (!np) {
		dev_err(dev, "no charger OF node\n");
@@ -708,11 +761,20 @@ static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
		chg->charge_input_threshold_volt =
			DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT;

	if (power_supply_get_battery_info(chg->charger, &battery_info) ||
			!battery_info->constant_charge_current_max_ua)
		chg->fast_charge_current = DEFAULT_FAST_CHARGE_CURRENT;
	else
		chg->fast_charge_current =
			battery_info->constant_charge_current_max_ua;

	return 0;
}
#else /* CONFIG_OF */
static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
{
	chg->fast_charge_current = DEFAULT_FAST_CHARGE_CURRENT;

	return 0;
}
#endif /* CONFIG_OF */
@@ -732,6 +794,15 @@ static int max77693_charger_probe(struct platform_device *pdev)
	chg->dev = &pdev->dev;
	chg->max77693 = max77693;

	psy_cfg.drv_data = chg;

	chg->charger = devm_power_supply_register(&pdev->dev,
						  &max77693_charger_desc,
						  &psy_cfg);
	if (IS_ERR(chg->charger))
		return dev_err_probe(&pdev->dev, PTR_ERR(chg->charger),
				     "failed: power supply register\n");

	ret = max77693_dt_init(&pdev->dev, chg);
	if (ret)
		return ret;
@@ -740,8 +811,6 @@ static int max77693_charger_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	psy_cfg.drv_data = chg;

	ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
	if (ret) {
		dev_err(&pdev->dev, "failed: create fast charge timer sysfs entry\n");
@@ -761,15 +830,6 @@ static int max77693_charger_probe(struct platform_device *pdev)
		goto err;
	}

	chg->charger = devm_power_supply_register(&pdev->dev,
						  &max77693_charger_desc,
						  &psy_cfg);
	if (IS_ERR(chg->charger)) {
		dev_err(&pdev->dev, "failed: power supply register\n");
		ret = PTR_ERR(chg->charger);
		goto err;
	}

	return 0;

err:
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 20c5e02ed9da..0819cf0a4f5f 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -145,6 +145,8 @@ enum max77693_pmic_reg {
#define DEFAULT_THERMAL_REGULATION_TEMP		100
/* microamps */
#define DEFAULT_BATTERY_OVERCURRENT		3500000
/* microamps */
#define DEFAULT_FAST_CHARGE_CURRENT		500000
/* microvolts */
#define DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT	4300000


-- 
2.45.2

[PATCH v3 05/10] power: supply: max77693: Add USB extcon detection for enabling charging

Details
Message ID
<20240729-max77693-charger-extcon-v3-5-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +121 -0
1. Add a function that allows for enabling/disabling charging.

2. Add a device tree property, "maxim,usb-connector", that can be used to
specify a USB connector to use to detect whether a charging cable has
been plugged in/out, and enable/disable charging accordingly.

The extcon listener/worker implementation is inspired by the rt5033_charger
driver.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Adapted to both limits being split up again
- Move charging/extcon work functions above reg_init
- Drop unnecessary extcon unregister from probe error path
- Change disconnect message

Changes in v2:
- Changed to adapt to both current limits being managed by one function
---
 drivers/power/supply/Kconfig            |   1 +
 drivers/power/supply/max77693_charger.c | 120 ++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+)

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 3e31375491d5..e4aeff9e7ad1 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -549,6 +549,7 @@ config CHARGER_MAX77650
config CHARGER_MAX77693
	tristate "Maxim MAX77693 battery charger driver"
	depends on MFD_MAX77693
	depends on EXTCON || !EXTCON
	help
	  Say Y to enable support for the Maxim MAX77693 battery charger.

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 17975ec69a6a..2e05467c682e 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -5,6 +5,8 @@
// Copyright (C) 2014 Samsung Electronics
// Krzysztof Kozlowski <krzk@kernel.org>

#include <linux/devm-helpers.h>
#include <linux/extcon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
@@ -28,6 +30,13 @@ struct max77693_charger {
	u32 batttery_overcurrent;
	u32 fast_charge_current;
	u32 charge_input_threshold_volt;

	/* USB cable notifications */
	struct {
		struct extcon_dev *edev;
		struct notifier_block nb;
		struct work_struct work;
	} cable;
};

static int max77693_get_charger_state(struct regmap *regmap, int *val)
@@ -668,6 +677,77 @@ static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg
			CHG_CNFG_12_VCHGINREG_MASK, data);
}

static int max77693_set_charging(struct max77693_charger *chg, bool enable)
{
	unsigned int data;

	if (enable)
		data = CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK;
	else
		data = ~(CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK);

	return regmap_update_bits(chg->max77693->regmap,
			MAX77693_CHG_REG_CHG_CNFG_00,
			CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK,
			data);
}

static void max77693_charger_extcon_work(struct work_struct *work)
{
	struct max77693_charger *chg = container_of(work, struct max77693_charger,
						  cable.work);
	struct extcon_dev *edev = chg->cable.edev;
	int connector, state;
	int ret;

	for (connector = EXTCON_USB_HOST; connector <= EXTCON_CHG_USB_PD;
	     connector++) {
		state = extcon_get_state(edev, connector);
		if (state == 1)
			break;
	}

	switch (connector) {
	case EXTCON_CHG_USB_SDP:
	case EXTCON_CHG_USB_DCP:
	case EXTCON_CHG_USB_CDP:
	case EXTCON_CHG_USB_ACA:
	case EXTCON_CHG_USB_FAST:
	case EXTCON_CHG_USB_SLOW:
	case EXTCON_CHG_USB_PD:
		ret = max77693_set_charging(chg, true);
		if (ret) {
			dev_err(chg->dev, "failed to enable charging\n");
			break;
		}
		dev_info(chg->dev, "charging. connector type: %d\n",
			 connector);
		break;
	default:
		ret = max77693_set_charging(chg, false);
		if (ret) {
			dev_err(chg->dev, "failed to disable charging\n");
			break;
		}
		dev_info(chg->dev, "not charging. connector type: %d\n",
			 connector);
		break;
	}

	power_supply_changed(chg->charger);
}

static int max77693_charger_extcon_notifier(struct notifier_block *nb,
					  unsigned long event, void *param)
{
	struct max77693_charger *chg = container_of(nb, struct max77693_charger,
						    cable.nb);

	schedule_work(&chg->cable.work);

	return NOTIFY_OK;
}

/*
 * Sets charger registers to proper and safe default values.
 */
@@ -734,12 +814,32 @@ static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
{
	struct device_node *np = dev->of_node;
	struct power_supply_battery_info *battery_info;
	struct device_node *np_conn, *np_edev;

	if (!np) {
		dev_err(dev, "no charger OF node\n");
		return -EINVAL;
	}

	np_conn = of_parse_phandle(np, "maxim,usb-connector", 0);
	np_edev = of_get_parent(np_conn);

	chg->cable.edev = extcon_find_edev_by_node(np_edev);
	if (IS_ERR(chg->cable.edev)) {
		/*
		 * In case of deferred extcon probe, defer our probe as well
		 * until it appears.
		 */
		if (PTR_ERR(chg->cable.edev) == -EPROBE_DEFER)
			return PTR_ERR(chg->cable.edev);
		/*
		 * Otherwise, ignore errors (the charger can run without a
		 * connector provided).
		 */
		dev_warn(dev, "no extcon device found in device-tree (%ld)\n",
			 PTR_ERR(chg->cable.edev));
	}

	if (of_property_read_u32(np, "maxim,constant-microvolt",
			&chg->constant_volt))
		chg->constant_volt = DEFAULT_CONSTANT_VOLT;
@@ -811,6 +911,26 @@ static int max77693_charger_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	/* Set up extcon if the USB connector node was found */
	if (!IS_ERR(chg->cable.edev)) {
		ret = devm_work_autocancel(&pdev->dev, &chg->cable.work,
					   max77693_charger_extcon_work);
		if (ret) {
			dev_err(&pdev->dev, "failed: initialize extcon work\n");
			return ret;
		}

		chg->cable.nb.notifier_call = max77693_charger_extcon_notifier;

		ret = devm_extcon_register_notifier_all(&pdev->dev,
							chg->cable.edev,
							&chg->cable.nb);
		if (ret) {
			dev_err(&pdev->dev, "failed: register extcon notifier\n");
			return ret;
		}
	}

	ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
	if (ret) {
		dev_err(&pdev->dev, "failed: create fast charge timer sysfs entry\n");

-- 
2.45.2

[PATCH v3 06/10] power: supply: max77693: Add support for detecting and enabling OTG

Details
Message ID
<20240729-max77693-charger-extcon-v3-6-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +48 -10
Building upon the newly added extcon detection support, add detection
for USB OTG cables (EXTCON_USB_HOST type), and enable/disable the OTG
bits as needed.

Acked-by: Lee Jones <lee@kernel.org>
Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Dropped CHARGER regulator in favor of enabling charging directly

Changes in v2:
- Added CHGIN OTG current limit value
- Squashed MFD header register changes into this commit
---
 drivers/power/supply/max77693_charger.c | 53 ++++++++++++++++++++++++++-------
 include/linux/mfd/max77693-private.h    |  5 ++++
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 2e05467c682e..4ff402941d72 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -692,11 +692,30 @@ static int max77693_set_charging(struct max77693_charger *chg, bool enable)
			data);
}

static int max77693_set_otg(struct max77693_charger *chg, bool enable)
{
	unsigned int data;

	if (enable)
		data = CHG_CNFG_00_OTG_MASK | CHG_CNFG_00_BOOST_MASK |
				CHG_CNFG_00_DIS_MUIC_CTRL_MASK;
	else
		data = ~(CHG_CNFG_00_OTG_MASK | CHG_CNFG_00_BOOST_MASK |
				CHG_CNFG_00_DIS_MUIC_CTRL_MASK);

	return regmap_update_bits(chg->max77693->regmap,
			MAX77693_CHG_REG_CHG_CNFG_00,
			CHG_CNFG_00_OTG_MASK | CHG_CNFG_00_BOOST_MASK |
			CHG_CNFG_00_DIS_MUIC_CTRL_MASK,
			data);
}

static void max77693_charger_extcon_work(struct work_struct *work)
{
	struct max77693_charger *chg = container_of(work, struct max77693_charger,
						  cable.work);
	struct extcon_dev *edev = chg->cable.edev;
	bool set_charging, set_otg;
	int connector, state;
	int ret;

@@ -715,25 +734,39 @@ static void max77693_charger_extcon_work(struct work_struct *work)
	case EXTCON_CHG_USB_FAST:
	case EXTCON_CHG_USB_SLOW:
	case EXTCON_CHG_USB_PD:
		ret = max77693_set_charging(chg, true);
		if (ret) {
			dev_err(chg->dev, "failed to enable charging\n");
			break;
		}
		set_charging = true;
		set_otg = false;

		dev_info(chg->dev, "charging. connector type: %d\n",
			 connector);
		break;
	case EXTCON_USB_HOST:
		set_charging = false;
		set_otg = true;

		dev_info(chg->dev, "USB host. connector type: %d\n",
			 connector);
		break;
	default:
		ret = max77693_set_charging(chg, false);
		if (ret) {
			dev_err(chg->dev, "failed to disable charging\n");
			break;
		}
		set_charging = false;
		set_otg = false;

		dev_info(chg->dev, "not charging. connector type: %d\n",
			 connector);
		break;
	}

	ret = max77693_set_charging(chg, set_charging);
	if (ret) {
		dev_err(chg->dev, "failed to set charging (%d)\n", ret);
		goto out;
	}

	ret = max77693_set_otg(chg, set_otg);
	if (ret)
		dev_err(chg->dev, "failed to set OTG (%d)\n", ret);

out:
	power_supply_changed(chg->charger);
}

diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 0819cf0a4f5f..1fd93bfbf3dc 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -209,7 +209,10 @@ enum max77693_charger_battery_state {

/* MAX77693 CHG_CNFG_00 register */
#define CHG_CNFG_00_CHG_MASK		0x1
#define CHG_CNFG_00_OTG_MASK		0x2
#define CHG_CNFG_00_BUCK_MASK		0x4
#define CHG_CNFG_00_BOOST_MASK		0x8
#define CHG_CNFG_00_DIS_MUIC_CTRL_MASK	0x20

/* MAX77693_CHG_REG_CHG_CNFG_01 register */
#define CHG_CNFG_01_FCHGTIME_SHIFT	0
@@ -222,6 +225,8 @@ enum max77693_charger_battery_state {
/* MAX77693_CHG_REG_CHG_CNFG_02 register */
#define CHG_CNFG_02_CC_SHIFT		0
#define CHG_CNFG_02_CC_MASK		0x3F
#define CHG_CNFG_02_OTG_ILIM_SHIFT	7
#define CHG_CNFG_02_OTG_ILIM_MASK	0x80

/* MAX77693_CHG_REG_CHG_CNFG_03 register */
#define CHG_CNFG_03_TOITH_SHIFT		0

-- 
2.45.2

[PATCH v3 07/10] power: supply: max77693: Set up charge/input current according to cable type

Details
Message ID
<20240729-max77693-charger-extcon-v3-7-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +20 -3
This behavior was observed on a downstream kernel - for chargers, the
current would be set to a fast charge current value, and it would be
bumped down for all other cable types.

If we leave only the fast charge current value applied, peripheral mode
stops working. If we stick to 500mA, charging becomes too slow. So, set
the charge input current limit accordingly to the cable type.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Re-introduced this commit from v1. It seems to have been accidentally
  rolled into the previous commit in v2.
---
 drivers/power/supply/max77693_charger.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 4ff402941d72..a3aeaba77309 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -716,6 +716,7 @@ static void max77693_charger_extcon_work(struct work_struct *work)
						  cable.work);
	struct extcon_dev *edev = chg->cable.edev;
	bool set_charging, set_otg;
	unsigned int input_current;
	int connector, state;
	int ret;

@@ -728,19 +729,28 @@ static void max77693_charger_extcon_work(struct work_struct *work)

	switch (connector) {
	case EXTCON_CHG_USB_SDP:
	case EXTCON_CHG_USB_DCP:
	case EXTCON_CHG_USB_CDP:
	case EXTCON_CHG_USB_SLOW:
		input_current = 500000; /* 500 mA */
		set_charging = true;
		set_otg = false;

		dev_info(chg->dev, "slow charging. connector type: %d\n",
			 connector);
		break;
	case EXTCON_CHG_USB_DCP:
	case EXTCON_CHG_USB_ACA:
	case EXTCON_CHG_USB_FAST:
	case EXTCON_CHG_USB_SLOW:
	case EXTCON_CHG_USB_PD:
		input_current = chg->fast_charge_current;
		set_charging = true;
		set_otg = false;

		dev_info(chg->dev, "charging. connector type: %d\n",
		dev_info(chg->dev, "fast charging. connector type: %d\n",
			 connector);
		break;
	case EXTCON_USB_HOST:
		input_current = 500000; /* 500 mA */
		set_charging = false;
		set_otg = true;

@@ -748,6 +758,7 @@ static void max77693_charger_extcon_work(struct work_struct *work)
			 connector);
		break;
	default:
		input_current = 500000; /* 500 mA */
		set_charging = false;
		set_otg = false;

@@ -756,6 +767,12 @@ static void max77693_charger_extcon_work(struct work_struct *work)
		break;
	}

	ret = max77693_set_input_current_limit(chg, input_current);
	if (ret) {
		dev_err(chg->dev, "failed to set input current (%d)\n", ret);
		goto out;
	}

	ret = max77693_set_charging(chg, set_charging);
	if (ret) {
		dev_err(chg->dev, "failed to set charging (%d)\n", ret);

-- 
2.45.2

[PATCH v3 08/10] ARM: dts: samsung: exynos4212-tab3: Add battery node with charge current value

Details
Message ID
<20240729-max77693-charger-extcon-v3-8-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +6 -0
This value was verified by comparing register dumps of the MAX77693
charger with on mainline with a downstream kernel under Android; the
value on downstream was set to 1.8 amps when charging with a proper
charger.

Add it to a new battery node and pass it to the MAX77693 charger
so that the fast charge current setting can be used for charging.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v2:
- Switched to monitored-battery
---
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index 9bc05961577d..3c905bfedd96 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -159,6 +159,7 @@ charger_reg: CHARGER {

			charger {
				compatible = "maxim,max77693-charger";
				monitored-battery = <&battery>;

				maxim,constant-microvolt = <4350000>;
				maxim,min-system-microvolt = <3600000>;
@@ -300,6 +301,11 @@ submic_bias_reg: voltage-regulator-5 {
		regulator-max-microvolt = <2800000>;
	};

	battery: battery {
		compatible = "simple-battery";
		constant-charge-current-max-microamp = <1800000>;
	};

	sound: sound {
		compatible = "samsung,midas-audio";
		model = "TAB3";

-- 
2.45.2

[PATCH v3 09/10] ARM: dts: samsung: exynos4212-tab3: Add USB connector node

Details
Message ID
<20240729-max77693-charger-extcon-v3-9-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +13 -0
Add a subnode to the MAX77693 MFD for the MUIC and connect the USB
connector node to the charger to allow for charger type/OTG cable
detection.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index 3c905bfedd96..7309b4e1cc3d 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -157,6 +157,17 @@ charger_reg: CHARGER {
				};
			};

			muic {
				compatible = "maxim,max77693-muic";

				usb_conn: connector {
					compatible = "samsung,usb-connector-11pin",
						     "usb-b-connector";
					label = "micro-USB";
					type = "micro";
				};
			};

			charger {
				compatible = "maxim,max77693-charger";
				monitored-battery = <&battery>;
@@ -166,6 +177,8 @@ charger {
				maxim,thermal-regulation-celsius = <100>;
				maxim,battery-overcurrent-microamp = <3500000>;
				maxim,charge-input-threshold-microvolt = <4300000>;

				maxim,usb-connector = <&usb_conn>;
			};
		};
	};

-- 
2.45.2

[PATCH v3 10/10] ARM: dts: exynos4212-tab3: Drop CHARGER regulator

Details
Message ID
<20240729-max77693-charger-extcon-v3-10-02315a6869d4@gmail.com>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +0 -7
We don't use it for managing charging, and it interferes with the
extcon-based charging mode switching.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v3:
- Added this commit
---
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index 7309b4e1cc3d..2006cdcf3909 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -148,13 +148,6 @@ esafeout1_reg: ESAFEOUT1 {
				esafeout2_reg: ESAFEOUT2 {
					regulator-name = "ESAFEOUT2";
				};

				charger_reg: CHARGER {
					regulator-name = "CHARGER";
					regulator-min-microamp = <60000>;
					regulator-max-microamp = <2580000>;
					regulator-boot-on;
				};
			};

			muic {

-- 
2.45.2
Details
Message ID
<20240801062253.GA2681@l14.localdomain>
In-Reply-To
<20240729-max77693-charger-extcon-v3-0-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Hi Artur,

On Mon, Jul 29, 2024 at 07:47:34PM +0200, Artur Weber wrote:
> This patchset does the following:
> 
> - Add CURRENT_MAX and INPUT_CURRENT_MAX power supply properties to
>   expose the "fast charge current" (maximum current from charger to
>   battery) and "CHGIN input current limit" (maximum current from
>   external supply to charger).
> 
> - Add functions for toggling charging and OTG modes.
> 
> - Add an extcon-based handler that enables charging or OTG depending
>   on the cable type plugged in. The extcon device to use for cable
>   detection can be specified in the device tree, and is entirely
>   optional.
> 
> The extcon listener implementation is inspired by the rt5033 charger
> driver (commit 8242336dc8a8 ("power: supply: rt5033_charger: Add cable
> detection and USB OTG supply")).

Tested on exynos4412-i9305 (after applying the changes in patch 8 - 10
to exynos4412-midas.dtsi).  It works well, device correctly identifies
a usb cable connected to charger or a usb cable connected to computer,
and sets a limit of 1.8 A and 0.5 A in the two cases.

I did notice that device does not always detect cable insertion, so I
can occassionally get two de-attach events in a row.  Cable was
inserted between 428 and 462 in below log snippet:

[  389.458399] max77693-muic max77693-muic: external connector is attached(chg_type:0x3, prev_chg_type:0x3)
[  389.469765] max77693-charger max77693-charger: fast charging. connector type: 6
[  428.151857] max77693-muic max77693-muic: external connector is detached(chg_type:0x3, prev_chg_type:0x0)
[  428.160319] max77693-charger max77693-charger: not charging. connector type: 13
[  462.156048] max77693-muic max77693-muic: external connector is detached(chg_type:0x0, prev_chg_type:0x0)
[  469.881925] max77693-muic max77693-muic: external connector is attached(chg_type:0x3, prev_chg_type:0x3)
[  469.890049] max77693-charger max77693-charger: fast charging. connector type: 6

but this is probably an issue in extcon driver though rather than
charger.

I have not tested so that MHL still works, as I do not have access to
that cable at the moment, will try it in a few days.

Best regards
Henrik Grimler

> Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
> 
> v3 no longer uses the CHARGER regulator to manage the power status, and
> that's for two reasons:
> 
> - Regulator enable/disable behavior was interfering with how the power
>   supply driver worked (we occasionally got "unbalanced disables"
>   errors when switching charging state, despite checking for the
>   regulator status with regulator_is_enabled() - the CHARGER reg would
>   report as enabled despite the enable count being 0).
>   This broke OTG insertion if the OTG cable was plugged in first, and
>   sometimes caused warnings on unsuspend.
> 
> - Changing the charging values directly in the power supply driver is
>   less opaque and lets us avoid bringing in a dependency on regulators.
> 
> It also splits the current limits back into two properties:
> INPUT_CURRENT_LIMIT and CONSTANT_CHARGE_CURRENT_MAX. Again, there are
> two reasons for this split:
> 
> - They are two separate current controls, one for USB->charger and one
>   for charger->battery, and they have different limits (0-2.1A for CC
>   vs 60mA-2.58A for input). Given that the power supply core has the
>   properties for both values separately, it's more logical to present
>   them as such.
> 
> - It's safer to keep these separate; CONSTANT_CHARGE_CURRENT_MAX is
>   pretty explicitly only set *once* - at probe time with a safe value
>   specified in the DT. This way, INPUT_CURRENT_LIMIT is safer to modify
>   since in the event of an invalid value the CC current will hold back
>   the extra current thus preventing damage to the battery.
> 
> The latter is relevant as I'm working on a follow-up patchset that
> allows for controlling the charging parameters using power supply
> properties/sysfs properties rather than the CHARGER regulator.
> 
> Note that the CHARGER regulator gets disabled automatically if it's
> not used, which will disable charging if it was auto-enabled by the
> extcon code. This can be worked around by re-attaching the cable, or
> more properly by removing the CHARGER regulator from DT for devices
> that use the extcon-based charger management, as has been done in the
> Galaxy Tab 3 8.0 DTSI.
> 
> See v1 for old description:
> 
> https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com
> ---
> Changes in v3:
> - Drop uses of CHARGER regulator, manage registers directly in power
>   supply driver instead
> - Link to v2: https://lore.kernel.org/r/20240715-max77693-charger-extcon-v2-0-0838ffbb18c3@gmail.com
> 
> Changes in v2:
> - Changed to use monitored-battery for charge current value
> - Both current limit variables are now set by the CHARGER regulator
> - Link to v1: https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com
> 
> ---
> Artur Weber (10):
>       dt-bindings: power: supply: max77693: Add monitored-battery property
>       dt-bindings: power: supply: max77693: Add maxim,usb-connector property
>       power: supply: max77693: Expose input current limit and CC current properties
>       power: supply: max77693: Set charge current limits during init
>       power: supply: max77693: Add USB extcon detection for enabling charging
>       power: supply: max77693: Add support for detecting and enabling OTG
>       power: supply: max77693: Set up charge/input current according to cable type
>       ARM: dts: samsung: exynos4212-tab3: Add battery node with charge current value
>       ARM: dts: samsung: exynos4212-tab3: Add USB connector node
>       ARM: dts: exynos4212-tab3: Drop CHARGER regulator
> 
>  .../bindings/power/supply/maxim,max77693.yaml      |  15 +
>  arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi     |  22 +-
>  drivers/power/supply/Kconfig                       |   1 +
>  drivers/power/supply/max77693_charger.c            | 302 ++++++++++++++++++++-
>  include/linux/mfd/max77693-private.h               |  12 +
>  5 files changed, 337 insertions(+), 15 deletions(-)
> ---
> base-commit: 0c3836482481200ead7b416ca80c68a29cfdaabd
> change-id: 20240525-max77693-charger-extcon-9ebb7bad83ce
> 
> Best regards,
> -- 
> Artur Weber <aweber.kernel@gmail.com>
> 
Details
Message ID
<20240804105937.GA20421@l14.localdomain>
In-Reply-To
<20240801062253.GA2681@l14.localdomain> (view parent)
DKIM signature
pass
Download raw message
Hi again Artur,

On Thu, Aug 01, 2024 at 08:23:26AM +0200, Henrik Grimler wrote:
> Hi Artur,
> 
> On Mon, Jul 29, 2024 at 07:47:34PM +0200, Artur Weber wrote:
> > This patchset does the following:
> > 
> > - Add CURRENT_MAX and INPUT_CURRENT_MAX power supply properties to
> >   expose the "fast charge current" (maximum current from charger to
> >   battery) and "CHGIN input current limit" (maximum current from
> >   external supply to charger).
> > 
> > - Add functions for toggling charging and OTG modes.
> > 
> > - Add an extcon-based handler that enables charging or OTG depending
> >   on the cable type plugged in. The extcon device to use for cable
> >   detection can be specified in the device tree, and is entirely
> >   optional.
> > 
> > The extcon listener implementation is inspired by the rt5033 charger
> > driver (commit 8242336dc8a8 ("power: supply: rt5033_charger: Add cable
> > detection and USB OTG supply")).
> 
> Tested on exynos4412-i9305 (after applying the changes in patch 8 - 10
> to exynos4412-midas.dtsi).  It works well, device correctly identifies
> a usb cable connected to charger or a usb cable connected to computer,
> and sets a limit of 1.8 A and 0.5 A in the two cases.
> 
> I did notice that device does not always detect cable insertion, so I
> can occassionally get two de-attach events in a row.  Cable was
> inserted between 428 and 462 in below log snippet:
> 
> [  389.458399] max77693-muic max77693-muic: external connector is attached(chg_type:0x3, prev_chg_type:0x3)
> [  389.469765] max77693-charger max77693-charger: fast charging. connector type: 6
> [  428.151857] max77693-muic max77693-muic: external connector is detached(chg_type:0x3, prev_chg_type:0x0)
> [  428.160319] max77693-charger max77693-charger: not charging. connector type: 13
> [  462.156048] max77693-muic max77693-muic: external connector is detached(chg_type:0x0, prev_chg_type:0x0)
> [  469.881925] max77693-muic max77693-muic: external connector is attached(chg_type:0x3, prev_chg_type:0x3)
> [  469.890049] max77693-charger max77693-charger: fast charging. connector type: 6
> 
> but this is probably an issue in extcon driver though rather than
> charger.
> 
> I have not tested so that MHL still works, as I do not have access to
> that cable at the moment, will try it in a few days.

MHL now tested on exynos4412-i9300 as well.  It works, and the series
fixes so that we can hotplug the cable (with a few patches to make
sii9324 use extcon as well), before we had to connect cable before
boot and rely on bootloader to setup everything.  Thanks!

> > Signed-off-by: Artur Weber <aweber.kernel@gmail.com>

Tested-by: Henrik Grimler <henrik@grimler.se>

Best regards,
Henrik Grimler

> > v3 no longer uses the CHARGER regulator to manage the power status, and
> > that's for two reasons:
> > 
> > - Regulator enable/disable behavior was interfering with how the power
> >   supply driver worked (we occasionally got "unbalanced disables"
> >   errors when switching charging state, despite checking for the
> >   regulator status with regulator_is_enabled() - the CHARGER reg would
> >   report as enabled despite the enable count being 0).
> >   This broke OTG insertion if the OTG cable was plugged in first, and
> >   sometimes caused warnings on unsuspend.
> > 
> > - Changing the charging values directly in the power supply driver is
> >   less opaque and lets us avoid bringing in a dependency on regulators.
> > 
> > It also splits the current limits back into two properties:
> > INPUT_CURRENT_LIMIT and CONSTANT_CHARGE_CURRENT_MAX. Again, there are
> > two reasons for this split:
> > 
> > - They are two separate current controls, one for USB->charger and one
> >   for charger->battery, and they have different limits (0-2.1A for CC
> >   vs 60mA-2.58A for input). Given that the power supply core has the
> >   properties for both values separately, it's more logical to present
> >   them as such.
> > 
> > - It's safer to keep these separate; CONSTANT_CHARGE_CURRENT_MAX is
> >   pretty explicitly only set *once* - at probe time with a safe value
> >   specified in the DT. This way, INPUT_CURRENT_LIMIT is safer to modify
> >   since in the event of an invalid value the CC current will hold back
> >   the extra current thus preventing damage to the battery.
> > 
> > The latter is relevant as I'm working on a follow-up patchset that
> > allows for controlling the charging parameters using power supply
> > properties/sysfs properties rather than the CHARGER regulator.
> > 
> > Note that the CHARGER regulator gets disabled automatically if it's
> > not used, which will disable charging if it was auto-enabled by the
> > extcon code. This can be worked around by re-attaching the cable, or
> > more properly by removing the CHARGER regulator from DT for devices
> > that use the extcon-based charger management, as has been done in the
> > Galaxy Tab 3 8.0 DTSI.
> > 
> > See v1 for old description:
> > 
> > https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com
> > ---
> > Changes in v3:
> > - Drop uses of CHARGER regulator, manage registers directly in power
> >   supply driver instead
> > - Link to v2: https://lore.kernel.org/r/20240715-max77693-charger-extcon-v2-0-0838ffbb18c3@gmail.com
> > 
> > Changes in v2:
> > - Changed to use monitored-battery for charge current value
> > - Both current limit variables are now set by the CHARGER regulator
> > - Link to v1: https://lore.kernel.org/r/20240530-max77693-charger-extcon-v1-0-dc2a9e5bdf30@gmail.com
> > 
> > ---
> > Artur Weber (10):
> >       dt-bindings: power: supply: max77693: Add monitored-battery property
> >       dt-bindings: power: supply: max77693: Add maxim,usb-connector property
> >       power: supply: max77693: Expose input current limit and CC current properties
> >       power: supply: max77693: Set charge current limits during init
> >       power: supply: max77693: Add USB extcon detection for enabling charging
> >       power: supply: max77693: Add support for detecting and enabling OTG
> >       power: supply: max77693: Set up charge/input current according to cable type
> >       ARM: dts: samsung: exynos4212-tab3: Add battery node with charge current value
> >       ARM: dts: samsung: exynos4212-tab3: Add USB connector node
> >       ARM: dts: exynos4212-tab3: Drop CHARGER regulator
> > 
> >  .../bindings/power/supply/maxim,max77693.yaml      |  15 +
> >  arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi     |  22 +-
> >  drivers/power/supply/Kconfig                       |   1 +
> >  drivers/power/supply/max77693_charger.c            | 302 ++++++++++++++++++++-
> >  include/linux/mfd/max77693-private.h               |  12 +
> >  5 files changed, 337 insertions(+), 15 deletions(-)
> > ---
> > base-commit: 0c3836482481200ead7b416ca80c68a29cfdaabd
> > change-id: 20240525-max77693-charger-extcon-9ebb7bad83ce
> > 
> > Best regards,
> > -- 
> > Artur Weber <aweber.kernel@gmail.com>
> > 

Re: [PATCH v3 08/10] ARM: dts: samsung: exynos4212-tab3: Add battery node with charge current value

Krzysztof Kozlowski <krzk@kernel.org>
Details
Message ID
<100dff5a-a07a-487f-b1a4-50c3e94804b0@kernel.org>
In-Reply-To
<20240729-max77693-charger-extcon-v3-8-02315a6869d4@gmail.com> (view parent)
DKIM signature
pass
Download raw message
On 29/07/2024 19:47, Artur Weber wrote:
> This value was verified by comparing register dumps of the MAX77693
> charger with on mainline with a downstream kernel under Android; the
> value on downstream was set to 1.8 amps when charging with a proper
> charger.
> 
> Add it to a new battery node and pass it to the MAX77693 charger
> so that the fast charge current setting can be used for charging.
> 
> Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
> ---
> Changes in v2:
> - Switched to monitored-battery
> ---

Please ping me or resend DTS when the bindings got accepted to power
supply tree.

Best regards,
Krzysztof
Reply to thread Export thread (mbox)