Loading drivers/power/supply/qcom/qpnp-smb5.c +81 −1 Original line number Diff line number Diff line Loading @@ -730,6 +730,46 @@ static int smb5_parse_dt_voltages(struct smb5 *chip, struct device_node *node) return 0; } static int smb5_parse_sdam(struct smb5 *chip, struct device_node *node) { struct device_node *child; struct smb_charger *chg = &chip->chg; struct property *prop; const char *name; int rc; u32 base; u8 type; for_each_available_child_of_node(node, child) { of_property_for_each_string(child, "reg", prop, name) { rc = of_property_read_u32(child, "reg", &base); if (rc < 0) { pr_err("Failed to read base rc=%d\n", rc); return rc; } rc = smblib_read(chg, base + PERPH_TYPE_OFFSET, &type); if (rc < 0) { pr_err("Failed to read type rc=%d\n", rc); return rc; } switch (type) { case SDAM_TYPE: chg->sdam_base = base; break; default: break; } } } if (!chg->sdam_base) pr_debug("SDAM node not defined\n"); return 0; } static int smb5_parse_dt(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; Loading Loading @@ -757,6 +797,10 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) return rc; rc = smb5_parse_sdam(chip, node); if (rc < 0) return rc; return 0; } Loading Loading @@ -828,6 +872,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_SKIN_HEALTH, POWER_SUPPLY_PROP_APSD_RERUN, POWER_SUPPLY_PROP_APSD_TIMEOUT, POWER_SUPPLY_PROP_CHARGER_STATUS, POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading @@ -837,6 +883,7 @@ static int smb5_usb_get_prop(struct power_supply *psy, struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; u8 reg = 0, buff[2] = {0}; val->intval = 0; switch (psp) { Loading Loading @@ -977,6 +1024,24 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_APSD_TIMEOUT: val->intval = chg->apsd_ext_timeout; break; case POWER_SUPPLY_PROP_CHARGER_STATUS: val->intval = 0; if (chg->sdam_base) { rc = smblib_read(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, ®); if (!rc) val->intval = reg; } break; case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: val->intval = 0; if (chg->sdam_base) { rc = smblib_batch_read(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2); if (!rc) val->intval = (buff[1] << 8 | buff[0]) * 1038; } break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -2576,11 +2641,23 @@ static int smb5_init_hw(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; int rc; u8 val = 0, mask = 0; u8 val = 0, mask = 0, buf[2] = {0}; if (chip->dt.no_battery) chg->fake_capacity = 50; if (chg->sdam_base) { rc = smblib_write(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0); if (rc < 0) pr_err("Couldn't clear SDAM QC status rc=%d\n", rc); rc = smblib_batch_write(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, buf, 2); if (rc < 0) pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc); } if (chip->dt.batt_profile_fcc_ua < 0) smblib_get_charge_param(chg, &chg->param.fcc, &chg->batt_profile_fcc_ua); Loading Loading @@ -3673,6 +3750,9 @@ static void smb5_shutdown(struct platform_device *pdev) /* disable all interrupts */ smb5_disable_interrupts(chg); /* disable the SMB_EN configuration */ smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, 0); /* configure power role for UFP */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, Loading drivers/power/supply/qcom/smb5-lib.c +13 −0 Original line number Diff line number Diff line Loading @@ -6164,6 +6164,7 @@ static void typec_src_removal(struct smb_charger *chg) struct smb_irq_data *data; struct storm_watch *wdata; int sec_charger; u8 val[2] = {0}; sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL : POWER_SUPPLY_CHARGER_SEC_NONE; Loading Loading @@ -6254,6 +6255,18 @@ static void typec_src_removal(struct smb_charger *chg) smblib_err(chg, "Couldn't write float charger options rc=%d\n", rc); if (chg->sdam_base) { rc = smblib_write(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0); if (rc < 0) pr_err("Couldn't clear SDAM QC status rc=%d\n", rc); rc = smblib_batch_write(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, val, 2); if (rc < 0) pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc); } if (!chg->pr_swap_in_progress) { rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL); if (rc < 0) Loading drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,7 @@ struct smb_charger { struct smb_chg_freq chg_freq; int otg_delay_ms; int weak_chg_icl_ua; u32 sdam_base; bool pd_not_supported; /* locks */ Loading drivers/power/supply/qcom/smb5-reg.h +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #define PERPH_SUBTYPE_OFFSET 0x05 #define SUBTYPE_MASK GENMASK(7, 0) #define INT_RT_STS_OFFSET 0x10 #define SDAM_TYPE 0x2E /******************************** * CHGR Peripheral Registers * Loading Loading @@ -549,4 +550,8 @@ enum { /* SDAM regs */ #define MISC_PBS_RT_STS_REG (MISC_PBS_BASE + 0x10) #define PULSE_SKIP_IRQ_BIT BIT(4) #define SDAM_QC_DET_STATUS_REG 0x58 #define SDAM_QC_ADC_LSB_REG 0x54 #endif /* __SMB5_CHARGER_REG_H */ Loading
drivers/power/supply/qcom/qpnp-smb5.c +81 −1 Original line number Diff line number Diff line Loading @@ -730,6 +730,46 @@ static int smb5_parse_dt_voltages(struct smb5 *chip, struct device_node *node) return 0; } static int smb5_parse_sdam(struct smb5 *chip, struct device_node *node) { struct device_node *child; struct smb_charger *chg = &chip->chg; struct property *prop; const char *name; int rc; u32 base; u8 type; for_each_available_child_of_node(node, child) { of_property_for_each_string(child, "reg", prop, name) { rc = of_property_read_u32(child, "reg", &base); if (rc < 0) { pr_err("Failed to read base rc=%d\n", rc); return rc; } rc = smblib_read(chg, base + PERPH_TYPE_OFFSET, &type); if (rc < 0) { pr_err("Failed to read type rc=%d\n", rc); return rc; } switch (type) { case SDAM_TYPE: chg->sdam_base = base; break; default: break; } } } if (!chg->sdam_base) pr_debug("SDAM node not defined\n"); return 0; } static int smb5_parse_dt(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; Loading Loading @@ -757,6 +797,10 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) return rc; rc = smb5_parse_sdam(chip, node); if (rc < 0) return rc; return 0; } Loading Loading @@ -828,6 +872,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_SKIN_HEALTH, POWER_SUPPLY_PROP_APSD_RERUN, POWER_SUPPLY_PROP_APSD_TIMEOUT, POWER_SUPPLY_PROP_CHARGER_STATUS, POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading @@ -837,6 +883,7 @@ static int smb5_usb_get_prop(struct power_supply *psy, struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; u8 reg = 0, buff[2] = {0}; val->intval = 0; switch (psp) { Loading Loading @@ -977,6 +1024,24 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_APSD_TIMEOUT: val->intval = chg->apsd_ext_timeout; break; case POWER_SUPPLY_PROP_CHARGER_STATUS: val->intval = 0; if (chg->sdam_base) { rc = smblib_read(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, ®); if (!rc) val->intval = reg; } break; case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: val->intval = 0; if (chg->sdam_base) { rc = smblib_batch_read(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2); if (!rc) val->intval = (buff[1] << 8 | buff[0]) * 1038; } break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -2576,11 +2641,23 @@ static int smb5_init_hw(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; int rc; u8 val = 0, mask = 0; u8 val = 0, mask = 0, buf[2] = {0}; if (chip->dt.no_battery) chg->fake_capacity = 50; if (chg->sdam_base) { rc = smblib_write(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0); if (rc < 0) pr_err("Couldn't clear SDAM QC status rc=%d\n", rc); rc = smblib_batch_write(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, buf, 2); if (rc < 0) pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc); } if (chip->dt.batt_profile_fcc_ua < 0) smblib_get_charge_param(chg, &chg->param.fcc, &chg->batt_profile_fcc_ua); Loading Loading @@ -3673,6 +3750,9 @@ static void smb5_shutdown(struct platform_device *pdev) /* disable all interrupts */ smb5_disable_interrupts(chg); /* disable the SMB_EN configuration */ smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, 0); /* configure power role for UFP */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, Loading
drivers/power/supply/qcom/smb5-lib.c +13 −0 Original line number Diff line number Diff line Loading @@ -6164,6 +6164,7 @@ static void typec_src_removal(struct smb_charger *chg) struct smb_irq_data *data; struct storm_watch *wdata; int sec_charger; u8 val[2] = {0}; sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL : POWER_SUPPLY_CHARGER_SEC_NONE; Loading Loading @@ -6254,6 +6255,18 @@ static void typec_src_removal(struct smb_charger *chg) smblib_err(chg, "Couldn't write float charger options rc=%d\n", rc); if (chg->sdam_base) { rc = smblib_write(chg, chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0); if (rc < 0) pr_err("Couldn't clear SDAM QC status rc=%d\n", rc); rc = smblib_batch_write(chg, chg->sdam_base + SDAM_QC_ADC_LSB_REG, val, 2); if (rc < 0) pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc); } if (!chg->pr_swap_in_progress) { rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL); if (rc < 0) Loading
drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,7 @@ struct smb_charger { struct smb_chg_freq chg_freq; int otg_delay_ms; int weak_chg_icl_ua; u32 sdam_base; bool pd_not_supported; /* locks */ Loading
drivers/power/supply/qcom/smb5-reg.h +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #define PERPH_SUBTYPE_OFFSET 0x05 #define SUBTYPE_MASK GENMASK(7, 0) #define INT_RT_STS_OFFSET 0x10 #define SDAM_TYPE 0x2E /******************************** * CHGR Peripheral Registers * Loading Loading @@ -549,4 +550,8 @@ enum { /* SDAM regs */ #define MISC_PBS_RT_STS_REG (MISC_PBS_BASE + 0x10) #define PULSE_SKIP_IRQ_BIT BIT(4) #define SDAM_QC_DET_STATUS_REG 0x58 #define SDAM_QC_ADC_LSB_REG 0x54 #endif /* __SMB5_CHARGER_REG_H */