Loading drivers/power/supply/qcom/qg-reg.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef __QG_REG_H__ Loading Loading @@ -121,6 +121,7 @@ #define QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET 0x6E /* 4-byte 0x6E-0x71 */ #define QG_SDAM_ESR_CHARGE_SF_OFFSET 0x72 /* 2-byte 0x72-0x73 */ #define QG_SDAM_ESR_DISCHARGE_SF_OFFSET 0x74 /* 2-byte 0x74-0x75 */ #define QG_SDAM_MAGIC_OFFSET 0x80 /* 4-byte 0x80-0x83 */ #define QG_SDAM_MAX_OFFSET 0xA4 /* Below offset is used by PBS */ Loading drivers/power/supply/qcom/qg-sdam.c +23 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "QG-K: %s: " fmt, __func__ Loading Loading @@ -81,6 +81,11 @@ static struct qg_sdam_info sdam_info[] = { .offset = QG_SDAM_ESR_DISCHARGE_SF_OFFSET, .length = 2, }, [SDAM_MAGIC] = { .name = "SDAM_MAGIC_OFFSET", .offset = QG_SDAM_MAGIC_OFFSET, .length = 4, }, }; int qg_sdam_write(u8 param, u32 data) Loading Loading @@ -235,6 +240,23 @@ int qg_sdam_write_all(u32 *sdam_data) return 0; } int qg_sdam_clear(void) { int i, rc = 0; struct qg_sdam *chip = the_chip; u8 data = 0; if (!chip) { pr_err("Invalid sdam-chip pointer\n"); return -EINVAL; } for (i = SDAM_MIN_OFFSET; i <= SDAM_MAX_OFFSET; i++) rc |= qg_sdam_multibyte_write(i, &data, 1); return rc; } int qg_sdam_init(struct device *dev) { int rc; Loading drivers/power/supply/qcom/qg-sdam.h +5 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef __QG_SDAM_H__ #define __QG_SDAM_H__ #define SDAM_TYPE 0x2E #define SDAM_MIN_OFFSET 0x45 #define SDAM_MAX_OFFSET 0xB3 enum qg_sdam_param { SDAM_VALID, Loading @@ -21,6 +23,7 @@ enum qg_sdam_param { SDAM_ESR_DISCHARGE_DELTA, SDAM_ESR_CHARGE_SF, SDAM_ESR_DISCHARGE_SF, SDAM_MAGIC, SDAM_MAX, }; Loading @@ -36,5 +39,6 @@ int qg_sdam_write_all(u32 *sdam_data); int qg_sdam_read_all(u32 *sdam_data); int qg_sdam_multibyte_write(u32 offset, u8 *sdam_data, u32 length); int qg_sdam_multibyte_read(u32 offset, u8 *sdam_data, u32 length); int qg_sdam_clear(void); #endif drivers/power/supply/qcom/qpnp-qg.c +39 −0 Original line number Diff line number Diff line Loading @@ -3175,6 +3175,39 @@ static int qg_set_wa_flags(struct qpnp_qg *chip) return 0; } #define SDAM_MAGIC_NUMBER 0x12345678 static int qg_sanitize_sdam(struct qpnp_qg *chip) { int rc = 0; u32 data = 0; rc = qg_sdam_read(SDAM_MAGIC, &data); if (rc < 0) { pr_err("Failed to read SDAM rc=%d\n", rc); return rc; } if (data == SDAM_MAGIC_NUMBER) { qg_dbg(chip, QG_DEBUG_PON, "SDAM valid\n"); } else if (data == 0) { rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER); if (!rc) qg_dbg(chip, QG_DEBUG_PON, "First boot. SDAM initilized\n"); } else { /* SDAM has invalid value */ rc = qg_sdam_clear(); if (!rc) { pr_err("SDAM uninitialized, SDAM reset\n"); rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER); } } if (rc < 0) pr_err("Failed in SDAM operation, rc=%d\n", rc); return rc; } #define ADC_CONV_DLY_512MS 0xA static int qg_hw_init(struct qpnp_qg *chip) { Loading Loading @@ -4351,6 +4384,12 @@ static int qpnp_qg_probe(struct platform_device *pdev) return rc; } rc = qg_sanitize_sdam(chip); if (rc < 0) { pr_err("Failed to sanitize SDAM, rc=%d\n", rc); return rc; } rc = qg_soc_init(chip); if (rc < 0) { pr_err("Failed to initialize SOC scaling init rc=%d\n", rc); Loading Loading
drivers/power/supply/qcom/qg-reg.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef __QG_REG_H__ Loading Loading @@ -121,6 +121,7 @@ #define QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET 0x6E /* 4-byte 0x6E-0x71 */ #define QG_SDAM_ESR_CHARGE_SF_OFFSET 0x72 /* 2-byte 0x72-0x73 */ #define QG_SDAM_ESR_DISCHARGE_SF_OFFSET 0x74 /* 2-byte 0x74-0x75 */ #define QG_SDAM_MAGIC_OFFSET 0x80 /* 4-byte 0x80-0x83 */ #define QG_SDAM_MAX_OFFSET 0xA4 /* Below offset is used by PBS */ Loading
drivers/power/supply/qcom/qg-sdam.c +23 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "QG-K: %s: " fmt, __func__ Loading Loading @@ -81,6 +81,11 @@ static struct qg_sdam_info sdam_info[] = { .offset = QG_SDAM_ESR_DISCHARGE_SF_OFFSET, .length = 2, }, [SDAM_MAGIC] = { .name = "SDAM_MAGIC_OFFSET", .offset = QG_SDAM_MAGIC_OFFSET, .length = 4, }, }; int qg_sdam_write(u8 param, u32 data) Loading Loading @@ -235,6 +240,23 @@ int qg_sdam_write_all(u32 *sdam_data) return 0; } int qg_sdam_clear(void) { int i, rc = 0; struct qg_sdam *chip = the_chip; u8 data = 0; if (!chip) { pr_err("Invalid sdam-chip pointer\n"); return -EINVAL; } for (i = SDAM_MIN_OFFSET; i <= SDAM_MAX_OFFSET; i++) rc |= qg_sdam_multibyte_write(i, &data, 1); return rc; } int qg_sdam_init(struct device *dev) { int rc; Loading
drivers/power/supply/qcom/qg-sdam.h +5 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef __QG_SDAM_H__ #define __QG_SDAM_H__ #define SDAM_TYPE 0x2E #define SDAM_MIN_OFFSET 0x45 #define SDAM_MAX_OFFSET 0xB3 enum qg_sdam_param { SDAM_VALID, Loading @@ -21,6 +23,7 @@ enum qg_sdam_param { SDAM_ESR_DISCHARGE_DELTA, SDAM_ESR_CHARGE_SF, SDAM_ESR_DISCHARGE_SF, SDAM_MAGIC, SDAM_MAX, }; Loading @@ -36,5 +39,6 @@ int qg_sdam_write_all(u32 *sdam_data); int qg_sdam_read_all(u32 *sdam_data); int qg_sdam_multibyte_write(u32 offset, u8 *sdam_data, u32 length); int qg_sdam_multibyte_read(u32 offset, u8 *sdam_data, u32 length); int qg_sdam_clear(void); #endif
drivers/power/supply/qcom/qpnp-qg.c +39 −0 Original line number Diff line number Diff line Loading @@ -3175,6 +3175,39 @@ static int qg_set_wa_flags(struct qpnp_qg *chip) return 0; } #define SDAM_MAGIC_NUMBER 0x12345678 static int qg_sanitize_sdam(struct qpnp_qg *chip) { int rc = 0; u32 data = 0; rc = qg_sdam_read(SDAM_MAGIC, &data); if (rc < 0) { pr_err("Failed to read SDAM rc=%d\n", rc); return rc; } if (data == SDAM_MAGIC_NUMBER) { qg_dbg(chip, QG_DEBUG_PON, "SDAM valid\n"); } else if (data == 0) { rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER); if (!rc) qg_dbg(chip, QG_DEBUG_PON, "First boot. SDAM initilized\n"); } else { /* SDAM has invalid value */ rc = qg_sdam_clear(); if (!rc) { pr_err("SDAM uninitialized, SDAM reset\n"); rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER); } } if (rc < 0) pr_err("Failed in SDAM operation, rc=%d\n", rc); return rc; } #define ADC_CONV_DLY_512MS 0xA static int qg_hw_init(struct qpnp_qg *chip) { Loading Loading @@ -4351,6 +4384,12 @@ static int qpnp_qg_probe(struct platform_device *pdev) return rc; } rc = qg_sanitize_sdam(chip); if (rc < 0) { pr_err("Failed to sanitize SDAM, rc=%d\n", rc); return rc; } rc = qg_soc_init(chip); if (rc < 0) { pr_err("Failed to initialize SOC scaling init rc=%d\n", rc); Loading