--- src-b10b3/drivers/power/supply/Kconfig 2026-09-21 19:09:00.000000000 +0600 +++ src-b10b4/drivers/power/supply/Kconfig 2026-10-04 18:42:45.872000000 +0600 @@ -768,6 +768,15 @@ To compile this driver as module, choose M here: the module will be called pm8916_lbc. +config CHARGER_PM8916_LBC_B10B4_DEBUG + bool "Aurora B10B-4 TEST-ONLY charger actuator debugfs hook" + depends on CHARGER_PM8916_LBC && DEBUG_FS + default n + help + TEST-ONLY (Aurora B10B-4, RAM images only). Adds the write-only debugfs file + pm8916_lbc/b10b4 accepting exactly "susp 0|1" (USB_SUSP bit0), "vdd <0..8>" + (VDD_MAX) and "ibat <0..4>" (IBAT_MAX). Never enable in a production image. + config CHARGER_BQ2415X tristate "TI BQ2415x battery charger driver" depends on I2C --- src-b10b3/drivers/power/supply/pm8916_lbc.c 2026-10-03 21:11:03.584000000 +0600 +++ src-b10b4/drivers/power/supply/pm8916_lbc.c 2026-10-04 18:17:19.300000000 +0600 @@ -20,6 +20,11 @@ #include #include #include +#ifdef CONFIG_CHARGER_PM8916_LBC_B10B4_DEBUG +#include +#include +#include +#endif /* Two bytes: type + subtype */ #define PM8916_PERPH_TYPE 0x04 @@ -544,6 +549,78 @@ } DEFINE_SHOW_ATTRIBUTE(lbc_state); +#ifdef CONFIG_CHARGER_PM8916_LBC_B10B4_DEBUG +/* + * Aurora B10B-4 TEST-ONLY actuator hook (Kconfig CHARGER_PM8916_LBC_B10B4_DEBUG, default n, RAM test images only). + * Write-only debugfs file pm8916_lbc/b10b4, exactly one of: + * "susp 0|1" USB_SUSP (USB block + 0x47) bit0 only, masked update + * "vdd " VDD_MAX (CHGR block + 0x40), code 0x00..0x08 (4.000..4.200 V) + * "ibat " IBAT_MAX (CHGR block + 0x44), code 0x00..0x04 (90..450 mA) + * Anything else (unknown command, extra/missing argument, out-of-range value) -> -EINVAL without any write. + * Taken under supv_lock (the supervisor/charger lock); old/new/readback logged with dev_warn. Supervisor logic unchanged. + */ +#define PM8916_LBC_USB_SUSP 0x47 +#define PM8916_LBC_USB_SUSP_BIT BIT(0) + +static ssize_t lbc_b10b4_write(struct file *file, const char __user *ubuf, size_t len, loff_t *ppos) +{ + struct pm8916_lbc_charger *chg = file->private_data; + char buf[32], *p, *cmd, *arg; + unsigned int val, addr, mask, old, rb; + int ret; + + if (len == 0 || len >= sizeof(buf)) + return -EINVAL; + if (copy_from_user(buf, ubuf, len)) + return -EFAULT; + buf[len] = 0; + p = strim(buf); + cmd = strsep(&p, " "); + arg = strsep(&p, " "); + if (!cmd || !arg || p || kstrtouint(arg, 0, &val)) + return -EINVAL; + + if (!strcmp(cmd, "susp") && val <= 1) { + addr = chg->reg[LBC_USB] + PM8916_LBC_USB_SUSP; + mask = PM8916_LBC_USB_SUSP_BIT; + } else if (!strcmp(cmd, "vdd") && val <= 0x08) { + addr = chg->reg[LBC_CHGR] + PM8916_LBC_CHGR_VDD_MAX; + mask = 0xff; + } else if (!strcmp(cmd, "ibat") && val <= 0x04) { + addr = chg->reg[LBC_CHGR] + PM8916_LBC_CHGR_IBAT_MAX; + mask = 0xff; + } else { + return -EINVAL; + } + + mutex_lock(&chg->supv_lock); + ret = regmap_read(chg->regmap, addr, &old); + if (!ret) { + if (mask == 0xff) + ret = regmap_write(chg->regmap, addr, val); + else + ret = regmap_update_bits(chg->regmap, addr, mask, val ? mask : 0); + } + if (!ret) + ret = regmap_read(chg->regmap, addr, &rb); + mutex_unlock(&chg->supv_lock); + + if (ret) { + dev_warn(chg->dev, "B10B-4 TEST hook: %s %u at 0x%04x failed: %d\n", cmd, val, addr, ret); + return ret; + } + dev_warn(chg->dev, "B10B-4 TEST hook: %s %u -> reg 0x%04x old 0x%02x readback 0x%02x\n", cmd, val, addr, old, rb); + return len; +} + +static const struct file_operations lbc_b10b4_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = lbc_b10b4_write, + .llseek = noop_llseek, +}; +#endif + static void lbc_debugfs_remove(void *data) { debugfs_remove_recursive(data); @@ -771,6 +848,10 @@ chg->debugfs = debugfs_create_dir("pm8916_lbc", NULL); debugfs_create_file("state", 0444, chg->debugfs, chg, &lbc_state_fops); +#ifdef CONFIG_CHARGER_PM8916_LBC_B10B4_DEBUG + debugfs_create_file("b10b4", 0200, chg->debugfs, chg, &lbc_b10b4_fops); + dev_warn(dev, "B10B-4 TEST-ONLY actuator hook enabled (debugfs pm8916_lbc/b10b4) - never in production\n"); +#endif ret = devm_add_action_or_reset(dev, lbc_debugfs_remove, chg->debugfs); if (ret) return ret;