Loading drivers/power/supply/qcom/qpnp-qnovo.c +97 −46 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #define QNOVO_PTRAIN_STS 0x08 #define QNOVO_ERROR_STS 0x09 #define QNOVO_ERROR_BIT BIT(0) #define QNOVO_ERROR_STS2 0x0A #define QNOVO_INT_RT_STS 0x10 #define QNOVO_INT_SET_TYPE 0x11 #define QNOVO_INT_POLARITY_HIGH 0x12 Loading Loading @@ -272,28 +273,22 @@ static int qnovo_disable_cb(struct votable *votable, void *data, int disable, const char *client) { struct qnovo *chip = data; int rc = 0; union power_supply_propval pval = {0}; int rc; if (disable) { rc = qnovo_batt_psy_update(chip, true); if (rc < 0) return rc; } if (!is_batt_available(chip)) return -EINVAL; rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, disable ? 0 : QNOVO_PTRAIN_EN_BIT); pval.intval = !disable; rc = power_supply_set_property(chip->batt_psy, POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE, &pval); if (rc < 0) { dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n", disable ? "disable" : "enable", rc); return rc; } if (!disable) { rc = qnovo_batt_psy_update(chip, false); if (rc < 0) return rc; pr_err("Couldn't set prop qnovo_enable rc = %d\n", rc); return -EINVAL; } rc = qnovo_batt_psy_update(chip, disable); return rc; } Loading Loading @@ -348,13 +343,15 @@ static int qnovo_check_chg_version(struct qnovo *chip) enum { VER = 0, OK_TO_QNOVO, ENABLE, QNOVO_ENABLE, PT_ENABLE, FV_REQUEST, FCC_REQUEST, PE_CTRL_REG, PE_CTRL2_REG, PTRAIN_STS_REG, INT_RT_STS_REG, ERR_STS2_REG, PREST1, PPULS1, NREST1, Loading Loading @@ -394,6 +391,12 @@ struct param_info { }; static struct param_info params[] = { [PT_ENABLE] = { .name = "PT_ENABLE", .start_addr = QNOVO_PTRAIN_EN, .num_regs = 1, .units_str = "", }, [FV_REQUEST] = { .units_str = "uV", }, Loading Loading @@ -424,6 +427,12 @@ static struct param_info params[] = { .num_regs = 1, .units_str = "", }, [ERR_STS2_REG] = { .name = "RAW_CHGR_ERR", .start_addr = QNOVO_ERROR_STS2, .num_regs = 1, .units_str = "", }, [PREST1] = { .name = "PREST1", .start_addr = QNOVO_PREST1_CTRL, Loading Loading @@ -648,30 +657,70 @@ static ssize_t ok_to_qnovo_show(struct class *c, struct class_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n", chip->cs.ok_to_qnovo); } static ssize_t enable_show(struct class *c, struct class_attribute *attr, static ssize_t qnovo_enable_show(struct class *c, struct class_attribute *attr, char *ubuf) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); int val; int val = get_effective_result(chip->disable_votable); val = get_client_vote(chip->disable_votable, USER_VOTER); val = !val; return snprintf(ubuf, PAGE_SIZE, "%d\n", val); return snprintf(ubuf, PAGE_SIZE, "%d\n", !val); } static ssize_t qnovo_enable_store(struct class *c, struct class_attribute *attr, const char *ubuf, size_t count) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); unsigned long val; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; vote(chip->disable_votable, USER_VOTER, !val, 0); return count; } static ssize_t enable_store(struct class *c, struct class_attribute *attr, static ssize_t pt_enable_show(struct class *c, struct class_attribute *attr, char *ubuf) { int i = attr - qnovo_attributes; struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); u8 buf[2] = {0, 0}; u16 regval; int rc; rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs); if (rc < 0) { pr_err("Couldn't read %s rc = %d\n", params[i].name, rc); return -EINVAL; } regval = buf[1] << 8 | buf[0]; return snprintf(ubuf, PAGE_SIZE, "%d\n", (int)(regval & QNOVO_PTRAIN_EN_BIT)); } static ssize_t pt_enable_store(struct class *c, struct class_attribute *attr, const char *ubuf, size_t count) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); unsigned long val; bool disable; int rc = 0; if (get_effective_result(chip->disable_votable)) return -EINVAL; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; disable = !val; rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, (bool)val ? QNOVO_PTRAIN_EN_BIT : 0); if (rc < 0) { dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n", (bool)val ? "enable" : "disable", rc); return rc; } vote(chip->disable_votable, USER_VOTER, disable, 0); return count; } Loading @@ -698,6 +747,9 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr, int i = attr - qnovo_attributes; unsigned long val; if (get_effective_result(chip->disable_votable)) return -EINVAL; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; Loading @@ -707,6 +759,8 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr, if (i == FCC_REQUEST) chip->fcc_uA_request = val; qnovo_batt_psy_update(chip, false); return count; } Loading Loading @@ -1016,8 +1070,8 @@ static ssize_t batt_prop_show(struct class *c, struct class_attribute *attr, static struct class_attribute qnovo_attributes[] = { [VER] = __ATTR_RO(version), [OK_TO_QNOVO] = __ATTR_RO(ok_to_qnovo), [ENABLE] = __ATTR(enable, 0644, enable_show, enable_store), [QNOVO_ENABLE] = __ATTR_RW(qnovo_enable), [PT_ENABLE] = __ATTR_RW(pt_enable), [FV_REQUEST] = __ATTR(fv_uV_request, 0644, val_show, val_store), [FCC_REQUEST] = __ATTR(fcc_uA_request, 0644, Loading @@ -1030,6 +1084,8 @@ static struct class_attribute qnovo_attributes[] = { reg_show, NULL), [INT_RT_STS_REG] = __ATTR(INT_RT_STS_REG, 0444, reg_show, NULL), [ERR_STS2_REG] = __ATTR(ERR_STS2_REG, 0444, reg_show, NULL), [PREST1] = __ATTR(PREST1_mS, 0644, time_show, time_store), [PPULS1] = __ATTR(PPULS1_uC, 0644, Loading @@ -1050,7 +1106,7 @@ static struct class_attribute qnovo_attributes[] = { time_show, NULL), [PREST2] = __ATTR(PREST2_mS, 0644, time_show, time_store), [PPULS2] = __ATTR(PPULS2_mS, 0644, [PPULS2] = __ATTR(PPULS2_uC, 0644, coulomb_show, coulomb_store), [NREST2] = __ATTR(NREST2_mS, 0644, time_show, time_store), Loading Loading @@ -1135,8 +1191,7 @@ static void get_chg_status(struct qnovo *chip, const struct chg_props *cp, { cs->ok_to_qnovo = false; if (cp->charging && (cp->usb_online || cp->dc_online)) if (cp->charging && (cp->usb_online || cp->dc_online)) cs->ok_to_qnovo = true; } Loading @@ -1152,17 +1207,10 @@ static void status_change_work(struct work_struct *work) get_chg_status(chip, &cp, &cs); if (cs.ok_to_qnovo ^ chip->cs.ok_to_qnovo) { /* * when it is not okay to Qnovo charge, disable both voters, * so that when it becomes okay to Qnovo charge the user voter * has to specifically enable its vote to being Qnovo charging */ if (!cs.ok_to_qnovo) { vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 1, 0); vote(chip->disable_votable, USER_VOTER, 1, 0); } else { vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 0, 0); } vote(chip->disable_votable, OK_TO_QNOVO_VOTER, !cs.ok_to_qnovo, 0); if (!cs.ok_to_qnovo) vote(chip->disable_votable, USER_VOTER, true, 0); notify_uevent = true; } Loading Loading @@ -1192,8 +1240,6 @@ static irqreturn_t handle_ptrain_done(int irq, void *data) { struct qnovo *chip = data; /* disable user voter here */ vote(chip->disable_votable, USER_VOTER, 0, 0); kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE); return IRQ_HANDLED; } Loading @@ -1206,7 +1252,7 @@ static int qnovo_hw_init(struct qnovo *chip) u8 vadc_offset, vadc_gain; u8 val; vote(chip->disable_votable, USER_VOTER, 1, 0); vote(chip->disable_votable, USER_VOTER, true, 0); val = 0; rc = qnovo_write(chip, QNOVO_STRM_CTRL, &val, 1); Loading Loading @@ -1318,6 +1364,9 @@ static int qnovo_request_interrupts(struct qnovo *chip) irq_ptrain_done, rc); return rc; } enable_irq_wake(irq_ptrain_done); return rc; } Loading Loading @@ -1399,6 +1448,8 @@ static int qnovo_probe(struct platform_device *pdev) goto unreg_notifier; } device_init_wakeup(chip->dev, true); return rc; unreg_notifier: Loading drivers/power/supply/qcom/qpnp-smb2.c +2 −0 Original line number Diff line number Diff line Loading @@ -999,6 +999,8 @@ static int smb2_batt_set_prop(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_QNOVO: chg->qnovo_fcc_ua = val->intval; vote(chg->pl_disable_votable, PL_QNOVO_VOTER, val->intval != -EINVAL && val->intval < 2000000, 0); rc = rerun_election(chg->fcc_votable); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: Loading drivers/power/supply/qcom/smb-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ enum print_reason { #define USB_PSY_VOTER "USB_PSY_VOTER" #define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER" #define PL_INDIRECT_VOTER "PL_INDIRECT_VOTER" #define PL_QNOVO_VOTER "PL_QNOVO_VOTER" #define USBIN_I_VOTER "USBIN_I_VOTER" #define USBIN_V_VOTER "USBIN_V_VOTER" #define CHG_STATE_VOTER "CHG_STATE_VOTER" Loading Loading
drivers/power/supply/qcom/qpnp-qnovo.c +97 −46 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #define QNOVO_PTRAIN_STS 0x08 #define QNOVO_ERROR_STS 0x09 #define QNOVO_ERROR_BIT BIT(0) #define QNOVO_ERROR_STS2 0x0A #define QNOVO_INT_RT_STS 0x10 #define QNOVO_INT_SET_TYPE 0x11 #define QNOVO_INT_POLARITY_HIGH 0x12 Loading Loading @@ -272,28 +273,22 @@ static int qnovo_disable_cb(struct votable *votable, void *data, int disable, const char *client) { struct qnovo *chip = data; int rc = 0; union power_supply_propval pval = {0}; int rc; if (disable) { rc = qnovo_batt_psy_update(chip, true); if (rc < 0) return rc; } if (!is_batt_available(chip)) return -EINVAL; rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, disable ? 0 : QNOVO_PTRAIN_EN_BIT); pval.intval = !disable; rc = power_supply_set_property(chip->batt_psy, POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE, &pval); if (rc < 0) { dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n", disable ? "disable" : "enable", rc); return rc; } if (!disable) { rc = qnovo_batt_psy_update(chip, false); if (rc < 0) return rc; pr_err("Couldn't set prop qnovo_enable rc = %d\n", rc); return -EINVAL; } rc = qnovo_batt_psy_update(chip, disable); return rc; } Loading Loading @@ -348,13 +343,15 @@ static int qnovo_check_chg_version(struct qnovo *chip) enum { VER = 0, OK_TO_QNOVO, ENABLE, QNOVO_ENABLE, PT_ENABLE, FV_REQUEST, FCC_REQUEST, PE_CTRL_REG, PE_CTRL2_REG, PTRAIN_STS_REG, INT_RT_STS_REG, ERR_STS2_REG, PREST1, PPULS1, NREST1, Loading Loading @@ -394,6 +391,12 @@ struct param_info { }; static struct param_info params[] = { [PT_ENABLE] = { .name = "PT_ENABLE", .start_addr = QNOVO_PTRAIN_EN, .num_regs = 1, .units_str = "", }, [FV_REQUEST] = { .units_str = "uV", }, Loading Loading @@ -424,6 +427,12 @@ static struct param_info params[] = { .num_regs = 1, .units_str = "", }, [ERR_STS2_REG] = { .name = "RAW_CHGR_ERR", .start_addr = QNOVO_ERROR_STS2, .num_regs = 1, .units_str = "", }, [PREST1] = { .name = "PREST1", .start_addr = QNOVO_PREST1_CTRL, Loading Loading @@ -648,30 +657,70 @@ static ssize_t ok_to_qnovo_show(struct class *c, struct class_attribute *attr, return snprintf(buf, PAGE_SIZE, "%d\n", chip->cs.ok_to_qnovo); } static ssize_t enable_show(struct class *c, struct class_attribute *attr, static ssize_t qnovo_enable_show(struct class *c, struct class_attribute *attr, char *ubuf) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); int val; int val = get_effective_result(chip->disable_votable); val = get_client_vote(chip->disable_votable, USER_VOTER); val = !val; return snprintf(ubuf, PAGE_SIZE, "%d\n", val); return snprintf(ubuf, PAGE_SIZE, "%d\n", !val); } static ssize_t qnovo_enable_store(struct class *c, struct class_attribute *attr, const char *ubuf, size_t count) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); unsigned long val; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; vote(chip->disable_votable, USER_VOTER, !val, 0); return count; } static ssize_t enable_store(struct class *c, struct class_attribute *attr, static ssize_t pt_enable_show(struct class *c, struct class_attribute *attr, char *ubuf) { int i = attr - qnovo_attributes; struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); u8 buf[2] = {0, 0}; u16 regval; int rc; rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs); if (rc < 0) { pr_err("Couldn't read %s rc = %d\n", params[i].name, rc); return -EINVAL; } regval = buf[1] << 8 | buf[0]; return snprintf(ubuf, PAGE_SIZE, "%d\n", (int)(regval & QNOVO_PTRAIN_EN_BIT)); } static ssize_t pt_enable_store(struct class *c, struct class_attribute *attr, const char *ubuf, size_t count) { struct qnovo *chip = container_of(c, struct qnovo, qnovo_class); unsigned long val; bool disable; int rc = 0; if (get_effective_result(chip->disable_votable)) return -EINVAL; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; disable = !val; rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, (bool)val ? QNOVO_PTRAIN_EN_BIT : 0); if (rc < 0) { dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n", (bool)val ? "enable" : "disable", rc); return rc; } vote(chip->disable_votable, USER_VOTER, disable, 0); return count; } Loading @@ -698,6 +747,9 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr, int i = attr - qnovo_attributes; unsigned long val; if (get_effective_result(chip->disable_votable)) return -EINVAL; if (kstrtoul(ubuf, 0, &val)) return -EINVAL; Loading @@ -707,6 +759,8 @@ static ssize_t val_store(struct class *c, struct class_attribute *attr, if (i == FCC_REQUEST) chip->fcc_uA_request = val; qnovo_batt_psy_update(chip, false); return count; } Loading Loading @@ -1016,8 +1070,8 @@ static ssize_t batt_prop_show(struct class *c, struct class_attribute *attr, static struct class_attribute qnovo_attributes[] = { [VER] = __ATTR_RO(version), [OK_TO_QNOVO] = __ATTR_RO(ok_to_qnovo), [ENABLE] = __ATTR(enable, 0644, enable_show, enable_store), [QNOVO_ENABLE] = __ATTR_RW(qnovo_enable), [PT_ENABLE] = __ATTR_RW(pt_enable), [FV_REQUEST] = __ATTR(fv_uV_request, 0644, val_show, val_store), [FCC_REQUEST] = __ATTR(fcc_uA_request, 0644, Loading @@ -1030,6 +1084,8 @@ static struct class_attribute qnovo_attributes[] = { reg_show, NULL), [INT_RT_STS_REG] = __ATTR(INT_RT_STS_REG, 0444, reg_show, NULL), [ERR_STS2_REG] = __ATTR(ERR_STS2_REG, 0444, reg_show, NULL), [PREST1] = __ATTR(PREST1_mS, 0644, time_show, time_store), [PPULS1] = __ATTR(PPULS1_uC, 0644, Loading @@ -1050,7 +1106,7 @@ static struct class_attribute qnovo_attributes[] = { time_show, NULL), [PREST2] = __ATTR(PREST2_mS, 0644, time_show, time_store), [PPULS2] = __ATTR(PPULS2_mS, 0644, [PPULS2] = __ATTR(PPULS2_uC, 0644, coulomb_show, coulomb_store), [NREST2] = __ATTR(NREST2_mS, 0644, time_show, time_store), Loading Loading @@ -1135,8 +1191,7 @@ static void get_chg_status(struct qnovo *chip, const struct chg_props *cp, { cs->ok_to_qnovo = false; if (cp->charging && (cp->usb_online || cp->dc_online)) if (cp->charging && (cp->usb_online || cp->dc_online)) cs->ok_to_qnovo = true; } Loading @@ -1152,17 +1207,10 @@ static void status_change_work(struct work_struct *work) get_chg_status(chip, &cp, &cs); if (cs.ok_to_qnovo ^ chip->cs.ok_to_qnovo) { /* * when it is not okay to Qnovo charge, disable both voters, * so that when it becomes okay to Qnovo charge the user voter * has to specifically enable its vote to being Qnovo charging */ if (!cs.ok_to_qnovo) { vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 1, 0); vote(chip->disable_votable, USER_VOTER, 1, 0); } else { vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 0, 0); } vote(chip->disable_votable, OK_TO_QNOVO_VOTER, !cs.ok_to_qnovo, 0); if (!cs.ok_to_qnovo) vote(chip->disable_votable, USER_VOTER, true, 0); notify_uevent = true; } Loading Loading @@ -1192,8 +1240,6 @@ static irqreturn_t handle_ptrain_done(int irq, void *data) { struct qnovo *chip = data; /* disable user voter here */ vote(chip->disable_votable, USER_VOTER, 0, 0); kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE); return IRQ_HANDLED; } Loading @@ -1206,7 +1252,7 @@ static int qnovo_hw_init(struct qnovo *chip) u8 vadc_offset, vadc_gain; u8 val; vote(chip->disable_votable, USER_VOTER, 1, 0); vote(chip->disable_votable, USER_VOTER, true, 0); val = 0; rc = qnovo_write(chip, QNOVO_STRM_CTRL, &val, 1); Loading Loading @@ -1318,6 +1364,9 @@ static int qnovo_request_interrupts(struct qnovo *chip) irq_ptrain_done, rc); return rc; } enable_irq_wake(irq_ptrain_done); return rc; } Loading Loading @@ -1399,6 +1448,8 @@ static int qnovo_probe(struct platform_device *pdev) goto unreg_notifier; } device_init_wakeup(chip->dev, true); return rc; unreg_notifier: Loading
drivers/power/supply/qcom/qpnp-smb2.c +2 −0 Original line number Diff line number Diff line Loading @@ -999,6 +999,8 @@ static int smb2_batt_set_prop(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_QNOVO: chg->qnovo_fcc_ua = val->intval; vote(chg->pl_disable_votable, PL_QNOVO_VOTER, val->intval != -EINVAL && val->intval < 2000000, 0); rc = rerun_election(chg->fcc_votable); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: Loading
drivers/power/supply/qcom/smb-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ enum print_reason { #define USB_PSY_VOTER "USB_PSY_VOTER" #define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER" #define PL_INDIRECT_VOTER "PL_INDIRECT_VOTER" #define PL_QNOVO_VOTER "PL_QNOVO_VOTER" #define USBIN_I_VOTER "USBIN_I_VOTER" #define USBIN_V_VOTER "USBIN_V_VOTER" #define CHG_STATE_VOTER "CHG_STATE_VOTER" Loading