summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorDzmitry Sankouski <dsankouski@gmail.com>2025-09-25 22:09:56 +0300
committerSebastian Reichel <sebastian.reichel@collabora.com>2025-11-03 00:02:30 +0100
commit8ed6b8842c44a4a716dfd536e7f13aff77039a02 (patch)
tree9f3f2bffe4a1dce7fac9f26018a664095bcac713 /drivers/power
parentb838cecc229122559b3e2e381a9275f714bd4146 (diff)
power: supply: max77705_charger: implement aicl feature
Adaptive input current allows charger to reduce it's current consumption, when source is not able to provide enough power. Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Link: https://patch.msgid.link/20250925-max77705_77976_charger_improvement-v6-1-972c716c17d1@gmail.com Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/supply/max77705_charger.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/power/supply/max77705_charger.c b/drivers/power/supply/max77705_charger.c
index b1a227bf72e2..35cdb10a0e89 100644
--- a/drivers/power/supply/max77705_charger.c
+++ b/drivers/power/supply/max77705_charger.c
@@ -40,6 +40,39 @@ static enum power_supply_property max77705_charger_props[] = {
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
};
+static irqreturn_t max77705_aicl_irq(int irq, void *irq_drv_data)
+{
+ struct max77705_charger_data *chg = irq_drv_data;
+ unsigned int regval, irq_status;
+ int err;
+
+ err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status);
+ if (err < 0)
+ return IRQ_HANDLED;
+
+ // irq is fiered at the end of current decrease sequence too
+ // early check AICL_I bit to guard against that excess irq call
+ while (!(irq_status & BIT(MAX77705_AICL_I))) {
+ err = regmap_field_read(chg->rfield[MAX77705_CHG_CHGIN_LIM], &regval);
+ if (err < 0)
+ return IRQ_HANDLED;
+
+ regval--;
+
+ err = regmap_field_write(chg->rfield[MAX77705_CHG_CHGIN_LIM], regval);
+ if (err < 0)
+ return IRQ_HANDLED;
+
+ msleep(AICL_WORK_DELAY_MS);
+
+ err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status);
+ if (err < 0)
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t max77705_chgin_irq(int irq, void *irq_drv_data)
{
struct max77705_charger_data *chg = irq_drv_data;
@@ -632,6 +665,15 @@ static int max77705_charger_probe(struct i2c_client *i2c)
goto destroy_wq;
}
+ ret = devm_request_threaded_irq(dev, regmap_irq_get_virq(irq_data, MAX77705_AICL_I),
+ NULL, max77705_aicl_irq,
+ IRQF_TRIGGER_NONE,
+ "aicl-irq", chg);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to Request aicl IRQ\n");
+ goto destroy_wq;
+ }
+
ret = max77705_charger_enable(chg);
if (ret) {
dev_err_probe(dev, ret, "failed to enable charge\n");