Loading drivers/power/supply/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pd_voltage_max), POWER_SUPPLY_ATTR(pd_voltage_min), POWER_SUPPLY_ATTR(sdp_current_max), POWER_SUPPLY_ATTR(fg_reset_clock), POWER_SUPPLY_ATTR(connector_type), POWER_SUPPLY_ATTR(parallel_batfet_mode), POWER_SUPPLY_ATTR(parallel_fcc_max), Loading drivers/power/supply/qcom/fg-core.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef __FG_CORE_H__ Loading Loading @@ -607,4 +607,5 @@ extern int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input, s32 *output); void fg_stay_awake(struct fg_dev *fg, int awake_reason); void fg_relax(struct fg_dev *fg, int awake_reason); extern int fg_dma_mem_req(struct fg_dev *fg, bool request); #endif drivers/power/supply/qcom/fg-memif.c +59 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ Loading Loading @@ -1078,6 +1078,64 @@ static int __fg_direct_mem_rw(struct fg_dev *fg, u16 sram_addr, u8 offset, return rc; } int fg_dma_mem_req(struct fg_dev *chip, bool request) { int ret, rc = 0, retry_count = RETRY_COUNT; u8 val; if (request) { /* configure for DMA access */ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, MEM_ACCESS_REQ_BIT); if (rc < 0) { pr_err("failed to set mem_access bit rc=%d\n", rc); return rc; } rc = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), MEM_IF_ARB_REQ_BIT, MEM_IF_ARB_REQ_BIT); if (rc < 0) { pr_err("failed to set mem_arb bit rc=%d\n", rc); goto release_mem; } while (retry_count--) { rc = fg_read(chip, MEM_IF_INT_RT_STS(chip), &val, 1); if (rc < 0) { pr_err("failed to set ima_rt_sts rc=%d\n", rc); goto release_mem; } if (val & MEM_GNT_BIT) break; msleep(20); } if ((retry_count < 0) && !(val & MEM_GNT_BIT)) { pr_err("failed to get memory access\n"); rc = -ETIMEDOUT; goto release_mem; } return 0; } release_mem: /* Release access */ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0); if (rc < 0) pr_err("failed to reset mem_access bit rc = %d\n", rc); ret = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), MEM_IF_ARB_REQ_BIT, 0); if (ret < 0) { pr_err("failed to release mem_arb bit rc=%d\n", ret); return ret; } return rc; } int fg_direct_mem_read(struct fg_dev *fg, u16 sram_addr, u8 offset, u8 *val, int len) { Loading drivers/power/supply/qcom/fg-reg.h +15 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef __FG_REG_H__ Loading Loading @@ -58,6 +58,9 @@ #define BATT_SOC_RESTART(chip) (chip->batt_soc_base + 0x48) #define RESTART_GO_BIT BIT(0) /* BCL_RESET */ #define BCL_RESET_BIT BIT(2) #define BATT_SOC_STS_CLR(chip) (chip->batt_soc_base + 0x4A) #define BATT_SOC_LOW_PWR_CFG(chip) (chip->batt_soc_base + 0x52) #define BATT_SOC_LOW_PWR_STS(chip) (chip->batt_soc_base + 0x56) Loading @@ -68,6 +71,8 @@ /* FG_BATT_INFO register definitions */ #define BATT_INFO_BATT_TEMP_STS(chip) (chip->batt_info_base + 0x06) #define BATT_INFO_PEEK_MUX1(chip) (chip->batt_info_base + 0xEB) #define BATT_INFO_RDBACK(chip) (chip->batt_info_base + 0xEF) #define JEITA_TOO_HOT_STS_BIT BIT(7) #define JEITA_HOT_STS_BIT BIT(6) #define JEITA_COLD_STS_BIT BIT(5) Loading Loading @@ -285,6 +290,12 @@ #define ESR_REQ_CTL_BIT BIT(1) #define ESR_REQ_CTL_EN_BIT BIT(0) /* BATT_INFO_PEEK_MUX1 */ #define PEEK_MUX1_BIT BIT(0) #define MEM_IF_MEM_ARB_CFG(chip) ((chip->mem_if_base) + 0x40) #define MEM_GNT_BIT BIT(2) #define BATT_INFO_PEEK_MUX4(chip) (chip->batt_info_base + 0xEE) #define ALG_ACTIVE_PEEK_CFG 0xAC Loading Loading @@ -357,6 +368,9 @@ #define ADDR_KIND_BIT BIT(1) #define DMA_CLEAR_LOG_BIT BIT(0) /* MEM_IF_REQ */ #define MEM_IF_ARB_REQ_BIT BIT(0) /* FG_DMAx */ #define FG_DMA0_BASE 0x4800 #define FG_DMA1_BASE 0x4900 Loading drivers/power/supply/qcom/qpnp-fg-gen3.c +108 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ Loading Loading @@ -3766,6 +3766,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CC_STEP_SEL: pval->intval = chip->ttf.cc_step.sel; break; case POWER_SUPPLY_PROP_FG_RESET_CLOCK: pval->intval = 0; break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading @@ -3778,6 +3781,100 @@ static int fg_psy_get_property(struct power_supply *psy, return 0; } #define BCL_RESET_RETRY_COUNT 4 static int fg_bcl_reset(struct fg_dev *chip) { int i, ret, rc = 0; u8 val, peek_mux; bool success = false; /* Read initial value of peek mux1 */ rc = fg_read(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1); if (rc < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); return rc; } val = 0x83; rc = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &val, 1); if (rc < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); return rc; } mutex_lock(&chip->sram_rw_lock); for (i = 0; i < BCL_RESET_RETRY_COUNT; i++) { rc = fg_dma_mem_req(chip, true); if (rc < 0) { pr_err("Error in locking memory, rc=%d\n", rc); goto unlock; } rc = fg_read(chip, BATT_INFO_RDBACK(chip), &val, 1); if (rc < 0) { pr_err("Error in reading rdback, rc=%d\n", rc); goto release_mem; } if (val & PEEK_MUX1_BIT) { rc = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip), BCL_RESET_BIT, BCL_RESET_BIT); if (rc < 0) { pr_err("Error in writing RST_CTRL0, rc=%d\n", rc); goto release_mem; } rc = fg_dma_mem_req(chip, false); if (rc < 0) pr_err("Error in unlocking memory, rc=%d\n", rc); /* Delay of 2ms */ usleep_range(2000, 3000); ret = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip), BCL_RESET_BIT, 0); if (ret < 0) pr_err("Error in writing RST_CTRL0, rc=%d\n", rc); if (!rc && !ret) success = true; goto unlock; } else { rc = fg_dma_mem_req(chip, false); if (rc < 0) { pr_err("Error in unlocking memory, rc=%d\n", rc); goto unlock; } success = false; pr_err_ratelimited("PEEK_MUX1 not set retrying...\n"); msleep(1000); } } release_mem: rc = fg_dma_mem_req(chip, false); if (rc < 0) pr_err("Error in unlocking memory, rc=%d\n", rc); unlock: ret = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1); if (ret < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); mutex_unlock(&chip->sram_rw_lock); return ret; } mutex_unlock(&chip->sram_rw_lock); if (!success) return -EAGAIN; else return rc; } static int fg_psy_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *pval) Loading Loading @@ -3816,6 +3913,7 @@ static int fg_psy_set_property(struct power_supply *psy, return -EINVAL; } break; case POWER_SUPPLY_PROP_CHARGE_FULL: if (chip->cl.active) { pr_warn("Capacity learning active!\n"); Loading Loading @@ -3858,6 +3956,14 @@ static int fg_psy_set_property(struct power_supply *psy, return rc; } break; case POWER_SUPPLY_PROP_FG_RESET_CLOCK: rc = fg_bcl_reset(fg); if (rc < 0) { pr_err("Error in resetting BCL clock, rc=%d\n", rc); return rc; } break; default: break; } Loading Loading @@ -3972,6 +4078,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, POWER_SUPPLY_PROP_CC_STEP, POWER_SUPPLY_PROP_CC_STEP_SEL, POWER_SUPPLY_PROP_FG_RESET_CLOCK, }; static const struct power_supply_desc fg_psy_desc = { Loading Loading
drivers/power/supply/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pd_voltage_max), POWER_SUPPLY_ATTR(pd_voltage_min), POWER_SUPPLY_ATTR(sdp_current_max), POWER_SUPPLY_ATTR(fg_reset_clock), POWER_SUPPLY_ATTR(connector_type), POWER_SUPPLY_ATTR(parallel_batfet_mode), POWER_SUPPLY_ATTR(parallel_fcc_max), Loading
drivers/power/supply/qcom/fg-core.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef __FG_CORE_H__ Loading Loading @@ -607,4 +607,5 @@ extern int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input, s32 *output); void fg_stay_awake(struct fg_dev *fg, int awake_reason); void fg_relax(struct fg_dev *fg, int awake_reason); extern int fg_dma_mem_req(struct fg_dev *fg, bool request); #endif
drivers/power/supply/qcom/fg-memif.c +59 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ Loading Loading @@ -1078,6 +1078,64 @@ static int __fg_direct_mem_rw(struct fg_dev *fg, u16 sram_addr, u8 offset, return rc; } int fg_dma_mem_req(struct fg_dev *chip, bool request) { int ret, rc = 0, retry_count = RETRY_COUNT; u8 val; if (request) { /* configure for DMA access */ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, MEM_ACCESS_REQ_BIT); if (rc < 0) { pr_err("failed to set mem_access bit rc=%d\n", rc); return rc; } rc = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), MEM_IF_ARB_REQ_BIT, MEM_IF_ARB_REQ_BIT); if (rc < 0) { pr_err("failed to set mem_arb bit rc=%d\n", rc); goto release_mem; } while (retry_count--) { rc = fg_read(chip, MEM_IF_INT_RT_STS(chip), &val, 1); if (rc < 0) { pr_err("failed to set ima_rt_sts rc=%d\n", rc); goto release_mem; } if (val & MEM_GNT_BIT) break; msleep(20); } if ((retry_count < 0) && !(val & MEM_GNT_BIT)) { pr_err("failed to get memory access\n"); rc = -ETIMEDOUT; goto release_mem; } return 0; } release_mem: /* Release access */ rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip), MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0); if (rc < 0) pr_err("failed to reset mem_access bit rc = %d\n", rc); ret = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip), MEM_IF_ARB_REQ_BIT, 0); if (ret < 0) { pr_err("failed to release mem_arb bit rc=%d\n", ret); return ret; } return rc; } int fg_direct_mem_read(struct fg_dev *fg, u16 sram_addr, u8 offset, u8 *val, int len) { Loading
drivers/power/supply/qcom/fg-reg.h +15 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef __FG_REG_H__ Loading Loading @@ -58,6 +58,9 @@ #define BATT_SOC_RESTART(chip) (chip->batt_soc_base + 0x48) #define RESTART_GO_BIT BIT(0) /* BCL_RESET */ #define BCL_RESET_BIT BIT(2) #define BATT_SOC_STS_CLR(chip) (chip->batt_soc_base + 0x4A) #define BATT_SOC_LOW_PWR_CFG(chip) (chip->batt_soc_base + 0x52) #define BATT_SOC_LOW_PWR_STS(chip) (chip->batt_soc_base + 0x56) Loading @@ -68,6 +71,8 @@ /* FG_BATT_INFO register definitions */ #define BATT_INFO_BATT_TEMP_STS(chip) (chip->batt_info_base + 0x06) #define BATT_INFO_PEEK_MUX1(chip) (chip->batt_info_base + 0xEB) #define BATT_INFO_RDBACK(chip) (chip->batt_info_base + 0xEF) #define JEITA_TOO_HOT_STS_BIT BIT(7) #define JEITA_HOT_STS_BIT BIT(6) #define JEITA_COLD_STS_BIT BIT(5) Loading Loading @@ -285,6 +290,12 @@ #define ESR_REQ_CTL_BIT BIT(1) #define ESR_REQ_CTL_EN_BIT BIT(0) /* BATT_INFO_PEEK_MUX1 */ #define PEEK_MUX1_BIT BIT(0) #define MEM_IF_MEM_ARB_CFG(chip) ((chip->mem_if_base) + 0x40) #define MEM_GNT_BIT BIT(2) #define BATT_INFO_PEEK_MUX4(chip) (chip->batt_info_base + 0xEE) #define ALG_ACTIVE_PEEK_CFG 0xAC Loading Loading @@ -357,6 +368,9 @@ #define ADDR_KIND_BIT BIT(1) #define DMA_CLEAR_LOG_BIT BIT(0) /* MEM_IF_REQ */ #define MEM_IF_ARB_REQ_BIT BIT(0) /* FG_DMAx */ #define FG_DMA0_BASE 0x4800 #define FG_DMA1_BASE 0x4900 Loading
drivers/power/supply/qcom/qpnp-fg-gen3.c +108 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ Loading Loading @@ -3766,6 +3766,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CC_STEP_SEL: pval->intval = chip->ttf.cc_step.sel; break; case POWER_SUPPLY_PROP_FG_RESET_CLOCK: pval->intval = 0; break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading @@ -3778,6 +3781,100 @@ static int fg_psy_get_property(struct power_supply *psy, return 0; } #define BCL_RESET_RETRY_COUNT 4 static int fg_bcl_reset(struct fg_dev *chip) { int i, ret, rc = 0; u8 val, peek_mux; bool success = false; /* Read initial value of peek mux1 */ rc = fg_read(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1); if (rc < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); return rc; } val = 0x83; rc = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &val, 1); if (rc < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); return rc; } mutex_lock(&chip->sram_rw_lock); for (i = 0; i < BCL_RESET_RETRY_COUNT; i++) { rc = fg_dma_mem_req(chip, true); if (rc < 0) { pr_err("Error in locking memory, rc=%d\n", rc); goto unlock; } rc = fg_read(chip, BATT_INFO_RDBACK(chip), &val, 1); if (rc < 0) { pr_err("Error in reading rdback, rc=%d\n", rc); goto release_mem; } if (val & PEEK_MUX1_BIT) { rc = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip), BCL_RESET_BIT, BCL_RESET_BIT); if (rc < 0) { pr_err("Error in writing RST_CTRL0, rc=%d\n", rc); goto release_mem; } rc = fg_dma_mem_req(chip, false); if (rc < 0) pr_err("Error in unlocking memory, rc=%d\n", rc); /* Delay of 2ms */ usleep_range(2000, 3000); ret = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip), BCL_RESET_BIT, 0); if (ret < 0) pr_err("Error in writing RST_CTRL0, rc=%d\n", rc); if (!rc && !ret) success = true; goto unlock; } else { rc = fg_dma_mem_req(chip, false); if (rc < 0) { pr_err("Error in unlocking memory, rc=%d\n", rc); goto unlock; } success = false; pr_err_ratelimited("PEEK_MUX1 not set retrying...\n"); msleep(1000); } } release_mem: rc = fg_dma_mem_req(chip, false); if (rc < 0) pr_err("Error in unlocking memory, rc=%d\n", rc); unlock: ret = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1); if (ret < 0) { pr_err("Error in writing peek mux1, rc=%d\n", rc); mutex_unlock(&chip->sram_rw_lock); return ret; } mutex_unlock(&chip->sram_rw_lock); if (!success) return -EAGAIN; else return rc; } static int fg_psy_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *pval) Loading Loading @@ -3816,6 +3913,7 @@ static int fg_psy_set_property(struct power_supply *psy, return -EINVAL; } break; case POWER_SUPPLY_PROP_CHARGE_FULL: if (chip->cl.active) { pr_warn("Capacity learning active!\n"); Loading Loading @@ -3858,6 +3956,14 @@ static int fg_psy_set_property(struct power_supply *psy, return rc; } break; case POWER_SUPPLY_PROP_FG_RESET_CLOCK: rc = fg_bcl_reset(fg); if (rc < 0) { pr_err("Error in resetting BCL clock, rc=%d\n", rc); return rc; } break; default: break; } Loading Loading @@ -3972,6 +4078,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, POWER_SUPPLY_PROP_CC_STEP, POWER_SUPPLY_PROP_CC_STEP_SEL, POWER_SUPPLY_PROP_FG_RESET_CLOCK, }; static const struct power_supply_desc fg_psy_desc = { Loading