Loading drivers/power/supply/qcom/qg-reg.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -128,6 +128,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 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -88,6 +88,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 @@ -242,6 +247,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 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,6 +14,8 @@ #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 @@ -28,6 +30,7 @@ enum qg_sdam_param { SDAM_ESR_DISCHARGE_DELTA, SDAM_ESR_CHARGE_SF, SDAM_ESR_DISCHARGE_SF, SDAM_MAGIC, SDAM_MAX, }; Loading @@ -43,5 +46,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 @@ -3147,6 +3147,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 @@ -4268,6 +4301,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 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -128,6 +128,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 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -88,6 +88,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 @@ -242,6 +247,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 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,6 +14,8 @@ #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 @@ -28,6 +30,7 @@ enum qg_sdam_param { SDAM_ESR_DISCHARGE_DELTA, SDAM_ESR_CHARGE_SF, SDAM_ESR_DISCHARGE_SF, SDAM_MAGIC, SDAM_MAX, }; Loading @@ -43,5 +46,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 @@ -3147,6 +3147,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 @@ -4268,6 +4301,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