Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dzmitry Sankouski and committed by
Sebastian Reichel
8ed6b884 b838cecc

+44
+42
drivers/power/supply/max77705_charger.c
··· 40 40 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 41 41 }; 42 42 43 + static irqreturn_t max77705_aicl_irq(int irq, void *irq_drv_data) 44 + { 45 + struct max77705_charger_data *chg = irq_drv_data; 46 + unsigned int regval, irq_status; 47 + int err; 48 + 49 + err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status); 50 + if (err < 0) 51 + return IRQ_HANDLED; 52 + 53 + // irq is fiered at the end of current decrease sequence too 54 + // early check AICL_I bit to guard against that excess irq call 55 + while (!(irq_status & BIT(MAX77705_AICL_I))) { 56 + err = regmap_field_read(chg->rfield[MAX77705_CHG_CHGIN_LIM], &regval); 57 + if (err < 0) 58 + return IRQ_HANDLED; 59 + 60 + regval--; 61 + 62 + err = regmap_field_write(chg->rfield[MAX77705_CHG_CHGIN_LIM], regval); 63 + if (err < 0) 64 + return IRQ_HANDLED; 65 + 66 + msleep(AICL_WORK_DELAY_MS); 67 + 68 + err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status); 69 + if (err < 0) 70 + return IRQ_HANDLED; 71 + } 72 + 73 + return IRQ_HANDLED; 74 + } 75 + 43 76 static irqreturn_t max77705_chgin_irq(int irq, void *irq_drv_data) 44 77 { 45 78 struct max77705_charger_data *chg = irq_drv_data; ··· 662 629 "chgin-irq", chg); 663 630 if (ret) { 664 631 dev_err_probe(dev, ret, "Failed to Request chgin IRQ\n"); 632 + goto destroy_wq; 633 + } 634 + 635 + ret = devm_request_threaded_irq(dev, regmap_irq_get_virq(irq_data, MAX77705_AICL_I), 636 + NULL, max77705_aicl_irq, 637 + IRQF_TRIGGER_NONE, 638 + "aicl-irq", chg); 639 + if (ret) { 640 + dev_err_probe(dev, ret, "Failed to Request aicl IRQ\n"); 665 641 goto destroy_wq; 666 642 } 667 643
+2
include/linux/power/max77705_charger.h
··· 123 123 #define MAX77705_DISABLE_SKIP 1 124 124 #define MAX77705_AUTO_SKIP 0 125 125 126 + #define AICL_WORK_DELAY_MS 100 127 + 126 128 /* uA */ 127 129 #define MAX77705_CURRENT_CHGIN_STEP 25000 128 130 #define MAX77705_CURRENT_CHG_STEP 50000