summaryrefslogtreecommitdiff
path: root/driver/charger/sm5803.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /driver/charger/sm5803.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14395.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'driver/charger/sm5803.c')
-rw-r--r--driver/charger/sm5803.c1933
1 files changed, 0 insertions, 1933 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
deleted file mode 100644
index 460dcf4093..0000000000
--- a/driver/charger/sm5803.c
+++ /dev/null
@@ -1,1933 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Silicon Mitus SM5803 Buck-Boost Charger
- */
-#include "atomic.h"
-#include "battery.h"
-#include "battery_smart.h"
-#include "charge_state_v2.h"
-#include "charger.h"
-#include "extpower.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "sm5803.h"
-#include "system.h"
-#include "stdbool.h"
-#include "throttle_ap.h"
-#include "timer.h"
-#include "usb_charge.h"
-#include "usb_pd.h"
-#include "usbc_ocp.h"
-#include "util.h"
-#include "watchdog.h"
-
-#ifndef CONFIG_CHARGER_NARROW_VDC
-#error "SM5803 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC."
-#endif
-
-/* Console output macros */
-#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
-
-#define UNKNOWN_DEV_ID -1
-static int dev_id = UNKNOWN_DEV_ID;
-
-static const struct charger_info sm5803_charger_info = {
- .name = CHARGER_NAME,
- .voltage_max = CHARGE_V_MAX,
- .voltage_min = CHARGE_V_MIN,
- .voltage_step = CHARGE_V_STEP,
- .current_max = CHARGE_I_MAX,
- .current_min = CHARGE_I_MIN,
- .current_step = CHARGE_I_STEP,
- .input_current_max = INPUT_I_MAX,
- .input_current_min = INPUT_I_MIN,
- .input_current_step = INPUT_I_STEP,
-};
-
-static uint32_t irq_pending; /* Bitmask of chips with interrupts pending */
-
-static struct mutex flow1_access_lock[CHARGER_NUM];
-static struct mutex flow2_access_lock[CHARGER_NUM];
-
-static int charger_vbus[CHARGER_NUM];
-
-/* Tracker for charging failures per port */
-struct {
- int count;
- timestamp_t time;
-} failure_tracker[CHARGER_NUM] = {};
-
-/* Port to restart charging on */
-static int active_restart_port = CHARGE_PORT_NONE;
-
-/*
- * If powered from the sub board port, we need to attempt to enable the BFET
- * before proceeding with charging.
- */
-static int attempt_bfet_enable;
-
-/*
- * Note if auto fast charge for the primary port is disabled due to a
- * disconnected battery, at re-enable auto fast charge later when the battery
- * has connected.
- */
-static bool fast_charge_disabled;
-
-
-#define CHARGING_FAILURE_MAX_COUNT 5
-#define CHARGING_FAILURE_INTERVAL MINUTE
-
-static int sm5803_is_sourcing_otg_power(int chgnum, int port);
-static enum ec_error_list sm5803_get_dev_id(int chgnum, int *id);
-static enum ec_error_list sm5803_set_current(int chgnum, int current);
-
-static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value)
-{
- return i2c_read8(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- offset, value);
-}
-
-static inline enum ec_error_list chg_write8(int chgnum, int offset, int value)
-{
- return i2c_write8(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- offset, value);
-}
-
-static inline enum ec_error_list meas_read8(int chgnum, int offset, int *value)
-{
- return i2c_read8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_MEAS_FLAGS,
- offset, value);
-}
-
-static inline enum ec_error_list meas_write8(int chgnum, int offset, int value)
-{
- return i2c_write8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_MEAS_FLAGS,
- offset, value);
-}
-
-static inline enum ec_error_list main_read8(int chgnum, int offset, int *value)
-{
- return i2c_read8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_MAIN_FLAGS,
- offset, value);
-}
-
-static inline enum ec_error_list main_write8(int chgnum, int offset, int value)
-{
- return i2c_write8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_MAIN_FLAGS,
- offset, value);
-}
-
-static inline enum ec_error_list test_write8(int chgnum, int offset, int value)
-{
- return i2c_write8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_TEST_FLAGS,
- offset, value);
-}
-
-static inline enum ec_error_list test_update8(int chgnum, const int offset,
- const uint8_t mask,
- const enum mask_update_action action)
-{
- return i2c_update8(chg_chips[chgnum].i2c_port,
- SM5803_ADDR_TEST_FLAGS, offset, mask, action);
-}
-
-static enum ec_error_list sm5803_flow1_update(int chgnum, const uint8_t mask,
- const enum mask_update_action action)
-{
- int rv;
-
- /* Safety checks done, onto the actual register update */
- mutex_lock(&flow1_access_lock[chgnum]);
-
- rv = i2c_update8(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- SM5803_REG_FLOW1,
- mask, action);
-
- mutex_unlock(&flow1_access_lock[chgnum]);
-
- return rv;
-}
-
-static enum ec_error_list sm5803_flow2_update(int chgnum, const uint8_t mask,
- const enum mask_update_action action)
-{
- int rv;
-
- mutex_lock(&flow2_access_lock[chgnum]);
-
- rv = i2c_update8(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- SM5803_REG_FLOW2,
- mask, action);
-
- mutex_unlock(&flow2_access_lock[chgnum]);
-
- return rv;
-}
-
-static bool is_platform_id_2s(uint32_t platform_id)
-{
- return platform_id >= 0x06 && platform_id <= 0x0D;
-}
-
-static bool is_platform_id_3s(uint32_t platform_id)
-{
- return platform_id >= 0x0E && platform_id <= 0x16;
-}
-
-int sm5803_is_vbus_present(int chgnum)
-{
- return charger_vbus[chgnum];
-}
-
-enum ec_error_list sm5803_configure_gpio0(int chgnum,
- enum sm5803_gpio0_modes mode, int od)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
- if (rv)
- return rv;
-
- reg &= ~SM5803_GPIO0_MODE_MASK;
- reg |= mode << 1;
-
- if (od)
- reg |= SM5803_GPIO0_OPEN_DRAIN_EN;
- else
- reg &= ~SM5803_GPIO0_OPEN_DRAIN_EN;
-
- rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
- return rv;
-}
-
-enum ec_error_list sm5803_set_gpio0_level(int chgnum, int level)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
- if (rv)
- return rv;
-
- if (level)
- reg |= SM5803_GPIO0_VAL;
- else
- reg &= ~SM5803_GPIO0_VAL;
-
- rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
- return rv;
-}
-
-enum ec_error_list sm5803_configure_chg_det_od(int chgnum, int enable)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_GPIO0_CTRL, &reg);
- if (rv)
- return rv;
-
- if (enable)
- reg |= SM5803_CHG_DET_OPEN_DRAIN_EN;
- else
- reg &= ~SM5803_CHG_DET_OPEN_DRAIN_EN;
-
- rv = main_write8(chgnum, SM5803_REG_GPIO0_CTRL, reg);
- return rv;
-}
-
-enum ec_error_list sm5803_get_chg_det(int chgnum, int *chg_det)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_STATUS1, &reg);
- if (rv)
- return rv;
-
- *chg_det = (reg & SM5803_STATUS1_CHG_DET) != 0;
-
- return EC_SUCCESS;
-}
-
-enum ec_error_list sm5803_set_vbus_disch(int chgnum, int enable)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_PORTS_CTRL, &reg);
- if (rv)
- return rv;
-
- if (enable)
- reg |= SM5803_PORTS_VBUS_DISCH;
- else
- reg &= ~SM5803_PORTS_VBUS_DISCH;
-
- rv = main_write8(chgnum, SM5803_REG_PORTS_CTRL, reg);
- return rv;
-}
-
-enum ec_error_list sm5803_vbus_sink_enable(int chgnum, int enable)
-{
- enum ec_error_list rv;
- int regval;
-
- rv = sm5803_get_dev_id(chgnum, &dev_id);
- if (rv)
- return rv;
-
- if (enable) {
- if (chgnum == CHARGER_PRIMARY) {
- /* Magic for new silicon */
- if (dev_id >= 3) {
- rv |= main_write8(chgnum, 0x1F, 0x1);
- rv |= test_write8(chgnum, 0x44, 0x2);
- rv |= main_write8(chgnum, 0x1F, 0);
- }
- /*
- * Only enable auto fast charge when a battery is
- * connected and out of cutoff.
- */
- if (battery_get_disconnect_state() ==
- BATTERY_NOT_DISCONNECTED) {
- rv = sm5803_flow2_update(chgnum,
- SM5803_FLOW2_AUTO_ENABLED,
- MASK_SET);
- fast_charge_disabled = false;
- } else {
- rv = sm5803_flow2_update(chgnum,
- SM5803_FLOW2_AUTO_TRKL_EN |
- SM5803_FLOW2_AUTO_PRECHG_EN,
- MASK_SET);
- fast_charge_disabled = true;
- }
- } else {
- if (dev_id >= 3) {
- /* Touch of magic on the primary charger */
- rv |= main_write8(CHARGER_PRIMARY, 0x1F, 0x1);
- rv |= test_write8(CHARGER_PRIMARY, 0x44, 0x20);
- rv |= main_write8(CHARGER_PRIMARY, 0x1F, 0x0);
-
- /*
- * Disable linear, pre-charge, and linear fast
- * charge for primary charger.
- */
- rv = chg_read8(CHARGER_PRIMARY,
- SM5803_REG_FLOW3, &regval);
- regval &= ~(BIT(6) | BIT(5) | BIT(4));
-
- rv |= chg_write8(CHARGER_PRIMARY,
- SM5803_REG_FLOW3, regval);
- }
- }
-
- /* Last but not least, enable sinking */
- rv |= sm5803_flow1_update(chgnum, CHARGER_MODE_SINK, MASK_SET);
- } else {
- if (chgnum == CHARGER_PRIMARY)
- rv |= sm5803_flow2_update(chgnum,
- SM5803_FLOW2_AUTO_ENABLED,
- MASK_CLR);
-
- if (chgnum == CHARGER_SECONDARY) {
- rv |= sm5803_flow1_update(CHARGER_PRIMARY,
- SM5803_FLOW1_LINEAR_CHARGE_EN,
- MASK_CLR);
-
- rv = chg_read8(CHARGER_PRIMARY, SM5803_REG_FLOW3,
- &regval);
- regval &= ~(BIT(6) | BIT(5) | BIT(4));
- rv |= chg_write8(CHARGER_PRIMARY, SM5803_REG_FLOW3,
- regval);
- }
-
-
- /* Disable sink mode, unless currently sourcing out */
- if (!sm5803_is_sourcing_otg_power(chgnum, chgnum))
- rv |= sm5803_flow1_update(chgnum, CHARGER_MODE_SINK,
- MASK_CLR);
- }
-
- return rv;
-
-}
-
-/*
- * Track and store whether we've initialized the charger chips already on this
- * boot. This should prevent us from re-running inits after sysjumps.
- */
-static bool chip_inited[CHARGER_NUM];
-#define SM5803_SYSJUMP_TAG 0x534D /* SM */
-#define SM5803_HOOK_VERSION 1
-
-static void init_status_preserve(void)
-{
- system_add_jump_tag(SM5803_SYSJUMP_TAG, SM5803_HOOK_VERSION,
- sizeof(chip_inited), &chip_inited);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, init_status_preserve, HOOK_PRIO_DEFAULT);
-
-static void init_status_retrieve(void)
-{
- const uint8_t *tag_contents;
- int version, size;
-
- tag_contents = system_get_jump_tag(SM5803_SYSJUMP_TAG,
- &version, &size);
- if (tag_contents && (version == SM5803_HOOK_VERSION) &&
- (size == sizeof(chip_inited)))
- /* Valid init status found, restore before charger chip init */
- memcpy(&chip_inited, tag_contents, size);
-}
-DECLARE_HOOK(HOOK_INIT, init_status_retrieve, HOOK_PRIO_FIRST);
-
-static void sm5803_init(int chgnum)
-{
- enum ec_error_list rv;
- int reg;
- int vbus_mv;
- const struct battery_info *batt_info;
- int pre_term;
- int cells;
-
- /*
- * If a charger is not currently present, disable switching per OCPC
- * requirements
- */
- rv = charger_get_vbus_voltage(chgnum, &vbus_mv);
- if (rv == EC_SUCCESS) {
- if (vbus_mv < 4000) {
- /*
- * No charger connected, disable CHG_EN
- * (note other bits default to 0)
- */
- rv = chg_write8(chgnum, SM5803_REG_FLOW1, 0);
- } else if (!sm5803_is_sourcing_otg_power(chgnum, chgnum)) {
- charger_vbus[chgnum] = 1;
- }
- } else {
- CPRINTS("%s %d: Failed to read VBUS voltage during init",
- CHARGER_NAME, chgnum);
- return;
- }
-
- /*
- * A previous boot already ran inits, safe to return now that we've
- * checked i2c communication to the chip and cached Vbus presence
- */
- if (chip_inited[chgnum]) {
- CPRINTS("%s %d: Already initialized", CHARGER_NAME, chgnum);
- return;
- }
-
- rv |= charger_device_id(&reg);
- if (reg == 0x02) {
- /* --- Special register init ---
- * For early silicon (ID 2) with 3S batteries
- */
- rv |= main_write8(chgnum, 0x20, 0x08);
- rv |= main_write8(chgnum, 0x30, 0xC0);
- rv |= main_write8(chgnum, 0x80, 0x01);
-
- rv |= meas_write8(chgnum, 0x08, 0xC2);
-
- rv |= chg_write8(chgnum, 0x1D, 0x40);
- rv |= chg_write8(chgnum, 0x1F, 0x09);
-
- rv |= chg_write8(chgnum, 0x22, 0xB3);
- rv |= chg_write8(chgnum, 0x23, 0x81);
- rv |= chg_write8(chgnum, 0x28, 0xB7);
-
- rv |= chg_write8(chgnum, 0x4A, 0x82);
- rv |= chg_write8(chgnum, 0x4B, 0xA3);
- rv |= chg_write8(chgnum, 0x4C, 0xA8);
- rv |= chg_write8(chgnum, 0x4D, 0xCA);
- rv |= chg_write8(chgnum, 0x4E, 0x07);
- rv |= chg_write8(chgnum, 0x4F, 0xFF);
-
- rv |= chg_write8(chgnum, 0x50, 0x98);
- rv |= chg_write8(chgnum, 0x51, 0x00);
- rv |= chg_write8(chgnum, 0x52, 0x77);
- rv |= chg_write8(chgnum, 0x53, 0xD2);
- rv |= chg_write8(chgnum, 0x54, 0x02);
- rv |= chg_write8(chgnum, 0x55, 0xD1);
- rv |= chg_write8(chgnum, 0x56, 0x7F);
- rv |= chg_write8(chgnum, 0x57, 0x02);
- rv |= chg_write8(chgnum, 0x58, 0xD1);
- rv |= chg_write8(chgnum, 0x59, 0x7F);
- rv |= chg_write8(chgnum, 0x5A, 0x13);
- rv |= chg_write8(chgnum, 0x5B, 0x50);
- rv |= chg_write8(chgnum, 0x5C, 0x5B);
- rv |= chg_write8(chgnum, 0x5D, 0xB0);
- rv |= chg_write8(chgnum, 0x5E, 0x3C);
- rv |= chg_write8(chgnum, 0x5F, 0x3C);
-
- rv |= chg_write8(chgnum, 0x60, 0x44);
- rv |= chg_write8(chgnum, 0x61, 0x20);
- rv |= chg_write8(chgnum, 0x65, 0x35);
- rv |= chg_write8(chgnum, 0x66, 0x29);
- rv |= chg_write8(chgnum, 0x67, 0x64);
- rv |= chg_write8(chgnum, 0x68, 0x88);
- rv |= chg_write8(chgnum, 0x69, 0xC7);
-
- /* Inits to access page 0x37 and enable trickle charging */
- rv |= main_write8(chgnum, 0x1F, 0x01);
- rv |= test_update8(chgnum, 0x8E, BIT(5), MASK_SET);
- rv |= main_write8(chgnum, 0x1F, 0x00);
- } else if (reg == 0x03) {
- uint32_t platform_id;
-
- rv = main_read8(chgnum, SM5803_REG_PLATFORM, &platform_id);
- if (rv) {
- CPRINTS("%s %d: Failed to read platform during init",
- CHARGER_NAME, chgnum);
- return;
- }
- platform_id &= SM5803_PLATFORM_ID;
-
- if (is_platform_id_3s(platform_id)) {
- /* 3S Battery inits */
- /* set 13.3V VBAT_SNSP TH GPADC THRESHOLD*/
- rv |= meas_write8(chgnum, 0x26,
- SM5803_VBAT_SNSP_MAXTH_3S_LEVEL);
- /* OV_VBAT HW second level (14.1V) */
- rv |= chg_write8(chgnum, 0x21,
- SM5803_VBAT_PWR_MINTH_3S_LEVEL);
- rv |= main_write8(chgnum, 0x30, 0xC0);
- rv |= main_write8(chgnum, 0x80, 0x01);
- rv |= main_write8(chgnum, 0x1A, 0x08);
-
- rv |= meas_write8(chgnum, 0x08, 0xC2);
-
- rv |= chg_write8(chgnum, 0x1D, 0x40);
-
- rv |= chg_write8(chgnum, 0x22, 0xB3);
-
- rv |= chg_write8(chgnum, 0x3E, 0x3C);
-
- rv |= chg_write8(chgnum, 0x4B, 0xA6);
- rv |= chg_write8(chgnum, 0x4F, 0xBF);
-
- rv |= chg_write8(chgnum, 0x52, 0x77);
- rv |= chg_write8(chgnum, 0x53, 0xD2);
- rv |= chg_write8(chgnum, 0x54, 0x02);
- rv |= chg_write8(chgnum, 0x55, 0xD1);
- rv |= chg_write8(chgnum, 0x56, 0x7F);
- rv |= chg_write8(chgnum, 0x57, 0x01);
- rv |= chg_write8(chgnum, 0x58, 0x50);
- rv |= chg_write8(chgnum, 0x59, 0x7F);
- rv |= chg_write8(chgnum, 0x5A, 0x13);
- rv |= chg_write8(chgnum, 0x5B, 0x50);
- rv |= chg_write8(chgnum, 0x5D, 0xB0);
-
- rv |= chg_write8(chgnum, 0x60, 0x44);
- rv |= chg_write8(chgnum, 0x65, 0x35);
- rv |= chg_write8(chgnum, 0x66, 0x29);
-
- rv |= chg_write8(chgnum, 0x7D, 0x67);
- rv |= chg_write8(chgnum, 0x7E, 0x04);
-
- rv |= chg_write8(chgnum, 0x33, 0x3C);
-
- rv |= chg_write8(chgnum, 0x5C, 0x7A);
- } else if (is_platform_id_2s(platform_id)) {
- /* 2S Battery inits */
-
- /*
- * Set 9V as higher threshold for VBATSNSP_MAX_TH GPADC
- * threshold for interrupt generation.
- */
- rv |= meas_write8(chgnum, 0x26,
- SM5803_VBAT_SNSP_MAXTH_2S_LEVEL);
-
- /* Set OV_VBAT HW second level threshold as 9.4V */
- rv |= chg_write8(chgnum, 0x21,
- SM5803_VBAT_PWR_MINTH_2S_LEVEL);
-
- rv |= main_write8(chgnum, 0x30, 0xC0);
- rv |= main_write8(chgnum, 0x80, 0x01);
- rv |= main_write8(chgnum, 0x1A, 0x08);
-
- rv |= meas_write8(chgnum, 0x08, 0xC2);
-
- rv |= chg_write8(chgnum, 0x1D, 0x40);
-
- rv |= chg_write8(chgnum, 0x22, 0xB3);
-
- rv |= chg_write8(chgnum, 0x3E, 0x3C);
-
- rv |= chg_write8(chgnum, 0x4F, 0xBF);
-
- rv |= chg_write8(chgnum, 0x52, 0x77);
- rv |= chg_write8(chgnum, 0x53, 0xD2);
- rv |= chg_write8(chgnum, 0x54, 0x02);
- rv |= chg_write8(chgnum, 0x55, 0xD1);
- rv |= chg_write8(chgnum, 0x56, 0x7F);
- rv |= chg_write8(chgnum, 0x57, 0x01);
- rv |= chg_write8(chgnum, 0x58, 0x50);
- rv |= chg_write8(chgnum, 0x59, 0x7F);
- rv |= chg_write8(chgnum, 0x5A, 0x13);
- rv |= chg_write8(chgnum, 0x5B, 0x52);
- rv |= chg_write8(chgnum, 0x5D, 0xD0);
-
- rv |= chg_write8(chgnum, 0x60, 0x44);
- rv |= chg_write8(chgnum, 0x65, 0x35);
- rv |= chg_write8(chgnum, 0x66, 0x29);
-
- rv |= chg_write8(chgnum, 0x7D, 0x97);
- rv |= chg_write8(chgnum, 0x7E, 0x07);
-
- rv |= chg_write8(chgnum, 0x33, 0x3C);
-
- rv |= chg_write8(chgnum, 0x5C, 0x7A);
- }
-
- rv |= chg_write8(chgnum, 0x73, 0x22);
- rv |= chg_write8(chgnum, 0x50, 0x88);
- rv |= chg_read8(chgnum, 0x34, &reg);
- reg |= BIT(7);
- rv |= chg_write8(chgnum, 0x34, reg);
- rv |= main_write8(chgnum, 0x1F, 0x1);
- rv |= test_write8(chgnum, 0x43, 0x10);
- rv |= test_write8(chgnum, 0x47, 0x10);
- rv |= test_write8(chgnum, 0x48, 0x04);
- rv |= main_write8(chgnum, 0x1F, 0x0);
- }
-
- /* Enable LDO bits */
- rv |= main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- reg &= ~(BIT(0) | BIT(1));
- rv |= main_write8(chgnum, SM5803_REG_REFERENCE, reg);
-
- /* Set a higher clock speed in case it was lowered for z-state */
- rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
- reg &= ~SM5803_CLOCK_SEL_LOW;
- rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
-
- /*
- * Turn on GPADCs to default. Enable the IBAT_CHG ADC in order to
- * measure battery current and calculate system resistance.
- */
- reg = SM5803_GPADCC1_TINT_EN |
- SM5803_GPADCC1_VSYS_EN |
- SM5803_GPADCC1_VCHGPWR_EN |
- SM5803_GPADCC1_VBUS_EN |
- SM5803_GPADCC1_IBAT_CHG_EN |
- SM5803_GPADCC1_IBAT_DIS_EN |
- SM5803_GPADCC1_VBATSNSP_EN;
- rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG1, reg);
-
- /* Enable Psys DAC */
- rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
- reg |= SM5803_PSYS1_DAC_EN;
- rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
-
- /* Enable ADC sigma delta */
- rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
- reg |= SM5803_CC_CONFIG1_SD_PWRUP;
- rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
-
- /* Enable PROCHOT comparators except Ibus */
- rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
- reg |= SM5803_PHOT1_COMPARATOR_EN;
- reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN;
- rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
-
- /* Set DPM Voltage to 4200 mv, see b:172173517 */
- reg = SM5803_VOLTAGE_TO_REG(4200);
- rv = chg_write8(chgnum, SM5803_REG_DPM_VL_SET_MSB, (reg >> 3));
- rv |= chg_write8(chgnum, SM5803_REG_DPM_VL_SET_LSB, (reg & 0x7));
-
- /* Set default input current */
- reg = SM5803_CURRENT_TO_REG(CONFIG_CHARGER_INPUT_CURRENT)
- & SM5803_CHG_ILIM_RAW;
- rv |= chg_write8(chgnum, SM5803_REG_CHG_ILIM, reg);
-
- /* Configure charger insertion interrupts */
- rv |= main_write8(chgnum, SM5803_REG_INT1_EN, SM5803_INT1_CHG);
- /* Enable end of charge interrupts for logging */
- rv |= main_write8(chgnum, SM5803_REG_INT4_EN, SM5803_INT4_CHG_FAIL |
- SM5803_INT4_CHG_DONE |
- SM5803_INT4_OTG_FAIL);
-
- /* Set TINT interrupts for higher threshold 360 K */
- rv |= meas_write8(chgnum, SM5803_REG_TINT_HIGH_TH,
- SM5803_TINT_HIGH_LEVEL);
- /*
- * Set TINT interrupts for lower threshold to 0 when not
- * throttled to prevent trigger interrupts continually
- */
- rv |= meas_write8(chgnum, SM5803_REG_TINT_LOW_TH,
- SM5803_TINT_MIN_LEVEL);
-
- /*
- * Configure VBAT_SNSP high interrupt to fire after thresholds are set.
- */
- rv |= main_read8(chgnum, SM5803_REG_INT2_EN, &reg);
- reg |= SM5803_INT2_VBATSNSP;
- rv |= main_write8(chgnum, SM5803_REG_INT2_EN, reg);
-
-
- /* Configure TINT interrupts to fire after thresholds are set */
- rv |= main_write8(chgnum, SM5803_REG_INT2_EN, SM5803_INT2_TINT);
-
- /*
- * Configure CHG_ENABLE to only be set through I2C by setting
- * HOST_MODE_EN bit (all other register bits are 0 by default)
- */
- rv |= chg_write8(chgnum, SM5803_REG_FLOW2, SM5803_FLOW2_HOST_MODE_EN);
-
- if (chgnum == CHARGER_PRIMARY) {
- int ibat_eoc_ma;
-
- /* Set end of fast charge threshold */
- batt_info = battery_get_info();
- ibat_eoc_ma = batt_info->precharge_current - 50;
- ibat_eoc_ma /= 100;
- ibat_eoc_ma = CLAMP(ibat_eoc_ma, 0, SM5803_CONF5_IBAT_EOC_TH);
- rv |= chg_read8(chgnum, SM5803_REG_FAST_CONF5, &reg);
- reg &= ~SM5803_CONF5_IBAT_EOC_TH;
- reg |= ibat_eoc_ma;
- rv |= chg_write8(CHARGER_PRIMARY, SM5803_REG_FAST_CONF5, reg);
-
- /* Setup the proper precharge thresholds. */
- cells = batt_info->voltage_max / 4;
- pre_term = batt_info->voltage_min / cells;
- pre_term /= 100; /* Convert to decivolts. */
- pre_term = CLAMP(pre_term, SM5803_VBAT_PRE_TERM_MIN_DV,
- SM5803_VBAT_PRE_TERM_MAX_DV);
- pre_term -= SM5803_VBAT_PRE_TERM_MIN_DV; /* Convert to regval */
-
- rv |= chg_read8(chgnum, SM5803_REG_PRE_FAST_CONF_REG1, &reg);
- reg &= ~SM5803_VBAT_PRE_TERM;
- reg |= pre_term << SM5803_VBAT_PRE_TERM_SHIFT;
- rv |= chg_write8(chgnum, SM5803_REG_PRE_FAST_CONF_REG1, reg);
-
- /*
- * Set up precharge current
- * Note it is preferred to under-shoot the precharge current
- * requested. Upper bits of this register are read/write 1 to
- * clear
- */
- reg = SM5803_CURRENT_TO_REG(batt_info->precharge_current);
- reg = MIN(reg, SM5803_PRECHG_ICHG_PRE_SET);
- rv |= chg_write8(chgnum, SM5803_REG_PRECHG, reg);
-
- /*
- * Set up BFET alerts
- *
- * We'll set the soft limit at 1.5W and the hard limit at 6W.
- *
- * The register is 29.2 mW per bit.
- */
- reg = (1500 * 10) / 292;
- rv |= meas_write8(chgnum, SM5803_REG_BFET_PWR_MAX_TH, reg);
- reg = (6000 * 10) / 292;
- rv |= meas_write8(chgnum, SM5803_REG_BFET_PWR_HWSAFE_MAX_TH,
- reg);
- rv |= main_read8(chgnum, SM5803_REG_INT3_EN, &reg);
- reg |= SM5803_INT3_BFET_PWR_LIMIT |
- SM5803_INT3_BFET_PWR_HWSAFE_LIMIT;
- rv |= main_write8(chgnum, SM5803_REG_INT3_EN, reg);
-
- rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &reg);
- reg &= ~SM5803_FLOW3_SWITCH_BCK_BST;
- rv |= chg_write8(chgnum, SM5803_REG_FLOW3, reg);
-
- rv |= chg_read8(chgnum, SM5803_REG_SWITCHER_CONF, &reg);
- reg |= SM5803_SW_BCK_BST_CONF_AUTO;
- rv |= chg_write8(chgnum, SM5803_REG_SWITCHER_CONF, reg);
- }
-
- if (rv)
- CPRINTS("%s %d: Failed initialization", CHARGER_NAME, chgnum);
- else
- chip_inited[chgnum] = true;
-}
-
-static enum ec_error_list sm5803_post_init(int chgnum)
-{
- /* Nothing to do, charger is always powered */
- return EC_SUCCESS;
-}
-
-void sm5803_hibernate(int chgnum)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
- chgnum);
- return;
- }
-
- /* Disable LDO bits - note the primary LDO should not be disabled */
- if (chgnum != CHARGER_PRIMARY) {
- reg |= (BIT(0) | BIT(1));
- rv |= main_write8(chgnum, SM5803_REG_REFERENCE, reg);
- }
-
- /* Slow the clock speed */
- rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
- reg |= SM5803_CLOCK_SEL_LOW;
- rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
-
- /* Turn off GPADCs */
- rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG1, 0);
- rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG2, 0);
-
- /* Disable Psys DAC */
- rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
- reg &= ~SM5803_PSYS1_DAC_EN;
- rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
-
- /* Disable ADC sigma delta */
- rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
- reg &= ~SM5803_CC_CONFIG1_SD_PWRUP;
- rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
-
- /* Disable PROCHOT comparators */
- rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
- reg &= ~SM5803_PHOT1_COMPARATOR_EN;
- rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
-
- if (rv)
- CPRINTS("%s %d: Failed to set hibernate", CHARGER_NAME, chgnum);
-}
-
-static void sm5803_disable_runtime_low_power_mode(void)
-{
- enum ec_error_list rv;
- int reg;
- int chgnum = TASK_ID_TO_PD_PORT(task_get_current());
-
- CPRINTS("%s %d: disable runtime low power mode", CHARGER_NAME, chgnum);
- rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
- chgnum);
- return;
- }
- /* Set a higher clock speed */
- rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
- reg &= ~SM5803_CLOCK_SEL_LOW;
- rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
-
- /* Enable ADC sigma delta */
- rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
- reg |= SM5803_CC_CONFIG1_SD_PWRUP;
- rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
-
- if (rv)
- CPRINTS("%s %d: Failed to set in disable runtime LPM",
- CHARGER_NAME, chgnum);
-}
-DECLARE_HOOK(HOOK_USB_PD_CONNECT,
- sm5803_disable_runtime_low_power_mode,
- HOOK_PRIO_FIRST);
-
-static enum ec_error_list sm5803_enable_linear_charge(int chgnum, bool enable)
-{
- int rv;
- int regval;
- const struct battery_info *batt_info;
-
- if (enable) {
- /*
- * We need to wait for the BFET enable attempt to complete,
- * otherwise we may end up disabling linear charge.
- */
- if (!attempt_bfet_enable)
- return EC_ERROR_TRY_AGAIN;
- rv = main_write8(chgnum, 0x1F, 0x1);
- rv |= test_write8(chgnum, 0x44, 0x20);
- rv |= main_write8(chgnum, 0x1F, 0);
-
- /*
- * Precharge thresholds have already been set up as a part of
- * init, however set fast charge current equal to the precharge
- * current in case the battery moves beyond that threshold.
- */
- batt_info = battery_get_info();
- rv |= sm5803_set_current(CHARGER_PRIMARY,
- batt_info->precharge_current);
-
- /* Enable linear charge mode. */
- rv |= sm5803_flow1_update(chgnum,
- SM5803_FLOW1_LINEAR_CHARGE_EN,
- MASK_SET);
- rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &regval);
- regval |= BIT(6) | BIT(5) | BIT(4);
- rv |= chg_write8(chgnum, SM5803_REG_FLOW3, regval);
- } else {
- rv = sm5803_flow1_update(chgnum,
- SM5803_FLOW1_LINEAR_CHARGE_EN,
- MASK_CLR);
- rv |= sm5803_flow2_update(chgnum,
- SM5803_FLOW2_AUTO_ENABLED,
- MASK_CLR);
- rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &regval);
- regval &= ~(BIT(6) | BIT(5) | BIT(4) |
- SM5803_FLOW3_SWITCH_BCK_BST);
- rv |= chg_write8(chgnum, SM5803_REG_FLOW3, regval);
- rv |= chg_read8(chgnum, SM5803_REG_SWITCHER_CONF, &regval);
- regval |= SM5803_SW_BCK_BST_CONF_AUTO;
- rv |= chg_write8(chgnum, SM5803_REG_SWITCHER_CONF, regval);
- }
-
- return rv;
-}
-
-static void sm5803_enable_runtime_low_power_mode(void)
-{
- enum ec_error_list rv;
- int reg;
- int chgnum = TASK_ID_TO_PD_PORT(task_get_current());
-
- CPRINTS("%s %d: enable runtime low power mode", CHARGER_NAME, chgnum);
- rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
- chgnum);
- return;
- }
- /* Slow the clock speed */
- rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
- reg |= SM5803_CLOCK_SEL_LOW;
- rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
-
- /* Disable ADC sigma delta */
- rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
- reg &= ~SM5803_CC_CONFIG1_SD_PWRUP;
- rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
-
- /* If the system is off, all PROCHOT comparators may be turned off */
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF |
- CHIPSET_STATE_ANY_SUSPEND)) {
- rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
- reg &= ~SM5803_PHOT1_COMPARATOR_EN;
- rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
- }
-
- if (rv)
- CPRINTS("%s %d: Failed to set in enable runtime LPM",
- CHARGER_NAME, chgnum);
-}
-DECLARE_HOOK(HOOK_USB_PD_DISCONNECT,
- sm5803_enable_runtime_low_power_mode,
- HOOK_PRIO_LAST);
-
-void sm5803_disable_low_power_mode(int chgnum)
-{
- enum ec_error_list rv;
- int reg;
-
- CPRINTS("%s %d: disable low power mode", CHARGER_NAME, chgnum);
- rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
- chgnum);
- return;
- }
- /* Enable Psys DAC */
- rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
- reg |= SM5803_PSYS1_DAC_EN;
- rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
-
- /* Enable PROCHOT comparators except Ibus */
- rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
- reg |= SM5803_PHOT1_COMPARATOR_EN;
- reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN;
- rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
-
- if (rv)
- CPRINTS("%s %d: Failed to set in disable low power mode",
- CHARGER_NAME, chgnum);
-}
-
-void sm5803_enable_low_power_mode(int chgnum)
-{
- enum ec_error_list rv;
- int reg;
-
- CPRINTS("%s %d: enable low power mode", CHARGER_NAME, chgnum);
- rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
- chgnum);
- return;
- }
- /* Disable Psys DAC */
- rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
- reg &= ~SM5803_PSYS1_DAC_EN;
- rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
-
- /*
- * Disable all PROCHOT comparators only if port is inactive. Vbus
- * sourcing requires that the Vbus comparator be enabled, and it
- * cannot be enabled from HOOK_USB_PD_CONNECT since that is
- * called after Vbus has turned on.
- */
- rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
- reg &= ~SM5803_PHOT1_COMPARATOR_EN;
- if (pd_is_connected(chgnum))
- reg |= SM5803_PHOT1_VBUS_MON_EN;
- rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
-
-
- if (rv)
- CPRINTS("%s %d: Failed to set in enable low power mode",
- CHARGER_NAME, chgnum);
-}
-
-/*
- * Restart charging on the active port, if it's still active and it hasn't
- * exceeded our maximum number of restarts.
- */
-void sm5803_restart_charging(void)
-{
- int act_chg = charge_manager_get_active_charge_port();
- timestamp_t now = get_time();
-
- if (act_chg == active_restart_port) {
- if (timestamp_expired(failure_tracker[act_chg].time, &now)) {
- /*
- * Enough time has passed since our last failure,
- * restart the timing and count from now.
- */
- failure_tracker[act_chg].time.val = now.val +
- CHARGING_FAILURE_INTERVAL;
- failure_tracker[act_chg].count = 1;
-
- sm5803_vbus_sink_enable(act_chg, 1);
- } else if (++failure_tracker[act_chg].count >
- CHARGING_FAILURE_MAX_COUNT) {
- CPRINTS("%s %d: Exceeded charging failure retries",
- CHARGER_NAME, act_chg);
- } else {
- sm5803_vbus_sink_enable(act_chg, 1);
- }
- }
-
- active_restart_port = CHARGE_PORT_NONE;
-}
-DECLARE_DEFERRED(sm5803_restart_charging);
-
-/*
- * Process interrupt registers and report any Vbus changes. Alert the AP if the
- * charger has become too hot.
- */
-void sm5803_handle_interrupt(int chgnum)
-{
- enum ec_error_list rv;
- int int_reg, meas_reg;
- static bool throttled;
- struct batt_params bp;
- int act_chg, val;
-
- /* Note: Interrupt registers are clear on read */
- rv = main_read8(chgnum, SM5803_REG_INT1_REQ, &int_reg);
- if (rv) {
- CPRINTS("%s %d: Failed read int1 register", CHARGER_NAME,
- chgnum);
- return;
- }
-
- if (int_reg & SM5803_INT1_CHG) {
- rv = main_read8(chgnum, SM5803_REG_STATUS1, &meas_reg);
- if (!(meas_reg & SM5803_STATUS1_CHG_DET)) {
- charger_vbus[chgnum] = 0;
- if (IS_ENABLED(CONFIG_USB_CHARGER))
- usb_charger_vbus_change(chgnum, 0);
- } else {
- charger_vbus[chgnum] = 1;
- if (IS_ENABLED(CONFIG_USB_CHARGER))
- usb_charger_vbus_change(chgnum, 1);
- }
- board_check_extpower();
- }
-
- rv = main_read8(chgnum, SM5803_REG_INT2_REQ, &int_reg);
- if (rv) {
- CPRINTS("%s %d: Failed read int2 register", CHARGER_NAME,
- chgnum);
- return;
- }
-
- if (int_reg & SM5803_INT2_TINT) {
- rv = meas_read8(chgnum, SM5803_REG_TINT_MEAS_MSB, &meas_reg);
- if ((meas_reg <= SM5803_TINT_LOW_LEVEL) && throttled) {
- throttled = false;
- throttle_ap(THROTTLE_OFF, THROTTLE_HARD,
- THROTTLE_SRC_THERMAL);
- /*
- * Set back higher threshold to 360 K and set lower
- * threshold to 0.
- */
- rv |= meas_write8(chgnum, SM5803_REG_TINT_LOW_TH,
- SM5803_TINT_MIN_LEVEL);
- rv |= meas_write8(chgnum, SM5803_REG_TINT_HIGH_TH,
- SM5803_TINT_HIGH_LEVEL);
- } else if (meas_reg >= SM5803_TINT_HIGH_LEVEL) {
- throttled = true;
- throttle_ap(THROTTLE_ON, THROTTLE_HARD,
- THROTTLE_SRC_THERMAL);
- /*
- * Set back lower threshold to 330 K and set higher
- * threshold to maximum.
- */
- rv |= meas_write8(chgnum, SM5803_REG_TINT_HIGH_TH,
- SM5803_TINT_MAX_LEVEL);
- rv |= meas_write8(chgnum, SM5803_REG_TINT_LOW_TH,
- SM5803_TINT_LOW_LEVEL);
- }
- /*
- * If the interrupt came in and we're not currently throttling
- * or the level is below the upper threshold, it can likely be
- * ignored.
- */
- }
-
- if (int_reg & SM5803_INT2_VBATSNSP) {
- int meas_volt;
- uint32_t platform_id;
-
- rv = main_read8(chgnum, SM5803_REG_PLATFORM, &platform_id);
- if (rv) {
- CPRINTS("%s %d: Failed to read platform in interrupt",
- CHARGER_NAME, chgnum);
- return;
- }
- platform_id &= SM5803_PLATFORM_ID;
- act_chg = charge_manager_get_active_charge_port();
- rv = meas_read8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MEAS_MSB,
- &meas_reg);
- if (rv)
- return;
- meas_volt = meas_reg << 2;
- rv = meas_read8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MEAS_LSB,
- &meas_reg);
- if (rv)
- return;
- meas_volt |= meas_reg & 0x03;
- rv = meas_read8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MAX_TH, &meas_reg);
- if (rv)
- return;
-
- if (is_platform_id_2s(platform_id)) {
- /* 2S Battery */
- CPRINTS("%s %d : VBAT_SNSP_HIGH_TH: %d mV ! - "
- "VBAT %d mV",
- CHARGER_NAME, CHARGER_PRIMARY,
- meas_reg * 408/10,
- meas_volt * 102/10);
- }
-
- if (is_platform_id_3s(platform_id)) {
- /* 3S Battery */
- CPRINTS("%s %d : VBAT_SNSP_HIGH_TH: %d mV ! "
- "- VBAT %d mV",
- CHARGER_NAME, CHARGER_PRIMARY,
- meas_reg * 616/10,
- meas_volt * 154/10);
- }
-
- /* Set Vbat Threshold to Max value to re-arm the interrupt */
- rv = meas_write8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MAX_TH, 0xFF);
-
- /* Disable battery charge */
- rv |= sm5803_flow1_update(chgnum, CHARGER_MODE_DISABLED,
- MASK_CLR);
- if (is_platform_id_2s(platform_id)) {
- /* 2S battery: set VBAT_SENSP TH 9V */
- rv |= meas_write8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MAX_TH,
- SM5803_VBAT_SNSP_MAXTH_2S_LEVEL);
- }
- if (is_platform_id_3s(platform_id)) {
- /* 3S battery: set VBAT_SENSP TH 13.3V */
- rv |= meas_write8(CHARGER_PRIMARY,
- SM5803_REG_VBATSNSP_MAX_TH,
- SM5803_VBAT_SNSP_MAXTH_3S_LEVEL);
- }
-
- active_restart_port = act_chg;
- hook_call_deferred(&sm5803_restart_charging_data, 1 * SECOND);
- }
-
- /* TODO(b/159376384): Take action on fatal BFET power alert. */
- rv = main_read8(chgnum, SM5803_REG_INT3_REQ, &int_reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read int3 register", CHARGER_NAME,
- chgnum);
- return;
- }
-
- if ((int_reg & SM5803_INT3_BFET_PWR_LIMIT) ||
- (int_reg & SM5803_INT3_BFET_PWR_HWSAFE_LIMIT)) {
- battery_get_params(&bp);
- act_chg = charge_manager_get_active_charge_port();
- CPRINTS("%s BFET power limit reached! (%s)", CHARGER_NAME,
- (int_reg & SM5803_INT3_BFET_PWR_LIMIT) ? "warn" :
- "FATAL");
- CPRINTS("\tVbat: %dmV", bp.voltage);
- CPRINTS("\tIbat: %dmA", bp.current);
- charger_get_voltage(act_chg, &val);
- CPRINTS("\tVsys(aux): %dmV", val);
- charger_get_current(act_chg, &val);
- CPRINTS("\tIsys: %dmA", val);
- cflush();
- }
-
- rv = main_read8(chgnum, SM5803_REG_INT4_REQ, &int_reg);
- if (rv) {
- CPRINTS("%s %d: Failed to read int4 register", CHARGER_NAME,
- chgnum);
- return;
- }
-
- if (int_reg & SM5803_INT4_CHG_FAIL) {
- int status_reg;
-
- act_chg = charge_manager_get_active_charge_port();
- chg_read8(chgnum, SM5803_REG_STATUS_CHG_REG, &status_reg);
- CPRINTS("%s %d: CHG_FAIL_INT fired. Status 0x%02x",
- CHARGER_NAME, chgnum, status_reg);
-
- /* Write 1 to clear status interrupts */
- chg_write8(chgnum, SM5803_REG_STATUS_CHG_REG, status_reg);
-
- /*
- * If a survivable fault happened, re-start sinking on the
- * active charger after an appropriate delay.
- */
- if (status_reg & SM5803_STATUS_CHG_OV_ITEMP) {
- active_restart_port = act_chg;
- hook_call_deferred(&sm5803_restart_charging_data,
- 30 * SECOND);
- } else if ((status_reg & SM5803_STATUS_CHG_OV_VBAT) &&
- act_chg == CHARGER_PRIMARY) {
- active_restart_port = act_chg;
- hook_call_deferred(&sm5803_restart_charging_data,
- 1 * SECOND);
- }
- }
-
- if (int_reg & SM5803_INT4_CHG_DONE)
- CPRINTS("%s %d: CHG_DONE_INT fired!!!", CHARGER_NAME, chgnum);
-
- if (int_reg & SM5803_INT4_OTG_FAIL) {
- int status_reg;
-
- /*
- * Gather status to detect if this was overcurrent
- *
- * Note: a status of 0 with this interrupt also indicates an
- * overcurrent (see b/170517117)
- */
- chg_read8(chgnum, SM5803_REG_STATUS_DISCHG, &status_reg);
- CPRINTS("%s %d: OTG_FAIL_INT fired. Status 0x%02x",
- CHARGER_NAME, chgnum, status_reg);
- if ((status_reg == 0) ||
- (status_reg == SM5803_STATUS_DISCHG_VBUS_SHORT)) {
- pd_handle_overcurrent(chgnum);
- }
-
- /*
- * Clear source mode here when status is 0, since OTG disable
- * will detect us as sinking in this failure case.
- */
- if (status_reg == 0)
- rv = sm5803_flow1_update(chgnum, CHARGER_MODE_SOURCE |
- SM5803_FLOW1_DIRECTCHG_SRC_EN,
- MASK_CLR);
- }
-
-}
-
-static void sm5803_irq_deferred(void)
-{
- int i;
- uint32_t pending = atomic_clear(&irq_pending);
-
- for (i = 0; i < CHARGER_NUM; i++)
- if (BIT(i) & pending)
- sm5803_handle_interrupt(i);
-}
-DECLARE_DEFERRED(sm5803_irq_deferred);
-
-void sm5803_interrupt(int chgnum)
-{
- atomic_or(&irq_pending, BIT(chgnum));
- hook_call_deferred(&sm5803_irq_deferred_data, 0);
-}
-
-static enum ec_error_list sm5803_get_dev_id(int chgnum, int *id)
-{
- int rv = EC_SUCCESS;
-
- if (dev_id == UNKNOWN_DEV_ID)
- rv = main_read8(chgnum, SM5803_REG_CHIP_ID, &dev_id);
-
- if (!rv)
- *id = dev_id;
-
- return rv;
-
-}
-
-static const struct charger_info *sm5803_get_info(int chgnum)
-{
- return &sm5803_charger_info;
-}
-
-static enum ec_error_list sm5803_get_status(int chgnum, int *status)
-{
- enum ec_error_list rv;
- int reg;
-
- /* Charger obeys smart battery requests - making it level 2 */
- *status = CHARGER_LEVEL_2;
-
- rv = chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
- if (rv)
- return rv;
-
-
- if ((reg & SM5803_FLOW1_MODE) == CHARGER_MODE_DISABLED &&
- !(reg & SM5803_FLOW1_LINEAR_CHARGE_EN))
- *status |= CHARGER_CHARGE_INHIBITED;
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_set_mode(int chgnum, int mode)
-{
- enum ec_error_list rv = EC_SUCCESS;
-
- if (mode & CHARGE_FLAG_INHIBIT_CHARGE) {
- rv = sm5803_flow1_update(chgnum, 0xFF, MASK_CLR);
- rv |= sm5803_flow2_update(chgnum, SM5803_FLOW2_AUTO_ENABLED,
- MASK_CLR);
- }
-
- return rv;
-}
-
-static enum ec_error_list sm5803_get_actual_current(int chgnum, int *current)
-{
- enum ec_error_list rv;
- int reg;
- int curr;
-
- rv = meas_read8(chgnum, SM5803_REG_IBAT_CHG_AVG_MEAS_MSB, &reg);
- if (rv)
- return rv;
- curr = reg << 2;
-
- rv = meas_read8(chgnum, SM5803_REG_IBAT_CHG_AVG_MEAS_LSB, &reg);
- if (rv)
- return rv;
- curr |= reg & SM5803_IBAT_CHG_MEAS_LSB;
-
- /* The LSB is 7.32mA */
- *current = curr * 732 / 100;
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_get_current(int chgnum, int *current)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_FAST_CONF4, &reg);
- if (rv)
- return rv;
-
- reg &= SM5803_CONF4_ICHG_FAST;
- *current = SM5803_REG_TO_CURRENT(reg);
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_set_current(int chgnum, int current)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_FAST_CONF4, &reg);
- if (rv)
- return rv;
-
- reg &= ~SM5803_CONF4_ICHG_FAST;
- reg |= SM5803_CURRENT_TO_REG(current);
-
- rv = chg_write8(chgnum, SM5803_REG_FAST_CONF4, reg);
- return rv;
-}
-
-static enum ec_error_list sm5803_get_actual_voltage(int chgnum, int *voltage)
-{
- enum ec_error_list rv;
- int reg;
- int volt_bits;
-
- rv = meas_read8(chgnum, SM5803_REG_VSYS_AVG_MEAS_MSB, &reg);
- if (rv)
- return rv;
- volt_bits = reg << 2;
-
- rv = meas_read8(chgnum, SM5803_REG_VSYS_AVG_MEAS_LSB, &reg);
- if (rv)
- return rv;
- volt_bits |= reg & 0x3;
-
- /* The LSB is 23.4mV */
- *voltage = volt_bits * 234 / 10;
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_get_voltage(int chgnum, int *voltage)
-{
- enum ec_error_list rv;
- int regval;
- int v;
-
- rv = chg_read8(chgnum, SM5803_REG_VBAT_FAST_MSB, &regval);
- v = regval << 3;
- rv |= chg_read8(chgnum, SM5803_REG_VBAT_FAST_LSB, &regval);
- v |= (regval & 0x3);
-
- *voltage = SM5803_REG_TO_VOLTAGE(v);
-
- if (rv)
- return EC_ERROR_UNKNOWN;
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_set_voltage(int chgnum, int voltage)
-{
- enum ec_error_list rv;
- int regval;
-
- regval = SM5803_VOLTAGE_TO_REG(voltage);
-
- /*
- * Note: Set both voltages on both chargers. Vbat will only be used on
- * primary, which enables charging.
- */
- rv = chg_write8(chgnum, SM5803_REG_VSYS_PREREG_MSB, (regval >> 3));
- rv |= chg_write8(chgnum, SM5803_REG_VSYS_PREREG_LSB, (regval & 0x7));
- rv |= chg_write8(chgnum, SM5803_REG_VBAT_FAST_MSB, (regval >> 3));
- rv |= chg_write8(chgnum, SM5803_REG_VBAT_FAST_LSB, (regval & 0x7));
-
- /* Once battery is connected, set up fast charge enable */
- if (fast_charge_disabled && chgnum == CHARGER_PRIMARY &&
- battery_get_disconnect_state() == BATTERY_NOT_DISCONNECTED) {
- rv = sm5803_flow2_update(chgnum,
- SM5803_FLOW2_AUTO_ENABLED,
- MASK_SET);
- fast_charge_disabled = false;
- }
-
- if (IS_ENABLED(CONFIG_OCPC) && chgnum != CHARGER_PRIMARY) {
- /*
- * Check to see if the BFET is enabled. If not, enable it by
- * toggling linear mode on the primary charger. The BFET can be
- * disabled if the system is powered up from an auxiliary charge
- * port and the battery is dead.
- */
- rv |= chg_read8(CHARGER_PRIMARY, SM5803_REG_LOG1, &regval);
- if (!(regval & SM5803_BATFET_ON) && !attempt_bfet_enable) {
- CPRINTS("SM5803: Attempting to turn on BFET");
- cflush();
- rv |= sm5803_flow1_update(CHARGER_PRIMARY,
- SM5803_FLOW1_LINEAR_CHARGE_EN,
- MASK_SET);
- rv |= sm5803_flow1_update(CHARGER_PRIMARY,
- SM5803_FLOW1_LINEAR_CHARGE_EN,
- MASK_CLR);
- attempt_bfet_enable = 1;
- sm5803_vbus_sink_enable(chgnum, 1);
- }
- /* There's no need to attempt it if the BFET's already on. */
- if (regval & SM5803_BATFET_ON)
- attempt_bfet_enable = 1;
- }
-
- return rv;
-}
-
-static enum ec_error_list sm5803_discharge_on_ac(int chgnum, int enable)
-{
- enum ec_error_list rv = EC_SUCCESS;
-
- if (enable) {
- rv = sm5803_vbus_sink_enable(chgnum, 0);
- } else {
- if (chgnum == charge_manager_get_active_charge_port())
- rv = sm5803_vbus_sink_enable(chgnum, 1);
- }
-
- return rv;
-}
-
-static enum ec_error_list sm5803_get_vbus_voltage(int chgnum, int port,
- int *voltage)
-{
- enum ec_error_list rv;
- int reg;
- int volt_bits;
-
- rv = meas_read8(chgnum, SM5803_REG_VBUS_MEAS_MSB, &reg);
- if (rv)
- return rv;
-
- volt_bits = reg << 2;
-
- rv = meas_read8(chgnum, SM5803_REG_VBUS_MEAS_LSB, &reg);
-
- volt_bits |= reg & SM5803_VBUS_MEAS_LSB;
-
- /* Vbus ADC is in 23.4 mV steps */
- *voltage = (volt_bits * 234) / 10;
- return rv;
-}
-
-static enum ec_error_list sm5803_set_input_current_limit(int chgnum,
- int input_current)
-{
- int reg;
-
- reg = SM5803_CURRENT_TO_REG(input_current) & SM5803_CHG_ILIM_RAW;
-
- return chg_write8(chgnum, SM5803_REG_CHG_ILIM, reg);
-}
-
-static enum ec_error_list sm5803_get_input_current_limit(int chgnum,
- int *input_current)
-{
- int rv;
- int val;
-
- rv = chg_read8(chgnum, SM5803_REG_CHG_ILIM, &val);
- if (rv)
- return rv;
-
- *input_current = SM5803_REG_TO_CURRENT(val & SM5803_CHG_ILIM_RAW);
- return rv;
-}
-
-static enum ec_error_list sm5803_get_input_current(int chgnum,
- int *input_current)
-{
- enum ec_error_list rv;
- int reg;
- int curr;
-
- rv = meas_read8(chgnum, SM5803_REG_IBUS_CHG_MEAS_MSB, &reg);
- if (rv)
- return rv;
- curr = reg << 2;
-
- rv = meas_read8(chgnum, SM5803_REG_IBUS_CHG_MEAS_LSB, &reg);
- if (rv)
- return rv;
- curr |= reg & 0x3;
-
- /* The LSB is 7.32mA */
- *input_current = curr * 732 / 100;
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_get_option(int chgnum, int *option)
-{
- enum ec_error_list rv;
- uint32_t control;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
- control = reg;
-
- rv |= chg_read8(chgnum, SM5803_REG_FLOW2, &reg);
- control |= reg << 8;
-
- rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &reg);
- control |= reg << 16;
-
- return rv;
-}
-
-enum ec_error_list sm5803_is_acok(int chgnum, bool *acok)
-{
- int rv;
- int reg, vbus_mv;
-
- rv = main_read8(chgnum, SM5803_REG_STATUS1, &reg);
-
- if (rv)
- return rv;
-
- /* If we're not sinking, then AC can't be OK. */
- if (!(reg & SM5803_STATUS1_CHG_DET)) {
- *acok = false;
- return EC_SUCCESS;
- }
-
- /*
- * Okay, we're sinking. Check that VBUS has some voltage. This
- * should indicate that the path is good.
- */
- rv = charger_get_vbus_voltage(chgnum, &vbus_mv);
-
- if (rv)
- return rv;
-
- /* Assume that ACOK would be asserted if VBUS is higher than ~4V. */
- *acok = vbus_mv >= 4000;
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_is_input_current_limit_reached(int chgnum,
- bool *reached)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_LOG2, &reg);
- if (rv)
- return rv;
-
- *reached = (reg & SM5803_ISOLOOP_ON) ? true : false;
-
- return EC_SUCCESS;
-}
-
-static enum ec_error_list sm5803_set_option(int chgnum, int option)
-{
- enum ec_error_list rv;
- int reg;
-
- mutex_lock(&flow1_access_lock[chgnum]);
-
- reg = option & 0xFF;
- rv = chg_write8(chgnum, SM5803_REG_FLOW1, reg);
-
- mutex_unlock(&flow1_access_lock[chgnum]);
- if (rv)
- return rv;
-
- reg = (option >> 8) & 0xFF;
- rv = chg_write8(chgnum, SM5803_REG_FLOW2, reg);
- if (rv)
- return rv;
-
- reg = (option >> 16) & 0xFF;
- rv = chg_write8(chgnum, SM5803_REG_FLOW3, reg);
-
- return rv;
-}
-
-static enum ec_error_list sm5803_set_otg_current_voltage(int chgnum,
- int output_current,
- int output_voltage)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_DISCH_CONF5, &reg);
- if (rv)
- return rv;
-
- reg &= ~SM5803_DISCH_CONF5_CLS_LIMIT;
- reg |= MIN((output_current / SM5803_CLS_CURRENT_STEP),
- SM5803_DISCH_CONF5_CLS_LIMIT);
- rv |= chg_write8(chgnum, SM5803_REG_DISCH_CONF5, reg);
-
- reg = SM5803_VOLTAGE_TO_REG(output_voltage);
- rv = chg_write8(chgnum, SM5803_REG_VPWR_MSB, (reg >> 3));
- rv |= chg_write8(chgnum, SM5803_REG_DISCH_CONF2,
- reg & SM5803_DISCH_CONF5_VPWR_LSB);
-
- return rv;
-}
-
-static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled)
-{
- enum ec_error_list rv;
- int reg, status;
-
- if (enabled) {
- int selected_current;
-
- rv = chg_read8(chgnum, SM5803_REG_ANA_EN1, &reg);
- if (rv)
- return rv;
-
- /* Enable current limit */
- reg &= ~SM5803_ANA_EN1_CLS_DISABLE;
- rv = chg_write8(chgnum, SM5803_REG_ANA_EN1, reg);
-
- /* Disable ramps on current set in discharge */
- rv |= chg_read8(chgnum, SM5803_REG_DISCH_CONF6, &reg);
- reg |= SM5803_DISCH_CONF6_RAMPS_DIS;
- rv |= chg_write8(chgnum, SM5803_REG_DISCH_CONF6, reg);
-
- /*
- * In order to ensure the Vbus output doesn't overshoot too
- * much, turn the starting voltage down to 4.8 V and ramp up
- * after 4 ms
- */
- rv = chg_read8(chgnum, SM5803_REG_DISCH_CONF5, &reg);
- if (rv)
- return rv;
-
- selected_current = (reg & SM5803_DISCH_CONF5_CLS_LIMIT) *
- SM5803_CLS_CURRENT_STEP;
- sm5803_set_otg_current_voltage(chgnum, selected_current, 4800);
-
- /*
- * Enable: SOURCE_MODE - enable sourcing out
- * DIRECTCHG_SOURCE_EN - enable current loop
- * (for designs with no external Vbus FET)
- */
- rv = sm5803_flow1_update(chgnum, CHARGER_MODE_SOURCE |
- SM5803_FLOW1_DIRECTCHG_SRC_EN,
- MASK_SET);
- usleep(4000);
-
- sm5803_set_otg_current_voltage(chgnum, selected_current, 5000);
- } else {
- /* Always clear out discharge status before clearing FLOW1 */
- rv = chg_read8(chgnum, SM5803_REG_STATUS_DISCHG, &status);
- if (rv)
- return rv;
-
- if (status)
- CPRINTS("%s %d: Discharge failure 0x%02x", CHARGER_NAME,
- chgnum, status);
-
- rv |= chg_write8(chgnum, SM5803_REG_STATUS_DISCHG, status);
-
- /* Re-enable ramps on current set in discharge */
- rv |= chg_read8(chgnum, SM5803_REG_DISCH_CONF6, &reg);
- reg &= ~SM5803_DISCH_CONF6_RAMPS_DIS;
- rv |= chg_write8(chgnum, SM5803_REG_DISCH_CONF6, reg);
-
- /*
- * PD tasks will always turn off previous sourcing on init.
- * Protect ourselves from brown out on init by checking if we're
- * sinking right now. The init process should only leave sink
- * mode enabled if a charger is plugged in; otherwise it's
- * expected to be 0.
- *
- * Always clear out sourcing if the previous source-out failed.
- */
- rv |= chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
- if (rv)
- return rv;
-
- if ((reg & SM5803_FLOW1_MODE) != CHARGER_MODE_SINK || status)
- rv = sm5803_flow1_update(chgnum, CHARGER_MODE_SOURCE |
- SM5803_FLOW1_DIRECTCHG_SRC_EN,
- MASK_CLR);
- }
-
- return rv;
-}
-
-static int sm5803_is_sourcing_otg_power(int chgnum, int port)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
- if (rv)
- return 0;
-
- /*
- * Note: In linear mode, MB charger will read a reserved mode when
- * sourcing, so bit 1 is the most reliable way to detect sourcing.
- */
- return (reg & BIT(1));
-}
-
-static enum ec_error_list sm5803_set_vsys_compensation(int chgnum,
- struct ocpc_data *ocpc,
- int current_ma,
- int voltage_mv)
-{
-
- int rv;
- int regval;
- int r;
-
- /* Set IR drop compensation */
- r = ocpc->combined_rsys_rbatt_mo * 100 / 167; /* 1.67mOhm steps */
- r = MAX(0, r);
- rv = chg_write8(chgnum, SM5803_REG_IR_COMP2, r & 0x7F);
- rv |= chg_read8(chgnum, SM5803_REG_IR_COMP1, &regval);
- regval &= ~SM5803_IR_COMP_RES_SET_MSB;
- r = r >> 8; /* Bits 9:8 */
- regval |= (r & 0x3) << SM5803_IR_COMP_RES_SET_MSB_SHIFT;
- regval |= SM5803_IR_COMP_EN;
- rv |= chg_write8(chgnum, SM5803_REG_IR_COMP1, regval);
-
- if (rv)
- return EC_ERROR_UNKNOWN;
-
- return EC_ERROR_UNIMPLEMENTED;
-}
-
-/* Hardware current ramping (aka DPM: Dynamic Power Management) */
-
-#ifdef CONFIG_CHARGE_RAMP_HW
-static enum ec_error_list sm5803_set_hw_ramp(int chgnum, int enable)
-{
- enum ec_error_list rv;
- int reg;
-
- rv = chg_read8(chgnum, SM5803_REG_CHG_MON_REG, &reg);
-
- if (enable)
- reg |= SM5803_DPM_LOOP_EN;
- else
- reg &= ~SM5803_DPM_LOOP_EN;
-
- rv |= chg_write8(chgnum, SM5803_REG_CHG_MON_REG, reg);
-
- return rv;
-}
-
-static int sm5803_ramp_is_stable(int chgnum)
-{
- /*
- * There is no way to read current limit that the ramp has
- * settled on with sm5803, so we don't consider the ramp stable,
- * because we never know what the stable limit is.
- */
- return 0;
-}
-
-static int sm5803_ramp_is_detected(int chgnum)
-{
- return 1;
-}
-
-static int sm5803_ramp_get_current_limit(int chgnum)
-{
- int rv;
- int input_current = 0;
-
- rv = sm5803_get_input_current_limit(chgnum, &input_current);
-
- return rv ? -1 : input_current;
-}
-#endif /* CONFIG_CHARGE_RAMP_HW */
-
-#ifdef CONFIG_CMD_CHARGER_DUMP
-static int command_sm5803_dump(int argc, char **argv)
-{
- int reg;
- int regval;
- int chgnum = 0;
-
- if (argc > 1)
- chgnum = atoi(argv[1]);
-
- /* Dump base regs */
- ccprintf("BASE regs\n");
- for (reg = 0x01; reg <= 0x30; reg++) {
- if (!main_read8(chgnum, reg, &regval))
- ccprintf("[0x%02X] = 0x%02x\n", reg, regval);
- if (reg & 0xf) {
- cflush(); /* Flush periodically */
- watchdog_reload();
- }
- }
-
- /* Dump measure regs */
- ccprintf("MEAS regs\n");
- for (reg = 0x01; reg <= 0xED; reg++) {
- if (!meas_read8(chgnum, reg, &regval))
- ccprintf("[0x%02X] = 0x%02x\n", reg, regval);
- if (reg & 0xf) {
- cflush(); /* Flush periodically */
- watchdog_reload();
- }
- }
-
- /* Dump Charger regs from 0x1C to 0x7F */
- ccprintf("CHG regs\n");
- for (reg = 0x1C; reg <= 0x7F; reg++) {
- if (!chg_read8(chgnum, reg, &regval))
- ccprintf("[0x%02X] = 0x%02x\n", reg, regval);
- if (reg & 0xf) {
- cflush(); /* Flush periodically */
- watchdog_reload();
- }
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(charger_dump, command_sm5803_dump,
- "charger_dump [chgnum]", "Dumps SM5803 registers");
-#endif /* CONFIG_CMD_CHARGER_DUMP */
-
-const struct charger_drv sm5803_drv = {
- .init = &sm5803_init,
- .post_init = &sm5803_post_init,
- .get_info = &sm5803_get_info,
- .get_status = &sm5803_get_status,
- .set_mode = &sm5803_set_mode,
- .get_actual_current = &sm5803_get_actual_current,
- .get_current = &sm5803_get_current,
- .set_current = &sm5803_set_current,
- .get_actual_voltage = &sm5803_get_actual_voltage,
- .get_voltage = &sm5803_get_voltage,
- .set_voltage = &sm5803_set_voltage,
- .discharge_on_ac = &sm5803_discharge_on_ac,
- .get_vbus_voltage = &sm5803_get_vbus_voltage,
- .set_input_current_limit = &sm5803_set_input_current_limit,
- .get_input_current_limit = &sm5803_get_input_current_limit,
- .get_input_current = &sm5803_get_input_current,
- .device_id = &sm5803_get_dev_id,
- .get_option = &sm5803_get_option,
- .set_option = &sm5803_set_option,
- .set_otg_current_voltage = &sm5803_set_otg_current_voltage,
- .enable_otg_power = &sm5803_enable_otg_power,
- .is_sourcing_otg_power = &sm5803_is_sourcing_otg_power,
- .set_vsys_compensation = &sm5803_set_vsys_compensation,
- .is_icl_reached = &sm5803_is_input_current_limit_reached,
- .enable_linear_charge = &sm5803_enable_linear_charge,
-#ifdef CONFIG_CHARGE_RAMP_HW
- .set_hw_ramp = &sm5803_set_hw_ramp,
- .ramp_is_stable = &sm5803_ramp_is_stable,
- .ramp_is_detected = &sm5803_ramp_is_detected,
- .ramp_get_current_limit = &sm5803_ramp_get_current_limit,
-#endif
-};