diff mbox series

[RFC,06/11] power: supply: max77693: Set charge current limits during init

Message ID 20240530-max77693-charger-extcon-v1-6-dc2a9e5bdf30@gmail.com
State New
Headers show
Series power: supply: max77693: Toggle charging/OTG based on extcon status | expand

Commit Message

Artur Weber May 30, 2024, 8:55 a.m. UTC
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, and is managed by the CHARGER regulator).

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

The default value for the fast charge current limit can be modified
by setting the maxim,fast-charge-current-microamp DT property; the
CHGIN input current limit will be set up later in the charger detection
mechanism.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
 drivers/power/supply/max77693_charger.c | 45 +++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

Comments

Artur Weber June 5, 2024, 2:43 p.m. UTC | #1
On 31.05.2024 14:18, Krzysztof Kozlowski wrote:
> On 31/05/2024 13:55, Artur Weber wrote:
>> On 31.05.2024 11:47, Krzysztof Kozlowski wrote:
>>> On 30/05/2024 10:55, Artur Weber wrote:
>>>> 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, and is managed by the CHARGER regulator).
>>>>
>>>> Add functions for setting both of the values, and set them to a
>>>> safe default value of 500mA at initialization.
>>>>
>>>> The default value for the fast charge current limit can be modified
>>>> by setting the maxim,fast-charge-current-microamp DT property; the
>>>> CHGIN input current limit will be set up later in the charger detection
>>>> mechanism.
>>>>
>>>> Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
>>>> ---
>>>>    drivers/power/supply/max77693_charger.c | 45 +++++++++++++++++++++++++++++++++
>>>>    1 file changed, 45 insertions(+)
>>>>
>>>> diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
>>>> index 894c35b750b3..d59b1524b0a4 100644
>>>> --- a/drivers/power/supply/max77693_charger.c
>>>> +++ b/drivers/power/supply/max77693_charger.c
>>>> @@ -28,6 +28,7 @@ struct max77693_charger {
>>>>    	u32 min_system_volt;
>>>>    	u32 thermal_regulation_temp;
>>>>    	u32 batttery_overcurrent;
>>>> +	u32 fast_charge_current;
>>>>    	u32 charge_input_threshold_volt;
>>>>    };
>>>>    
>>>> @@ -591,6 +592,35 @@ 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)
>>>> +{
>>>> +	dev_dbg(chg->dev, "CHGIN input current limit: %u\n", uamp);
>>>
>>> That's quite useless debug. It duplicates
>>> max77693_set_fast_charge_current(). Just drop entire wrapper.
>>
>> It doesn't duplicate max77693_set_fast_charge_current, they modify two
>> separate registers. Quote from the commit message:
> 
> But it is the same uamp value. Debug messages should not be per register
> write, because we are not debugging here registers...
> 
>>
>>> 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, and is managed by the CHARGER regulator).
>>
>> max77693_set_fast_charge_current sets up the "fast charge current"
>> register (in CNFG_02, CHG_CNFG_02_CC). The CHARGER regulators sets the
>> CHGIN input current (in CNFG_09, CHG_CNFG_09_CHGIN_ILIM).
>>
>> (Apparently the CHARGER regulator is supposed to handle the fast
>> charge current, but it does not; I wrote about this in the "CHARGER
>> regulator" section of the patchset description.)
>>
>>>> +
>>>> +	return regulator_set_current_limit(chg->regu, (int)uamp, (int)uamp);
>>>> +}
>>>> +
>>>> +static int max77693_set_fast_charge_current(struct max77693_charger *chg,
>>>> +		unsigned int uamp)
>>>> +{
>>>> +	unsigned int data;
>>>> +
>>>> +	data = (uamp / 1000) * 10 / 333; /* 0.1A/3 steps */
>>>> +
>>>> +	if (data > CHG_CNFG_02_CC_MASK) {
>>>> +		dev_err(chg->dev, "Wrong value for fast charge current\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	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);
>>>
>>> I am surprised that you set current limit via regulator but actual
>>> charging current value here. I think both should go to regulator in such
>>> case.
>>
>> As in, both fast charge current and input current should be set up by
>> the CHARGER regulator? Sure, sounds good to me.

Now that I look at it, there's one small problem with moving this to the 
CHARGER regulator - the CHGIN input limit and the fast charge current 
limit have different ranges for values; CHGIN input limit accepts values 
from 60mA to 2.58A, whereas fast charge current accepts values from 0mA 
to ~2.1A. (This also means the limits I described for the fast charge 
current property in [PATCH 2/11] are wrong...)

Should we limit the CHARGER regulator to 2.1A (would require fixing 
every DTS that defines the limits... though maybe they should be 
hardcoded in the driver anyways?), or leave the limit as-is and cap the 
fast charge current if the CHARGER current limit is set above 2.1A, or 
something else entirely?

Best regards
Artur
diff mbox series

Patch

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 894c35b750b3..d59b1524b0a4 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -28,6 +28,7 @@  struct max77693_charger {
 	u32 min_system_volt;
 	u32 thermal_regulation_temp;
 	u32 batttery_overcurrent;
+	u32 fast_charge_current;
 	u32 charge_input_threshold_volt;
 };
 
@@ -591,6 +592,35 @@  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)
+{
+	dev_dbg(chg->dev, "CHGIN input current limit: %u\n", uamp);
+
+	return regulator_set_current_limit(chg->regu, (int)uamp, (int)uamp);
+}
+
+static int max77693_set_fast_charge_current(struct max77693_charger *chg,
+		unsigned int uamp)
+{
+	unsigned int data;
+
+	data = (uamp / 1000) * 10 / 333; /* 0.1A/3 steps */
+
+	if (data > CHG_CNFG_02_CC_MASK) {
+		dev_err(chg->dev, "Wrong value for fast charge current\n");
+		return -EINVAL;
+	}
+
+	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)
 {
@@ -668,6 +698,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);
 }
@@ -703,11 +742,17 @@  static int max77693_dt_init(struct device *dev, struct max77693_charger *chg)
 		chg->charge_input_threshold_volt =
 			DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT;
 
+	if (of_property_read_u32(np, "maxim,fast-charge-current-microamp",
+			&chg->fast_charge_current))
+		chg->fast_charge_current = DEFAULT_FAST_CHARGE_CURRENT;
+
 	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 */