diff options
Diffstat (limited to 'driver/charger')
30 files changed, 0 insertions, 10241 deletions
diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c deleted file mode 100644 index 23303589b6..0000000000 --- a/driver/charger/bd9995x.c +++ /dev/null @@ -1,1674 +0,0 @@ -/* Copyright 2016 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. - * - * ROHM BD9995X battery charger driver. - */ - -#include "battery.h" -#include "battery_smart.h" -#include "bd9995x.h" -#include "charge_manager.h" -#include "charge_state.h" -#include "charger.h" -#include "console.h" -#include "ec_commands.h" -#include "hooks.h" -#include "i2c.h" -#include "task.h" -#include "time.h" -#include "util.h" -#include "usb_charge.h" -#include "usb_pd.h" - -#define OTPROM_LOAD_WAIT_RETRY 3 - -#define BD9995X_CHARGE_PORT_COUNT 2 - -/* - * BC1.2 detection starts 100ms after VBUS/VCC attach and typically - * completes 312ms after VBUS/VCC attach. - */ -#define BC12_DETECT_US (312*MSEC) -#define BD9995X_VSYS_PRECHARGE_OFFSET_MV 200 - -/* Console output macros */ -#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) - -#ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT -/* - * Used in a check to determine if VBUS is within the - * range of some VOLTAGE +/- VBUS_DELTA, where voltage - * is measured in mV. - */ -#define VBUS_DELTA 1000 - -/* VBUS is debounced if it's stable for this length of time */ -#define VBUS_MSEC (100*MSEC) - -/* VBUS debouncing sample interval */ -#define VBUS_CHECK_MSEC (10*MSEC) - -/* Time to wait before VBUS debouncing begins */ -#define STABLE_TIMEOUT (500*MSEC) - -/* Maximum time to wait until VBUS is debounced */ -#define DEBOUNCE_TIMEOUT (500*MSEC) - -enum vstate {START, STABLE, DEBOUNCE}; -static enum vstate vbus_state; - -static int vbus_voltage; -static uint64_t debounce_time; -static uint64_t vbus_timeout; -static int port_update; -static int select_update; -static int select_input_port_update; -#endif - -/* Charger parameters */ -static const struct charger_info bd9995x_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, -}; - -/* Charge command code map */ -static enum bd9995x_command charger_map_cmd = BD9995X_INVALID_COMMAND; - -/* Mutex for active register set control. */ -static struct mutex bd9995x_map_mutex; - -/* Tracks the state of VSYS_PRIORITY */ -static int vsys_priority; -/* Mutex for VIN_CTRL_SET register */ -static struct mutex bd9995x_vin_mutex; - -#ifdef HAS_TASK_USB_CHG -/* USB switch */ -static enum usb_switch usb_switch_state[BD9995X_CHARGE_PORT_COUNT] = { - USB_SWITCH_DISCONNECT, - USB_SWITCH_DISCONNECT, -}; - -static int bd9995x_get_bc12_ilim(int charge_supplier) -{ - switch (charge_supplier) { - case CHARGE_SUPPLIER_BC12_CDP: - return 1500; - case CHARGE_SUPPLIER_BC12_DCP: - return 2000; - case CHARGE_SUPPLIER_BC12_SDP: - return 900; - case CHARGE_SUPPLIER_OTHER: -#ifdef CONFIG_CHARGE_RAMP_SW - return 2400; -#else - /* - * Setting the higher limit of current may result in an - * anti-collapse hence limiting the current to 1A. - */ - return 1000; -#endif - default: - return 500; - } -} -#endif /* HAS_TASK_USB_CHG */ - -static inline int ch_raw_read16(int cmd, int *param, - enum bd9995x_command map_cmd) -{ - int rv; - - /* Map the Charge command code to appropriate region */ - mutex_lock(&bd9995x_map_mutex); - if (charger_map_cmd != map_cmd) { - rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - BD9995X_CMD_MAP_SET, map_cmd); - if (rv) { - charger_map_cmd = BD9995X_INVALID_COMMAND; - goto bd9995x_read_cleanup; - } - - charger_map_cmd = map_cmd; - } - - rv = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - cmd, param); - -bd9995x_read_cleanup: - mutex_unlock(&bd9995x_map_mutex); - - return rv; -} - -static inline int ch_raw_write16(int cmd, int param, - enum bd9995x_command map_cmd) -{ - int rv; - - /* Map the Charge command code to appropriate region */ - mutex_lock(&bd9995x_map_mutex); - if (charger_map_cmd != map_cmd) { - rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - BD9995X_CMD_MAP_SET, map_cmd); - if (rv) { - charger_map_cmd = BD9995X_INVALID_COMMAND; - goto bd9995x_write_cleanup; - } - - charger_map_cmd = map_cmd; - } - - rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - cmd, param); - -bd9995x_write_cleanup: - mutex_unlock(&bd9995x_map_mutex); - - return rv; -} - -/* BD9995X local interfaces */ - -static int bd9995x_set_vfastchg(int voltage) -{ - - int rv; - - /* Fast Charge Voltage Regulation Settings for fast charging. */ - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET1, - voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - -#ifndef CONFIG_CHARGER_BATTERY_TSENSE - /* - * If TSENSE is not connected set all the VFASTCHG_REG_SETx - * to same voltage. - */ - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET2, - voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET3, - voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); -#endif - - return rv; -} - -static int bd9995x_set_vsysreg(int voltage) -{ - /* VSYS Regulation voltage is in 64mV steps. */ - voltage &= ~0x3F; - - return ch_raw_write16(BD9995X_CMD_VSYSREG_SET, voltage, - BD9995X_EXTENDED_COMMAND); -} - -static int bd9995x_is_discharging_on_ac(void) -{ - int reg; - - if (ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND)) - return 0; - - return !!(reg & BD9995X_CMD_CHGOP_SET2_BATT_LEARN); -} - -static int bd9995x_charger_enable(int enable) -{ - int rv, reg; - static int prev_chg_enable = -1; - const struct battery_info *bi = battery_get_info(); - -#ifdef CONFIG_CHARGER_BD9995X_CHGEN - /* - * If the battery is not yet initialized, dont turn-off the BGATE so - * that voltage from the AC is applied to the battery PACK. - */ - if (!enable && !board_battery_initialized()) - return EC_SUCCESS; -#endif - - /* Nothing to change */ - if (enable == prev_chg_enable) - return EC_SUCCESS; - - prev_chg_enable = enable; - - if (enable) { - /* - * BGATE capacitor max : 0.1uF + 20% - * Charge MOSFET threshold max : 2.8V - * BGATE charge pump current min : 3uA - * T = C * V / I so, Tmax = 112ms - */ - msleep(115); - - /* - * Set VSYSREG_SET <= VBAT so that the charger is in Fast-Charge - * state when charging. - */ - rv = bd9995x_set_vsysreg(bi->voltage_min); - } else { - /* - * Set VSYSREG_SET > VBAT so that the charger is in Pre-Charge - * state when not charging or discharging. - */ - rv = bd9995x_set_vsysreg(bi->voltage_max + - BD9995X_VSYS_PRECHARGE_OFFSET_MV); - - /* - * Allow charger in pre-charge state for 50ms before disabling - * the charger which prevents inrush current while moving from - * fast-charge state to pre-charge state. - */ - msleep(50); - } - if (rv) - return rv; - - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - if (enable) - reg |= BD9995X_CMD_CHGOP_SET2_CHG_EN; - else - reg &= ~BD9995X_CMD_CHGOP_SET2_CHG_EN; - - return ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, - BD9995X_EXTENDED_COMMAND); -} - -static int bd9995x_por_reset(void) -{ - int rv; - int reg; - int i; - - rv = ch_raw_write16(BD9995X_CMD_SYSTEM_CTRL_SET, - BD9995X_CMD_SYSTEM_CTRL_SET_OTPLD | - BD9995X_CMD_SYSTEM_CTRL_SET_ALLRST, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* Wait until OTPROM loading is finished */ - for (i = 0; i < OTPROM_LOAD_WAIT_RETRY; i++) { - msleep(10); - rv = ch_raw_read16(BD9995X_CMD_SYSTEM_STATUS, ®, - BD9995X_EXTENDED_COMMAND); - - if (!rv && (reg & BD9995X_CMD_SYSTEM_STATUS_OTPLD_STATE) && - (reg & BD9995X_CMD_SYSTEM_STATUS_ALLRST_STATE)) - break; - } - - if (rv) - return rv; - if (i == OTPROM_LOAD_WAIT_RETRY) - return EC_ERROR_TIMEOUT; - - return ch_raw_write16(BD9995X_CMD_SYSTEM_CTRL_SET, 0, - BD9995X_EXTENDED_COMMAND); -} - -static int bd9995x_reset_to_zero(void) -{ - int rv; - - rv = charger_set_current(0); - if (rv) - return rv; - - return charger_set_voltage(0); -} - -static int bd9995x_get_charger_op_status(int *status) -{ - return ch_raw_read16(BD9995X_CMD_CHGOP_STATUS, status, - BD9995X_EXTENDED_COMMAND); -} - -#ifdef HAS_TASK_USB_CHG -static int bc12_detected_type[CONFIG_USB_PD_PORT_MAX_COUNT]; -/* Mutex for UCD_SET regsiters, lock before read / mask / write. */ -static struct mutex ucd_set_mutex[BD9995X_CHARGE_PORT_COUNT]; - -static int bd9995x_get_bc12_device_type(int port) -{ - int rv; - int reg; - - rv = ch_raw_read16((port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_VBUS_UCD_STATUS : - BD9995X_CMD_VCC_UCD_STATUS, - ®, BD9995X_EXTENDED_COMMAND); - if (rv) - return CHARGE_SUPPLIER_NONE; - - switch (reg & BD9995X_TYPE_MASK) { - case BD9995X_TYPE_CDP: - return CHARGE_SUPPLIER_BC12_CDP; - case BD9995X_TYPE_DCP: - return CHARGE_SUPPLIER_BC12_DCP; - case BD9995X_TYPE_SDP: - return CHARGE_SUPPLIER_BC12_SDP; - case BD9995X_TYPE_PUP_PORT: - case BD9995X_TYPE_OTHER: - return CHARGE_SUPPLIER_OTHER; - case BD9995X_TYPE_OPEN_PORT: - case BD9995X_TYPE_VBUS_OPEN: - default: - return CHARGE_SUPPLIER_NONE; - } -} - -/* - * Do safe read / mask / write of BD9995X_CMD_*_UCD_SET register. - * The USB charger task owns all bits of this register, except for bit 0 - * (BD9995X_CMD_UCD_SET_USB_SW), which is controlled by - * usb_charger_set_switches(). - */ -static int bd9995x_update_ucd_set_reg(int port, uint16_t mask, int set) -{ - int rv; - int reg; - int port_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_VBUS_UCD_SET : BD9995X_CMD_VCC_UCD_SET; - - mutex_lock(&ucd_set_mutex[port]); - rv = ch_raw_read16(port_reg, ®, BD9995X_EXTENDED_COMMAND); - if (!rv) { - if (set) - reg |= mask; - else - reg &= ~mask; - - rv = ch_raw_write16(port_reg, reg, BD9995X_EXTENDED_COMMAND); - } - - mutex_unlock(&ucd_set_mutex[port]); - return rv; -} - -static int bd9995x_bc12_check_type(int port) -{ - int bc12_type; - struct charge_port_info charge; - int vbus_provided = bd9995x_is_vbus_provided(port) && - !usb_charger_port_is_sourcing_vbus(port); - - /* - * If vbus is no longer provided, then no need to continue. Return 0 so - * that a wait event is not scheduled. - */ - if (!vbus_provided) - return 0; - - /* get device type */ - bc12_type = bd9995x_get_bc12_device_type(port); - if (bc12_type == CHARGE_SUPPLIER_NONE) - /* - * Device type is not available, return non-zero so new wait - * will be scheduled before putting the task to sleep. - */ - return 1; - - bc12_detected_type[port] = bc12_type; - /* Update charge manager */ - charge.voltage = USB_CHARGER_VOLTAGE_MV; - charge.current = bd9995x_get_bc12_ilim(bc12_type); - charge_manager_update_charge(bc12_type, port, &charge); - - return 0; -} - -static void bd9995x_bc12_detach(int port, int type) -{ - /* Update charge manager */ - charge_manager_update_charge(type, port, NULL); - - /* Disable charging trigger by BC1.2 detection */ - bd9995x_bc12_enable_charging(port, 0); -} - -static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) -{ - int reg; - int rv; - int port_reg; - int mask_val; - - /* 1st Level Interrupt Setting */ - rv = ch_raw_read16(BD9995X_CMD_INT0_SET, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - mask_val = ((port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_INT0_SET_INT1_EN : - BD9995X_CMD_INT0_SET_INT2_EN) | - BD9995X_CMD_INT0_SET_INT0_EN; - if (enable) - reg |= mask_val; - else - reg &= ~mask_val; - - rv = ch_raw_write16(BD9995X_CMD_INT0_SET, reg, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* 2nd Level Interrupt Setting */ - port_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_INT1_SET : BD9995X_CMD_INT2_SET; - rv = ch_raw_read16(port_reg, ®, BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* Enable threshold interrupts if we need to control discharge */ -#ifdef CONFIG_USB_PD_DISCHARGE - mask_val = BD9995X_CMD_INT_VBUS_DET | BD9995X_CMD_INT_VBUS_TH; -#else - mask_val = BD9995X_CMD_INT_VBUS_DET; -#endif - if (enable) - reg |= mask_val; - else - reg &= ~mask_val; - - return ch_raw_write16(port_reg, reg, BD9995X_EXTENDED_COMMAND); -} - -/* Read + clear active interrupt bits for a given port */ -static int bd9995x_get_interrupts(int port) -{ - int rv; - int reg; - int port_reg; - - port_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_INT1_STATUS : BD9995X_CMD_INT2_STATUS; - - rv = ch_raw_read16(port_reg, ®, BD9995X_EXTENDED_COMMAND); - - if (rv) - return 0; - - /* Clear the interrupt status bits we just read */ - ch_raw_write16(port_reg, reg, BD9995X_EXTENDED_COMMAND); - - return reg; -} - -/* - * Set or clear registers necessary to do one-time BC1.2 detection. - * Pass enable = 1 to trigger BC1.2 detection, and enable = 0 once - * BC1.2 detection has completed. - */ -static int bd9995x_bc12_detect(int port, int enable) -{ - return bd9995x_update_ucd_set_reg(port, - BD9995X_CMD_UCD_SET_BCSRETRY | - BD9995X_CMD_UCD_SET_USBDETEN | - BD9995X_CMD_UCD_SET_USB_SW_EN, - enable); -} - -static int usb_charger_process(int port) -{ - int vbus_provided = bd9995x_is_vbus_provided(port) && - !usb_charger_port_is_sourcing_vbus(port); - - /* Inform other modules about VBUS level */ - usb_charger_vbus_change(port, vbus_provided); - - /* - * Do BC1.2 detection, if we have VBUS and our port is not known - * to speak PD. - */ - if (vbus_provided && !pd_capable(port)) { - bd9995x_bc12_detect(port, 1); - /* - * Need to give the charger time (~312 mSec) before the - * bc12_type is available. The main task loop will schedule a - * task wait event which will then call bd9995x_bc12_get_type. - */ - return 1; - } - - /* Reset BC1.2 regs so we don't do auto-detection. */ - bd9995x_bc12_detect(port, 0); - - /* - * VBUS is no longer being provided, if the bc12_type had been - * previously determined, then need to detach. - */ - if (bc12_detected_type[port] != CHARGE_SUPPLIER_NONE) { - /* Charger/sink detached */ - bd9995x_bc12_detach(port, bc12_detected_type[port]); - bc12_detected_type[port] = CHARGE_SUPPLIER_NONE; - } - /* No need for the task to schedule a wait event */ - return 0; -} - -#ifdef CONFIG_CHARGE_RAMP_SW -int usb_charger_ramp_allowed(int supplier) -{ - return supplier == CHARGE_SUPPLIER_BC12_DCP || - supplier == CHARGE_SUPPLIER_BC12_SDP || - supplier == CHARGE_SUPPLIER_BC12_CDP || - supplier == CHARGE_SUPPLIER_OTHER; -} - -int usb_charger_ramp_max(int supplier, int sup_curr) -{ - return bd9995x_get_bc12_ilim(supplier); -} -#endif /* CONFIG_CHARGE_RAMP_SW */ -#endif /* HAS_TASK_USB_CHG */ - -/* chip specific interfaces */ - -int charger_set_input_current(int input_current) -{ - int rv; - - /* Input current step 32 mA */ - input_current &= ~0x1F; - - if (input_current < bd9995x_charger_info.input_current_min) - input_current = bd9995x_charger_info.input_current_min; - - rv = ch_raw_write16(BD9995X_CMD_IBUS_LIM_SET, input_current, - BD9995X_BAT_CHG_COMMAND); - if (rv) - return rv; - - return ch_raw_write16(BD9995X_CMD_ICC_LIM_SET, input_current, - BD9995X_BAT_CHG_COMMAND); -} - -int charger_get_input_current(int *input_current) -{ - return ch_raw_read16(BD9995X_CMD_CUR_ILIM_VAL, input_current, - BD9995X_EXTENDED_COMMAND); -} - -int charger_manufacturer_id(int *id) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_device_id(int *id) -{ - return ch_raw_read16(BD9995X_CMD_CHIP_ID, id, BD9995X_EXTENDED_COMMAND); -} - -int charger_get_option(int *option) -{ - int rv; - int reg; - - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET1, option, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - *option |= reg << 16; - - return EC_SUCCESS; -} - -int charger_set_option(int option) -{ - int rv; - - rv = ch_raw_write16(BD9995X_CMD_CHGOP_SET1, option & 0xFFFF, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - return ch_raw_write16(BD9995X_CMD_CHGOP_SET2, (option >> 16) & 0xFFFF, - BD9995X_EXTENDED_COMMAND); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bd9995x_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int reg; - int ch_status; - - /* charger level */ - *status = CHARGER_LEVEL_2; - - /* charger enable/inhibit */ - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - if (!(reg & BD9995X_CMD_CHGOP_SET2_CHG_EN)) - *status |= CHARGER_CHARGE_INHIBITED; - - /* charger alarm enable/inhibit */ - rv = ch_raw_read16(BD9995X_CMD_PROCHOT_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - if (!(reg & (BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN4 | - BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN3 | - BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN2 | - BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN1 | - BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN0))) - *status |= CHARGER_ALARM_INHIBITED; - - rv = bd9995x_get_charger_op_status(®); - if (rv) - return rv; - - /* power fail */ - if (!(reg & BD9995X_CMD_CHGOP_STATUS_RBOOST_UV)) - *status |= CHARGER_POWER_FAIL; - - /* Safety signal ranges & battery presence */ - ch_status = (reg & BD9995X_BATTTEMP_MASK) >> 8; - - *status |= CHARGER_BATTERY_PRESENT; - - switch (ch_status) { - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_COLD1: - *status |= CHARGER_RES_COLD; - break; - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_COLD2: - *status |= CHARGER_RES_COLD; - *status |= CHARGER_RES_UR; - break; - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT1: - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT2: - *status |= CHARGER_RES_HOT; - break; - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT3: - *status |= CHARGER_RES_HOT; - *status |= CHARGER_RES_OR; - break; - case BD9995X_CMD_CHGOP_STATUS_BATTEMP_BATOPEN: - *status &= ~CHARGER_BATTERY_PRESENT; - default: - break; - } - - /* source of power */ - if (bd9995x_is_vbus_provided(BD9995X_CHARGE_PORT_BOTH)) - *status |= CHARGER_AC_PRESENT; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - - if (mode & CHARGE_FLAG_POR_RESET) { - rv = bd9995x_por_reset(); - if (rv) - return rv; - } - - if (mode & CHARGE_FLAG_RESET_TO_ZERO) { - rv = bd9995x_reset_to_zero(); - if (rv) - return rv; - } - - return EC_SUCCESS; -} - -int charger_get_current(int *current) -{ - return ch_raw_read16(BD9995X_CMD_CHG_CURRENT, current, - BD9995X_BAT_CHG_COMMAND); -} - -int charger_set_current(int current) -{ - int rv; - int chg_enable = 1; - - /* Charge current step 64 mA */ - current &= ~0x3F; - - if (current < BD9995X_NO_BATTERY_CHARGE_I_MIN && - (battery_is_present() != BP_YES || battery_is_cut_off())) - current = BD9995X_NO_BATTERY_CHARGE_I_MIN; - - /* - * Disable charger before setting charge current to 0 or when - * discharging on AC. - * If charging current is set to 0mA during charging, reference of - * the charge current feedback amp (VREF_CHG) is set to 0V. Hence - * the DCDC stops switching (because of the EA offset). - */ - if (!current || bd9995x_is_discharging_on_ac()) { - chg_enable = 0; - rv = bd9995x_charger_enable(0); - if (rv) - return rv; - } - - rv = ch_raw_write16(BD9995X_CMD_IPRECH_SET, - MIN(current, BD9995X_IPRECH_MAX), - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - rv = ch_raw_write16(BD9995X_CMD_CHG_CURRENT, current, - BD9995X_BAT_CHG_COMMAND); - if (rv) - return rv; - - /* - * Enable charger if charge current is non-zero or not discharging - * on AC. - */ - return chg_enable ? bd9995x_charger_enable(1) : EC_SUCCESS; -} - -int charger_get_voltage(int *voltage) -{ - if (vsys_priority) { - int batt_volt_measured; - int reg; - int rv; - - /* Get battery voltage as reported by charger */ - batt_volt_measured = bd9995x_get_battery_voltage(); - if (batt_volt_measured > (battery_get_info()->voltage_min + - BD9995X_VSYS_PRECHARGE_OFFSET_MV)) { - /* - * Battery is not deeply discharged. Clear the - * VSYS_PRIORITY bit to ensure that input current limit - * is always active. - */ - mutex_lock(&bd9995x_vin_mutex); - if (!ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND)) { - reg &= ~BD9995X_CMD_VIN_CTRL_SET_VSYS_PRIORITY; - rv = ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, - reg, - BD9995X_EXTENDED_COMMAND); - - /* Mirror the state of this bit */ - if (!rv) - vsys_priority = 0; - } - mutex_unlock(&bd9995x_vin_mutex); - } - } - - return ch_raw_read16(BD9995X_CMD_CHG_VOLTAGE, voltage, - BD9995X_BAT_CHG_COMMAND); -} - -int charger_set_voltage(int voltage) -{ - const int battery_voltage_max = battery_get_info()->voltage_max; - - /* - * Regulate the system voltage to battery max if the battery - * is not present or the battery is discharging on AC. - */ - if (voltage == 0 || - bd9995x_is_discharging_on_ac() || - battery_is_present() != BP_YES || - battery_is_cut_off() || - voltage > battery_voltage_max) - voltage = battery_voltage_max; - - /* Charge voltage step 16 mV */ - voltage &= ~0x0F; - - /* Assumes charger's voltage_min < battery's voltage_max */ - if (voltage < bd9995x_charger_info.voltage_min) - voltage = bd9995x_charger_info.voltage_min; - - return bd9995x_set_vfastchg(voltage); -} - -static void bd9995x_battery_charging_profile_settings(void) -{ - const struct battery_info *bi = battery_get_info(); - - /* Input Current Limit Setting */ - charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); - - /* Charge Termination Current Setting */ - ch_raw_write16(BD9995X_CMD_ITERM_SET, 0, BD9995X_EXTENDED_COMMAND); - - /* Trickle-charge Current Setting */ - ch_raw_write16(BD9995X_CMD_ITRICH_SET, - bi->precharge_current & 0x07C0, - BD9995X_EXTENDED_COMMAND); - - bd9995x_set_vfastchg(bi->voltage_max); - - /* Set Pre-charge Voltage Threshold for trickle charging. */ - ch_raw_write16(BD9995X_CMD_VPRECHG_TH_SET, - (bi->voltage_min - 1000) & 0x7FC0, - BD9995X_EXTENDED_COMMAND); - - /* Re-charge Battery Voltage Setting */ - ch_raw_write16(BD9995X_CMD_VRECHG_SET, - bi->voltage_max & 0x7FF0, - BD9995X_EXTENDED_COMMAND); - - /* Set battery OVP to 500 + maximum battery voltage */ - ch_raw_write16(BD9995X_CMD_VBATOVP_SET, - (bi->voltage_max + 500) & 0x7ff0, - BD9995X_EXTENDED_COMMAND); - - /* Reverse buck boost voltage Setting */ - ch_raw_write16(BD9995X_CMD_VRBOOST_SET, 0, - BD9995X_EXTENDED_COMMAND); - - /* Disable fast/pre-charging watchdog */ - ch_raw_write16(BD9995X_CMD_CHGWDT_SET, 0, - BD9995X_EXTENDED_COMMAND); - - /* TODO(crosbug.com/p/55626): Set VSYSVAL_THH/THL appropriately */ -} - -static void bd9995x_init(void) -{ - int reg; - - /* - * Disable charging trigger by BC1.2 on VCC & VBUS and - * automatic limitation of the input current. - */ - if (ch_raw_read16(BD9995X_CMD_CHGOP_SET1, ®, - BD9995X_EXTENDED_COMMAND)) - return; - reg |= (BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN | - BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG | - BD9995X_CMD_CHGOP_SET1_VBUS_BC_DISEN | - BD9995X_CMD_CHGOP_SET1_VCC_BC_DISEN | - BD9995X_CMD_CHGOP_SET1_ILIM_AUTO_DISEN | - BD9995X_CMD_CHGOP_SET1_SDP_500_SEL | - BD9995X_CMD_CHGOP_SET1_DCP_2500_SEL); - ch_raw_write16(BD9995X_CMD_CHGOP_SET1, reg, - BD9995X_EXTENDED_COMMAND); - - /* - * OTP setting for this register is 6.08V. Set VSYS to above battery max - * (as is done when charger is disabled) to ensure VSYSREG_SET > VBAT so - * that the charger is in Pre-Charge state and that the input current - * disable setting below will be active. - */ - bd9995x_set_vsysreg(battery_get_info()->voltage_max + - BD9995X_VSYS_PRECHARGE_OFFSET_MV); - - /* Enable BC1.2 USB charging and DC/DC converter @ 1200KHz */ - if (ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND)) - return; - reg &= ~(BD9995X_CMD_CHGOP_SET2_USB_SUS | - BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL); - reg |= BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL_1200; -#ifdef CONFIG_CHARGER_BD9995X_CHGEN - reg |= BD9995X_CMD_CHGOP_SET2_CHG_EN; -#endif - ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, - BD9995X_EXTENDED_COMMAND); - - /* - * We disable IADP (here before setting IBUS_LIM_SET and ICC_LIM_SET) - * to prevent voltage on IADP/RESET pin from affecting SEL_ILIM_VAL. - */ - if (ch_raw_read16(BD9995X_CMD_VM_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND)) - return; - reg &= ~BD9995X_CMD_VM_CTRL_SET_EXTIADPEN; - ch_raw_write16(BD9995X_CMD_VM_CTRL_SET, reg, BD9995X_EXTENDED_COMMAND); - /* - * Disable the input current limit when VBAT is < VSYSREG_SET. This - * needs to be done before calling - * bd9995x_battery_charging_profile_settings() as in that function the - * input current limit is set to CONFIG_CHARGER_INPUT_CURRENT which is - * 512 mA. In deeply discharged battery cases, setting the input current - * limit this low can cause VSYS to collapse, which in turn can cause - * the EC's brownout detector to reset the EC. - */ - if (ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND)) - return; - reg |= BD9995X_CMD_VIN_CTRL_SET_VSYS_PRIORITY; - ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg, - BD9995X_EXTENDED_COMMAND); - /* Mirror the state of this bit */ - vsys_priority = 1; - - /* Define battery charging profile */ - bd9995x_battery_charging_profile_settings(); - - /* Power save mode when VBUS/VCC is removed. */ -#ifdef CONFIG_BD9995X_POWER_SAVE_MODE - bd9995x_set_power_save_mode(CONFIG_BD9995X_POWER_SAVE_MODE); -#else - bd9995x_set_power_save_mode(BD9995X_PWR_SAVE_OFF); -#endif - -#ifdef CONFIG_USB_PD_DISCHARGE - /* Set VBUS / VCC detection threshold for discharge enable */ - ch_raw_write16(BD9995X_CMD_VBUS_TH_SET, BD9995X_VBUS_DISCHARGE_TH, - BD9995X_EXTENDED_COMMAND); - ch_raw_write16(BD9995X_CMD_VCC_TH_SET, BD9995X_VBUS_DISCHARGE_TH, - BD9995X_EXTENDED_COMMAND); -#endif - - /* Unlock debug regs */ - ch_raw_write16(BD9995X_CMD_PROTECT_SET, 0x3c, BD9995X_EXTENDED_COMMAND); - - /* Undocumented - reverse current threshold = -50mV */ - ch_raw_write16(0x14, 0x0202, BD9995X_DEBUG_COMMAND); - /* Undocumented - internal gain = 2x */ - ch_raw_write16(0x1a, 0x80, BD9995X_DEBUG_COMMAND); - - /* Re-lock debug regs */ - ch_raw_write16(BD9995X_CMD_PROTECT_SET, 0x0, BD9995X_EXTENDED_COMMAND); -} -DECLARE_HOOK(HOOK_INIT, bd9995x_init, HOOK_PRIO_INIT_EXTPOWER); - -int charger_post_init(void) -{ - return EC_SUCCESS; -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int reg; - - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* - * Suspend USB charging and DC/DC converter so that BATT_LEARN mode - * doesn't auto exit if VBAT < VSYSVAL_THL_SET and also it helps to - * discharge VBUS quickly when charging is not allowed and the AC - * is removed. - */ - if (enable) - reg |= BD9995X_CMD_CHGOP_SET2_BATT_LEARN | - BD9995X_CMD_CHGOP_SET2_USB_SUS; - else - reg &= ~(BD9995X_CMD_CHGOP_SET2_BATT_LEARN | - BD9995X_CMD_CHGOP_SET2_USB_SUS); - - return ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, - BD9995X_EXTENDED_COMMAND); -} - -int charger_get_vbus_voltage(int port) -{ - uint8_t read_reg; - int voltage; - - read_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? BD9995X_CMD_VBUS_VAL : - BD9995X_CMD_VCC_VAL; - - return ch_raw_read16(read_reg, &voltage, BD9995X_EXTENDED_COMMAND) ? - 0 : voltage; -} - -/*** Non-standard interface functions ***/ - -int bd9995x_is_vbus_provided(enum bd9995x_charge_port port) -{ - int reg; - - if (ch_raw_read16(BD9995X_CMD_VBUS_VCC_STATUS, ®, - BD9995X_EXTENDED_COMMAND)) - return 0; - - if (port == BD9995X_CHARGE_PORT_VBUS) - reg &= BD9995X_CMD_VBUS_VCC_STATUS_VBUS_DETECT; - else if (port == BD9995X_CHARGE_PORT_VCC) - reg &= BD9995X_CMD_VBUS_VCC_STATUS_VCC_DETECT; - else if (port == BD9995X_CHARGE_PORT_BOTH) { - /* Check VBUS on either port */ - reg &= (BD9995X_CMD_VBUS_VCC_STATUS_VCC_DETECT | - BD9995X_CMD_VBUS_VCC_STATUS_VBUS_DETECT); - } else - reg = 0; - - return !!reg; -} - -#ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT -static int bd9995x_select_input_port_private(enum bd9995x_charge_port port, - int select) -#else -int bd9995x_select_input_port(enum bd9995x_charge_port port, int select) -#endif -{ - int rv; - int reg; - - mutex_lock(&bd9995x_vin_mutex); - rv = ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - goto select_input_port_exit; - - if (select) { - if (port == BD9995X_CHARGE_PORT_VBUS) { - reg |= BD9995X_CMD_VIN_CTRL_SET_VBUS_EN; - reg &= ~BD9995X_CMD_VIN_CTRL_SET_VCC_EN; - } else if (port == BD9995X_CHARGE_PORT_VCC) { - reg |= BD9995X_CMD_VIN_CTRL_SET_VCC_EN; - reg &= ~BD9995X_CMD_VIN_CTRL_SET_VBUS_EN; - } else if (port == BD9995X_CHARGE_PORT_BOTH) { - /* Enable both the ports for PG3 */ - reg |= BD9995X_CMD_VIN_CTRL_SET_VBUS_EN | - BD9995X_CMD_VIN_CTRL_SET_VCC_EN; - } else { - /* Invalid charge port */ - panic("Invalid charge port"); - } - } else { - if (port == BD9995X_CHARGE_PORT_VBUS) - reg &= ~BD9995X_CMD_VIN_CTRL_SET_VBUS_EN; - else if (port == BD9995X_CHARGE_PORT_VCC) - reg &= ~BD9995X_CMD_VIN_CTRL_SET_VCC_EN; - else if (port == BD9995X_CHARGE_PORT_BOTH) - reg &= ~(BD9995X_CMD_VIN_CTRL_SET_VBUS_EN | - BD9995X_CMD_VIN_CTRL_SET_VCC_EN); - else - panic("Invalid charge port"); - } - - rv = ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg, - BD9995X_EXTENDED_COMMAND); -select_input_port_exit: - mutex_unlock(&bd9995x_vin_mutex); - return rv; -} - -#ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT -int bd9995x_select_input_port(enum bd9995x_charge_port port, int select) -{ - port_update = port; - select_update = select; - vbus_state = START; - select_input_port_update = 1; - task_wake(TASK_ID_USB_CHG); - - return EC_SUCCESS; -} - -static inline int bd9995x_vbus_test(int value, int limit) -{ - uint32_t hi_value = limit + VBUS_DELTA; - uint32_t lo_value = limit - VBUS_DELTA; - - return ((value > lo_value) && (value < hi_value)); -} - -static int bd9995x_vbus_debounce(enum bd9995x_charge_port port) -{ - int vbus_reg; - int voltage; - - vbus_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_VBUS_VAL : BD9995X_CMD_VCC_VAL; - if (ch_raw_read16(vbus_reg, &voltage, BD9995X_EXTENDED_COMMAND)) - voltage = 0; - - if (!bd9995x_vbus_test(voltage, vbus_voltage)) { - vbus_voltage = voltage; - debounce_time = get_time().val + VBUS_MSEC; - } else { - if (get_time().val >= debounce_time) - return 1; - } - - return 0; -} -#endif - - -#ifdef CONFIG_CHARGER_BATTERY_TSENSE -int bd9995x_get_battery_temp(int *temp_ptr) -{ - int rv; - - rv = ch_raw_read16(BD9995X_CMD_THERM_VAL, temp_ptr, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* Degrees C = 200 - THERM_VAL, range is -55C-200C, 1C steps */ - *temp_ptr = 200 - *temp_ptr; - return EC_SUCCESS; -} -#endif - -void bd9995x_set_power_save_mode(int mode) -{ - ch_raw_write16(BD9995X_CMD_SMBREG, mode, BD9995X_EXTENDED_COMMAND); -} - -int bd9995x_get_battery_voltage(void) -{ - int vbat_val, rv; - - rv = ch_raw_read16(BD9995X_CMD_VBAT_VAL, &vbat_val, - BD9995X_EXTENDED_COMMAND); - - return rv ? 0 : vbat_val; -} - -#ifdef HAS_TASK_USB_CHG -int bd9995x_bc12_enable_charging(int port, int enable) -{ - int rv; - int reg; - int mask_val; - - /* - * For BC1.2, enable VBUS/VCC_BC_DISEN charging trigger by BC1.2 - * detection and disable SDP_CHG_TRIG, SDP_CHG_TRIG_EN. Vice versa - * for USB-C. - */ - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET1, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - mask_val = (BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN | - BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG | - ((port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_CHGOP_SET1_VBUS_BC_DISEN : - BD9995X_CMD_CHGOP_SET1_VCC_BC_DISEN)); - - if (enable) - reg &= ~mask_val; - else - reg |= mask_val; - - return ch_raw_write16(BD9995X_CMD_CHGOP_SET1, reg, - BD9995X_EXTENDED_COMMAND); -} - -void usb_charger_set_switches(int port, enum usb_switch setting) -{ - /* If switch is not changing then return */ - if (setting == usb_switch_state[port]) - return; - - if (setting != USB_SWITCH_RESTORE) - usb_switch_state[port] = setting; - - /* ensure we disable power saving when we are using DP/DN */ -#ifdef CONFIG_BD9995X_POWER_SAVE_MODE - bd9995x_set_power_save_mode( - (usb_switch_state[0] == USB_SWITCH_DISCONNECT && - usb_switch_state[1] == USB_SWITCH_DISCONNECT) - ? CONFIG_BD9995X_POWER_SAVE_MODE : BD9995X_PWR_SAVE_OFF); -#endif - - bd9995x_update_ucd_set_reg(port, BD9995X_CMD_UCD_SET_USB_SW, - usb_switch_state[port] == USB_SWITCH_CONNECT); -} - -void bd9995x_vbus_interrupt(enum gpio_signal signal) -{ - task_wake(TASK_ID_USB_CHG); -} - -void usb_charger_task(void *u) -{ - static int initialized; - int changed, port, interrupts; - int sleep_usec; - uint64_t bc12_det_mark[CONFIG_USB_PD_PORT_MAX_COUNT]; -#ifdef CONFIG_USB_PD_DISCHARGE - int vbus_reg, voltage; -#endif - -#ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT - select_input_port_update = 0; - vbus_voltage = 0; -#endif - - for (port = 0; port < board_get_usb_pd_port_count(); port++) { - bc12_detected_type[port] = CHARGE_SUPPLIER_NONE; - bd9995x_enable_vbus_detect_interrupts(port, 1); - bc12_det_mark[port] = 0; - } - - while (1) { - sleep_usec = -1; - changed = 0; - for (port = 0; port < board_get_usb_pd_port_count(); port++) { - /* Get port interrupts */ - interrupts = bd9995x_get_interrupts(port); - if (interrupts & BD9995X_CMD_INT_VBUS_DET || - !initialized) { - /* - * Detect based on current state of VBUS. If - * VBUS is provided, then need to wait for - * bc12_type to be available. If VBUS is not - * provided, then disable wait for this port. - */ - bc12_det_mark[port] = usb_charger_process(port) - ? get_time().val + BC12_DETECT_US : 0; - changed = 1; - } -#ifdef CONFIG_USB_PD_DISCHARGE - if (interrupts & BD9995X_CMD_INT_VBUS_TH || - !initialized) { - /* Get VBUS voltage */ - vbus_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? - BD9995X_CMD_VBUS_VAL : - BD9995X_CMD_VCC_VAL; - if (ch_raw_read16(vbus_reg, - &voltage, - BD9995X_EXTENDED_COMMAND)) - voltage = 0; - - /* Set discharge accordingly */ - pd_set_vbus_discharge(port, - voltage < BD9995X_VBUS_DISCHARGE_TH); - changed = 1; - } -#endif - if (bc12_det_mark[port] && (get_time().val > - bc12_det_mark[port])) { - /* - * bc12_type result should be available. If not - * available still, then function will return - * 1. Set up additional 100 msec wait. Note that - * if VBUS is no longer provided when this call - * happens the funciton will return 0. - */ - bc12_det_mark[port] = - bd9995x_bc12_check_type(port) ? - get_time().val + 100 * MSEC : 0; - /* Reset BC1.2 regs to skip auto-detection. */ - bd9995x_bc12_detect(port, 0); - } - - /* - * Determine if a wait for reading bc12_type needs to be - * scheduled. Use the scheduled wait for this port if - * it's less than the wait needed for a previous - * port. If previous port(s) don't need a wait, then - * sleep_usec will be -1. - */ - if (bc12_det_mark[port]) { - int bc12_wait_usec; - - bc12_wait_usec = bc12_det_mark[port] - - get_time().val; - if ((sleep_usec < 0) || - (sleep_usec > bc12_wait_usec)) - sleep_usec = bc12_wait_usec; - } - } - - initialized = 1; -#ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT -/* - * When a charge port is selected and VBUS is 5V, the inrush current on some - * devices causes VBUS to droop, which could signal a sink disconnection. - * - * To mitigate the problem, charge port selection is delayed until VBUS - * is stable or one second has passed. Hopefully PD has negotiated a VBUS - * voltage of at least 9V before the one second timeout. - */ - if (select_input_port_update) { - sleep_usec = VBUS_CHECK_MSEC; - changed = 0; - - switch (vbus_state) { - case START: - vbus_timeout = get_time().val + STABLE_TIMEOUT; - vbus_state = STABLE; - break; - case STABLE: - if (get_time().val > vbus_timeout) { - vbus_state = DEBOUNCE; - vbus_timeout = get_time().val + - DEBOUNCE_TIMEOUT; - } - break; - case DEBOUNCE: - if (bd9995x_vbus_debounce(port_update) || - get_time().val > vbus_timeout) { - select_input_port_update = 0; - bd9995x_select_input_port_private( - port_update, select_update); - } - break; - } - } -#endif - - /* - * Re-read interrupt registers immediately if we got an - * interrupt. We're dealing with multiple independent - * interrupt sources and the interrupt pin may have - * never deasserted if both sources were not in clear - * state simultaneously. - */ - if (!changed) - task_wait_event(sleep_usec); - } -} -#endif /* HAS_TASK_USB_CHG */ - - -/*** Console commands ***/ -#ifdef CONFIG_CMD_CHARGER_DUMP -static int read_bat(uint8_t cmd) -{ - int read = 0; - - ch_raw_read16(cmd, &read, BD9995X_BAT_CHG_COMMAND); - return read; -} - -static int read_ext(uint8_t cmd) -{ - int read = 0; - - ch_raw_read16(cmd, &read, BD9995X_EXTENDED_COMMAND); - return read; -} - -/* Dump all readable registers on bd9995x */ -static int console_bd9995x_dump_regs(int argc, char **argv) -{ - int i; - uint8_t regs[] = { 0x14, 0x15, 0x3c, 0x3d, 0x3e, 0x3f }; - - /* Battery group registers */ - for (i = 0; i < ARRAY_SIZE(regs); ++i) - ccprintf("BAT REG %4x: %4x\n", regs[i], read_bat(regs[i])); - - /* Extended group registers */ - for (i = 0; i < 0x7f; ++i) { - ccprintf("EXT REG %4x: %4x\n", i, read_ext(i)); - cflush(); - } - - return 0; -} -DECLARE_CONSOLE_COMMAND(charger_dump, console_bd9995x_dump_regs, - NULL, - "Dump all charger registers"); -#endif /* CONFIG_CMD_CHARGER_DUMP */ - -#ifdef CONFIG_CMD_CHARGER -static int console_command_bd9995x(int argc, char **argv) -{ - int rv, reg, data, val; - char rw, *e; - enum bd9995x_command cmd; - - if (argc < 4) - return EC_ERROR_PARAM_COUNT; - - rw = argv[1][0]; - if (rw == 'w' && argc < 5) - return EC_ERROR_PARAM_COUNT; - else if (rw != 'w' && rw != 'r') - return EC_ERROR_PARAM1; - - reg = strtoi(argv[2], &e, 16); - if (*e || reg < 0) - return EC_ERROR_PARAM2; - - cmd = strtoi(argv[3], &e, 0); - if (*e || cmd < 0) - return EC_ERROR_PARAM3; - - if (rw == 'r') - rv = ch_raw_read16(reg, &data, cmd); - else { - val = strtoi(argv[4], &e, 16); - if (*e || val < 0) - return EC_ERROR_PARAM4; - - rv = ch_raw_write16(reg, val, cmd); - if (rv == EC_SUCCESS) - rv = ch_raw_read16(reg, &data, cmd); - } - - if (rv == EC_SUCCESS) - CPRINTS("register 0x%x [%d] = 0x%x [%d]", reg, reg, data, data); - - return rv; -} -DECLARE_CONSOLE_COMMAND(bd9995x, console_command_bd9995x, - "bd9995x <r/w> <reg_hex> <cmd_type> | <val_hex>", - "Read or write a charger register"); -#endif /* CONFIG_CMD_CHARGER */ - -#ifdef CONFIG_CHARGER_PSYS_READ -static int bd9995x_psys_charger_adc(void) -{ - int i; - int reg; - uint64_t ipmon = 0; - - for (i = 0; i < BD9995X_PMON_IOUT_ADC_READ_COUNT; i++) { - if (ch_raw_read16(BD9995X_CMD_PMON_DACIN_VAL, ®, - BD9995X_EXTENDED_COMMAND)) - return 0; - - /* Conversion Interval is 200us */ - usleep(200); - ipmon += reg; - } - - /* - * Calculate power in mW - * PSYS = VACP×IACP+VBAT×IBAT = IPMON / GPMON - */ - return (int) ((ipmon * 1000) / (BIT(BD9995X_PSYS_GAIN_SELECT) * - BD9995X_PMON_IOUT_ADC_READ_COUNT)); -} - -static int bd9995x_enable_psys(void) -{ - int rv; - int reg; - - rv = ch_raw_read16(BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* Enable PSYS & Select PSYS Gain */ - reg &= ~BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_MASK; - reg |= (BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_INSEL | - BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_OUT_EN | - BD9995X_PSYS_GAIN_SELECT); - - return ch_raw_write16(BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, - BD9995X_EXTENDED_COMMAND); -} - -/** - * Get system power. - * - * TODO(b:71520677): Implement charger_get_system_power, disable psys readout - * when not needed (the code below leaves it enabled after the first access), - * update "psys" console command to use charger_get_system_power and move it - * to some common code. - */ -static int console_command_psys(int argc, char **argv) -{ - int rv; - - rv = bd9995x_enable_psys(); - if (rv) - return rv; - - CPRINTS("PSYS from chg_adc: %d mW", - bd9995x_psys_charger_adc()); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(psys, console_command_psys, - NULL, - "Get the system power in mW"); -#endif /* CONFIG_CHARGER_PSYS_READ */ - -#ifdef CONFIG_CMD_CHARGER_ADC_AMON_BMON -static int bd9995x_amon_bmon_chg_adc(void) -{ - int i; - int reg; - int iout = 0; - - for (i = 0; i < BD9995X_PMON_IOUT_ADC_READ_COUNT; i++) { - ch_raw_read16(BD9995X_CMD_IOUT_DACIN_VAL, ®, - BD9995X_EXTENDED_COMMAND); - iout += reg; - - /* Conversion Interval is 200us */ - usleep(200); - } - - /* - * Discharge current in mA - * IDCHG = iout * GIDCHG - * IADP = iout * GIADP - * - * VIDCHG = GIDCHG * (VSRN- VSRP) = GIDCHG * IDCHG / IDCHG_RES - * VIADP = GIADP * (VACP- VACN) = GIADP * IADP / IADP_RES - */ - return (iout * (5 << BD9995X_IOUT_GAIN_SELECT)) / - (10 * BD9995X_PMON_IOUT_ADC_READ_COUNT); -} - -static int bd9995x_amon_bmon(int amon_bmon) -{ - int rv; - int reg; - int imon; - int sns_res; - - rv = ch_raw_read16(BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - /* Enable monitor */ - reg &= ~BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_MASK; - reg |= (BD9995X_CMD_PMON_IOUT_CTRL_SET_IMON_INSEL | - BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_OUT_EN | - (BD9995X_IOUT_GAIN_SELECT << 4)); - - if (amon_bmon) { - reg |= BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_SOURCE_SEL; - sns_res = CONFIG_CHARGER_SENSE_RESISTOR_AC; - } else { - reg &= ~BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_SOURCE_SEL; - sns_res = CONFIG_CHARGER_SENSE_RESISTOR; - } - - rv = ch_raw_write16(BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - - imon = bd9995x_amon_bmon_chg_adc(); - - CPRINTS("%cMON from chg_adc: %d uV, %d mA]", - amon_bmon ? 'A' : 'B', - imon * sns_res, - imon); - - return EC_SUCCESS; -} - -/** - * Get charger AMON and BMON current. - */ -static int console_command_amon_bmon(int argc, char **argv) -{ - int rv = EC_ERROR_PARAM1; - - /* Switch to AMON */ - if (argc == 1 || (argc >= 2 && argv[1][0] == 'a')) - rv = bd9995x_amon_bmon(1); - - /* Switch to BMON */ - if (argc == 1 || (argc >= 2 && argv[1][0] == 'b')) - rv = bd9995x_amon_bmon(0); - - return rv; -} -DECLARE_CONSOLE_COMMAND(amonbmon, console_command_amon_bmon, - "amonbmon [a|b]", - "Get charger AMON/BMON voltage diff, current"); -#endif /* CONFIG_CMD_CHARGER_ADC_AMON_BMON */ - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_CHARGER -static int bd9995x_i2c_read(const int reg, int *data) -{ - return ch_raw_read16(reg, data, BD9995X_EXTENDED_COMMAND); -} - -static int bd9995x_i2c_write(const int reg, int data) -{ - return ch_raw_write16(reg, data, BD9995X_EXTENDED_COMMAND); -} - -/* BD9995X_CMD_CHIP_ID register value may vary by chip. */ -struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev = { - .reg_info = { - .read_reg = BD9995X_CMD_CHIP_ID, - .read_val = BD99956_CHIP_ID, - .write_reg = BD9995X_CMD_ITRICH_SET, - }, - .i2c_read_dev = &bd9995x_i2c_read, - .i2c_write_dev = &bd9995x_i2c_write, -}; -#endif /* CONFIG_CMD_I2C_STRESS_TEST_CHARGER */ diff --git a/driver/charger/bd9995x.h b/driver/charger/bd9995x.h deleted file mode 100644 index 491f4bdeac..0000000000 --- a/driver/charger/bd9995x.h +++ /dev/null @@ -1,364 +0,0 @@ -/* Copyright 2016 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. - * - * ROHM BD9995X battery charger driver. - */ - -#ifndef __CROS_EC_BD9995X_H -#define __CROS_EC_BD9995X_H - -#define BD9995X_ADDR_FLAGS 0x09 -#define I2C_ADDR_CHARGER_FLAGS BD9995X_ADDR_FLAGS - -#define BD9995X_CHARGER_NAME "bd9995x" -#define BD99955_CHIP_ID 0x221 -#define BD99956_CHIP_ID 0x331 - -/* BD9995X commands to change the command code map */ -enum bd9995x_command { - BD9995X_BAT_CHG_COMMAND, - BD9995X_EXTENDED_COMMAND, - BD9995X_DEBUG_COMMAND, - BD9995X_INVALID_COMMAND -}; - -/* - * BD9995X has two external VBUS inputs (named VBUS and VCC) and two sets - * of registers / bits for control. This entire driver is written under the - * assumption that the physical VBUS port corresponds to PD port 0, and the - * physical VCC port corresponds to PD port 1. - */ -enum bd9995x_charge_port { - BD9995X_CHARGE_PORT_VBUS, - BD9995X_CHARGE_PORT_VCC, - BD9995X_CHARGE_PORT_BOTH, -}; - -/* Charger parameters */ -#define CHARGER_NAME BD9995X_CHARGER_NAME -#define CHARGE_V_MAX 19200 -#define CHARGE_V_MIN 3072 -#define CHARGE_V_STEP 16 -#define CHARGE_I_MAX 16320 -#define CHARGE_I_MIN 128 -#define CHARGE_I_OFF 0 -#define CHARGE_I_STEP 64 -#define INPUT_I_MAX 16352 -#define INPUT_I_MIN 512 -#define INPUT_I_STEP 32 - -/* Min. charge current w/ no battery to prevent collapse */ -#define BD9995X_NO_BATTERY_CHARGE_I_MIN 512 - -/* - * BC1.2 minimum voltage threshold. - * BC1.2 charging port output voltage range is 4.75V to 5.25V, - * BD9995X Anti-Collapse Threshold Voltage Accuracy is -100mV to +100mV, - * and Delta of 50mV. - */ -#define BD9995X_BC12_MIN_VOLTAGE 4600 - -/* Battery Charger Commands */ -#define BD9995X_CMD_CHG_CURRENT 0x14 -#define BD9995X_CMD_CHG_VOLTAGE 0x15 -#define BD9995X_CMD_IBUS_LIM_SET 0x3C -#define BD9995X_CMD_ICC_LIM_SET 0x3D -#define BD9995X_CMD_PROTECT_SET 0x3E -#define BD9995X_CMD_MAP_SET 0x3F - -/* Extended commands */ -#define BD9995X_CMD_CHGSTM_STATUS 0x00 -#define BD9995X_CMD_VBAT_VSYS_STATUS 0x01 -#define BD9995X_CMD_VBUS_VCC_STATUS 0x02 -#define BD9995X_CMD_VBUS_VCC_STATUS_VCC_DETECT BIT(8) -#define BD9995X_CMD_VBUS_VCC_STATUS_VBUS_DETECT BIT(0) - -#define BD9995X_CMD_CHGOP_STATUS 0x03 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP2 BIT(10) -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP1 BIT(9) -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP0 BIT(8) -#define BD9995X_BATTTEMP_MASK 0x700 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_ROOMTEMP 0 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT1 1 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT2 2 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_HOT3 3 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_COLD1 4 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_COLD2 5 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_DISABLE 6 -#define BD9995X_CMD_CHGOP_STATUS_BATTEMP_BATOPEN 7 -#define BD9995X_CMD_CHGOP_STATUS_RBOOST_UV BIT(1) - -#define BD9995X_CMD_WDT_STATUS 0x04 -#define BD9995X_CMD_CUR_ILIM_VAL 0x05 -#define BD9995X_CMD_SEL_ILIM_VAL 0x06 -#define BD9995X_CMD_EXT_IBUS_LIM_SET 0x07 -#define BD9995X_CMD_EXT_ICC_LIM_SET 0x08 -#define BD9995X_CMD_IOTG_LIM_SET 0x09 -#define BD9995X_CMD_VIN_CTRL_SET 0x0A -#define BD9995X_CMD_VIN_CTRL_SET_VSYS_PRIORITY BIT(4) - -#define BD9995X_CMD_VIN_CTRL_SET_PP_BOTH_THRU BIT(11) -#define BD9995X_CMD_VIN_CTRL_SET_VBUS_PRIORITY BIT(7) -#define BD9995X_CMD_VIN_CTRL_SET_VBUS_EN BIT(6) -#define BD9995X_CMD_VIN_CTRL_SET_VCC_EN BIT(5) - -#define BD9995X_CMD_CHGOP_SET1 0x0B -#define BD9995X_CMD_CHGOP_SET1_DCP_2500_SEL BIT(15) -#define BD9995X_CMD_CHGOP_SET1_SDP_500_SEL BIT(14) -#define BD9995X_CMD_CHGOP_SET1_ILIM_AUTO_DISEN BIT(13) -#define BD9995X_CMD_CHGOP_SET1_VCC_BC_DISEN BIT(11) -#define BD9995X_CMD_CHGOP_SET1_VBUS_BC_DISEN BIT(10) -#define BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN BIT(9) -#define BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG BIT(8) - -#define BD9995X_CMD_CHGOP_SET2 0x0C -#define BD9995X_CMD_CHGOP_SET2_BATT_LEARN BIT(8) -#define BD9995X_CMD_CHGOP_SET2_CHG_EN BIT(7) -#define BD9995X_CMD_CHGOP_SET2_USB_SUS BIT(6) -#define BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL (3 << 2) -#define BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL_600 (0 << 2) -#define BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL_857 BIT(2) -#define BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL_1000 (2 << 2) -#define BD9995X_CMD_CHGOP_SET2_DCDC_CLK_SEL_1200 (3 << 2) - -#define BD9995X_CMD_VBUSCLPS_TH_SET 0x0D -#define BD9995X_CMD_VCCCLPS_TH_SET 0x0E -#define BD9995X_CMD_CHGWDT_SET 0x0F -#define BD9995X_CMD_BATTWDT_SET 0x10 -#define BD9995X_CMD_VSYSREG_SET 0x11 -#define BD9995X_CMD_VSYSVAL_THH_SET 0x12 -#define BD9995X_CMD_VSYSVAL_THL_SET 0x13 -#define BD9995X_CMD_ITRICH_SET 0x14 - -#define BD9995X_CMD_IPRECH_SET 0x15 -#define BD9995X_IPRECH_MAX 1024 - -#define BD9995X_CMD_ICHG_SET 0x16 -#define BD9995X_CMD_ITERM_SET 0x17 -#define BD9995X_CMD_VPRECHG_TH_SET 0x18 -#define BD9995X_CMD_VRBOOST_SET 0x19 -#define BD9995X_CMD_VFASTCHG_REG_SET1 0x1A -#define BD9995X_CMD_VFASTCHG_REG_SET2 0x1B -#define BD9995X_CMD_VFASTCHG_REG_SET3 0x1C -#define BD9995X_CMD_VRECHG_SET 0x1D -#define BD9995X_CMD_VBATOVP_SET 0x1E -#define BD9995X_CMD_IBATSHORT_SET 0x1F -#define BD9995X_CMD_PROCHOT_CTRL_SET 0x20 -#define BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN4 BIT(4) -#define BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN3 BIT(3) -#define BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN2 BIT(2) -#define BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN1 BIT(1) -#define BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN0 BIT(0) - -#define BD9995X_CMD_PROCHOT_ICRIT_SET 0x21 -#define BD9995X_CMD_PROCHOT_INORM_SET 0x22 -#define BD9995X_CMD_PROCHOT_IDCHG_SET 0x23 -#define BD9995X_CMD_PROCHOT_VSYS_SET 0x24 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET 0x25 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IMON_INSEL BIT(9) -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_INSEL BIT(8) -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_OUT_EN BIT(7) -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_SOURCE_SEL BIT(6) -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_MASK 0x30 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_40V 0x03 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_20V 0x02 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_10V 0x01 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_IOUT_GAIN_SET_05V 0x00 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_OUT_EN BIT(3) -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_MASK 0x07 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_64UAW 0x06 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_32UAW 0x05 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_16UAW 0x04 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_08UAW 0x03 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_04UAW 0x02 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_02UAW 0x01 -#define BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_GAIN_SET_01UAW 0x00 -#define BD9995X_PMON_IOUT_ADC_READ_COUNT 128 - -#define BD9995X_CMD_PMON_DACIN_VAL 0x26 -#define BD9995X_CMD_IOUT_DACIN_VAL 0x27 -#define BD9995X_CMD_VCC_UCD_SET 0x28 -/* Bits for both VCC_UCD_SET and VBUS_UCD_SET regs */ -/* Retry BC1.2 detection on set */ -#define BD9995X_CMD_UCD_SET_BCSRETRY BIT(12) -/* Enable BC1.2 detection, will automatically occur on VBUS detect */ -#define BD9995X_CMD_UCD_SET_USBDETEN BIT(7) -/* USB switch state auto-control */ -#define BD9995X_CMD_UCD_SET_USB_SW_EN BIT(1) -/* USB switch state, 1 = ON, only meaningful when USB_SW_EN = 0 */ -#define BD9995X_CMD_UCD_SET_USB_SW BIT(0) - -#define BD9995X_CMD_VCC_UCD_STATUS 0x29 -/* Bits for both VCC_UCD_STATUS and VBUS_UCD_STATUS regs */ -#define BD9995X_CMD_UCD_STATUS_DCDFAIL BIT(15) -#define BD9995X_CMD_UCD_STATUS_CHGPORT1 BIT(13) -#define BD9995X_CMD_UCD_STATUS_CHGPORT0 BIT(12) -#define BD9995X_CMD_UCD_STATUS_PUPDET BIT(11) -#define BD9995X_CMD_UCD_STATUS_CHGDET BIT(6) -#define BD9995X_TYPE_MASK (BD9995X_CMD_UCD_STATUS_DCDFAIL | \ - BD9995X_CMD_UCD_STATUS_CHGPORT1 | \ - BD9995X_CMD_UCD_STATUS_CHGPORT0 | \ - BD9995X_CMD_UCD_STATUS_PUPDET | \ - BD9995X_CMD_UCD_STATUS_CHGDET) - -/* BC1.2 chargers */ -#define BD9995X_TYPE_CDP (BD9995X_CMD_UCD_STATUS_CHGPORT1 | \ - BD9995X_CMD_UCD_STATUS_CHGDET) -#define BD9995X_TYPE_DCP (BD9995X_CMD_UCD_STATUS_CHGPORT1 | \ - BD9995X_CMD_UCD_STATUS_CHGPORT0 | \ - BD9995X_CMD_UCD_STATUS_CHGDET) -#define BD9995X_TYPE_SDP (BD9995X_CMD_UCD_STATUS_CHGPORT0) -/* non-standard BC1.2 chargers */ -#define BD9995X_TYPE_OTHER (BD9995X_CMD_UCD_STATUS_DCDFAIL | \ - BD9995X_CMD_UCD_STATUS_CHGPORT1 | \ - BD9995X_CMD_UCD_STATUS_CHGPORT0 | \ - BD9995X_CMD_UCD_STATUS_CHGDET) -#define BD9995X_TYPE_PUP_PORT (BD9995X_CMD_UCD_STATUS_DCDFAIL | \ - BD9995X_CMD_UCD_STATUS_CHGPORT0 | \ - BD9995X_CMD_UCD_STATUS_PUPDET) -/* Open ports */ -#define BD9995X_TYPE_OPEN_PORT (BD9995X_CMD_UCD_STATUS_DCDFAIL | \ - BD9995X_CMD_UCD_STATUS_CHGPORT0) -#define BD9995X_TYPE_VBUS_OPEN 0 - -#define BD9995X_CMD_VCC_IDD_STATUS 0x2A -#define BD9995X_CMD_VCC_UCD_FCTRL_SET 0x2B -#define BD9995X_CMD_VCC_UCD_FCTRL_EN 0x2C -#define BD9995X_CMD_VBUS_UCD_SET 0x30 -#define BD9995X_CMD_VBUS_UCD_STATUS 0x31 -#define BD9995X_CMD_VBUS_IDD_STATUS 0x32 -#define BD9995X_CMD_VBUS_UCD_FCTRL_SET 0x33 -#define BD9995X_CMD_VBUS_UCD_FCTRL_EN 0x34 -#define BD9995X_CMD_CHIP_ID 0x38 -#define BD9995X_CMD_CHIP_REV 0x39 -#define BD9995X_CMD_IC_SET1 0x3A -#define BD9995X_CMD_IC_SET2 0x3B -#define BD9995X_CMD_SYSTEM_STATUS 0x3C -#define BD9995X_CMD_SYSTEM_STATUS_OTPLD_STATE BIT(1) -#define BD9995X_CMD_SYSTEM_STATUS_ALLRST_STATE BIT(0) - -#define BD9995X_CMD_SYSTEM_CTRL_SET 0x3D -#define BD9995X_CMD_SYSTEM_CTRL_SET_OTPLD BIT(1) -#define BD9995X_CMD_SYSTEM_CTRL_SET_ALLRST BIT(0) - -#define BD9995X_CMD_EXT_PROTECT_SET 0x3E -#define BD9995X_CMD_EXT_MAP_SET 0x3F -#define BD9995X_CMD_VM_CTRL_SET 0x40 -#define BD9995X_CMD_VM_CTRL_SET_EXTIADPEN BIT(9) -#define BD9995X_CMD_THERM_WINDOW_SET1 0x41 -#define BD9995X_CMD_THERM_WINDOW_SET2 0x42 -#define BD9995X_CMD_THERM_WINDOW_SET3 0x43 -#define BD9995X_CMD_THERM_WINDOW_SET4 0x44 -#define BD9995X_CMD_THERM_WINDOW_SET5 0x45 -#define BD9995X_CMD_IBATP_TH_SET 0x46 -#define BD9995X_CMD_IBATM_TH_SET 0x47 -#define BD9995X_CMD_VBAT_TH_SET 0x48 -#define BD9995X_CMD_THERM_TH_SET 0x49 -#define BD9995X_CMD_IACP_TH_SET 0x4A -#define BD9995X_CMD_VACP_TH_SET 0x4B - -/* Enable discharge when VBUS falls below BD9995X_VBUS_DISCHARGE_TH */ -#define BD9995X_VBUS_DISCHARGE_TH 3900 -#define BD9995X_CMD_VBUS_TH_SET 0x4C -#define BD9995X_CMD_VCC_TH_SET 0x4D - -#define BD9995X_CMD_VSYS_TH_SET 0x4E -#define BD9995X_CMD_EXTIADP_TH_SET 0x4F -#define BD9995X_CMD_IBATP_VAL 0x50 -#define BD9995X_CMD_IBATP_AVE_VAL 0x51 -#define BD9995X_CMD_IBATM_VAL 0x52 -#define BD9995X_CMD_IBATM_AVE_VAL 0x53 -#define BD9995X_CMD_VBAT_VAL 0x54 -#define BD9995X_CMD_VBAT_AVE_VAL 0x55 -#define BD9995X_CMD_THERM_VAL 0x56 -#define BD9995X_CMD_VTH_VAL 0x57 -#define BD9995X_CMD_IACP_VAL 0x58 -#define BD9995X_CMD_IACP_AVE_VAL 0x59 -#define BD9995X_CMD_VACP_VAL 0x5A -#define BD9995X_CMD_VACP_AVE_VAL 0x5B -#define BD9995X_CMD_VBUS_VAL 0x5C -#define BD9995X_CMD_VBUS_AVE_VAL 0x5D -#define BD9995X_CMD_VCC_VAL 0x5E -#define BD9995X_CMD_VCC_AVE_VAL 0x5F -#define BD9995X_CMD_VSYS_VAL 0x60 -#define BD9995X_CMD_VSYS_AVE_VAL 0x61 -#define BD9995X_CMD_EXTIADP_VAL 0x62 -#define BD9995X_CMD_EXTIADP_AVE_VAL 0x63 -#define BD9995X_CMD_VACPCLPS_TH_SET 0x64 -#define BD9995X_CMD_INT0_SET 0x68 -#define BD9995X_CMD_INT0_SET_INT2_EN BIT(2) -#define BD9995X_CMD_INT0_SET_INT1_EN BIT(1) -#define BD9995X_CMD_INT0_SET_INT0_EN BIT(0) - -#define BD9995X_CMD_INT1_SET 0x69 -/* Bits for both INT1 & INT2 reg */ -#define BD9995X_CMD_INT_SET_TH_DET BIT(9) -#define BD9995X_CMD_INT_SET_TH_RES BIT(8) -#define BD9995X_CMD_INT_SET_DET BIT(1) -#define BD9995X_CMD_INT_SET_RES BIT(0) -#define BD9995X_CMD_INT_VBUS_DET (BD9995X_CMD_INT_SET_RES | \ - BD9995X_CMD_INT_SET_DET) -#define BD9995X_CMD_INT_VBUS_TH (BD9995X_CMD_INT_SET_TH_RES | \ - BD9995X_CMD_INT_SET_TH_DET) - -#define BD9995X_CMD_INT2_SET 0x6A -#define BD9995X_CMD_INT3_SET 0x6B -#define BD9995X_CMD_INT4_SET 0x6C -#define BD9995X_CMD_INT5_SET 0x6D -#define BD9995X_CMD_INT6_SET 0x6E -#define BD9995X_CMD_INT7_SET 0x6F -#define BD9995X_CMD_INT0_STATUS 0x70 -#define BD9995X_CMD_INT1_STATUS 0x71 -/* Bits for both INT1_STATUS & INT2_STATUS reg */ -#define BD9995X_CMD_INT_STATUS_DET BIT(1) -#define BD9995X_CMD_INT_STATUS_RES BIT(0) - -#define BD9995X_CMD_INT2_STATUS 0x72 -#define BD9995X_CMD_INT3_STATUS 0x73 -#define BD9995X_CMD_INT4_STATUS 0x74 -#define BD9995X_CMD_INT5_STATUS 0x75 -#define BD9995X_CMD_INT6_STATUS 0x76 -#define BD9995X_CMD_INT7_STATUS 0x77 -#define BD9995X_CMD_REG0 0x78 -#define BD9995X_CMD_REG1 0x79 -#define BD9995X_CMD_OTPREG0 0x7A -#define BD9995X_CMD_OTPREG1 0x7B -#define BD9995X_CMD_SMBREG 0x7C -/* Normal functionality - power save mode disabled. */ -#define BD9995X_PWR_SAVE_OFF 0 -/* BGATE ON w/ PROCHOT# monitored only system voltage. */ -#define BD9995X_PWR_SAVE_LOW 0x1 -/* BGATE ON w/ PROCHOT# monitored only system voltage every 1ms. */ -#define BD9995X_PWR_SAVE_MED 0x2 -/* BGATE ON w/o PROCHOT# monitoring. */ -#define BD9995X_PWR_SAVE_HIGH 0x5 -/* BGATE OFF */ -#define BD9995X_PWR_SAVE_MAX 0x6 -#define BD9995X_CMD_DEBUG_MODE_SET 0x7F - -/* - * Non-standard interface functions - bd9995x integrates additional - * functionality not part of the standard charger interface. - */ - -/* Is VBUS provided or external power present */ -int bd9995x_is_vbus_provided(enum bd9995x_charge_port port); -/* Select or deselect input port from {VCC, VBUS, VCC&VBUS}. */ -int bd9995x_select_input_port(enum bd9995x_charge_port port, int select); -/* Enable/Disable charging triggered by BC1.2 */ -int bd9995x_bc12_enable_charging(int port, int enable); -/* Interrupt handler for USB charger VBUS */ -void bd9995x_vbus_interrupt(enum gpio_signal signal); -/* Read temperature measurement value (in Celsius) */ -int bd9995x_get_battery_temp(int *temp_ptr); -/* Set power save mode */ -void bd9995x_set_power_save_mode(int mode); -/* Get Battery Voltage Measurement Value */ -int bd9995x_get_battery_voltage(void); - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_CHARGER -extern struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev; -#endif - -#endif /* __CROS_EC_BD9995X_H */ diff --git a/driver/charger/bq24192.c b/driver/charger/bq24192.c deleted file mode 100644 index 3345bab093..0000000000 --- a/driver/charger/bq24192.c +++ /dev/null @@ -1,277 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24192 battery charger driver. - */ - -#include "bq24192.h" -#include "charger.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "printf.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHARGER, outstr) -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) - -/* Charger information */ -static const struct charger_info bq24192_charger_info = { - .name = "bq24192", - .voltage_max = 4400, - .voltage_min = 3504, - .voltage_step = 16, - .current_max = 4544, - .current_min = 512, - .current_step = 64, - .input_current_max = 3000, - .input_current_min = 100, - .input_current_step = -1, -}; - -static const int input_current_steps[] = { - 100, 150, 500, 900, 1200, 1500, 2000, 3000}; - -static int bq24192_read(int reg, int *value) -{ - return i2c_read8(I2C_PORT_CHARGER, BQ24192_ADDR, reg, value); -} - -static int bq24192_write(int reg, int value) -{ - return i2c_write8(I2C_PORT_CHARGER, BQ24192_ADDR, reg, value); -} - -static int bq24192_watchdog_reset(void) -{ - int rv, val; - - rv = bq24192_read(BQ24192_REG_POWER_ON_CFG, &val); - if (rv) - return rv; - val |= BIT(6); - return bq24192_write(BQ24192_REG_POWER_ON_CFG, val) || - bq24192_write(BQ24192_REG_POWER_ON_CFG, val); -} - -static int bq24192_set_terminate_current(int current) -{ - int reg_val, rv; - int val = (current - 128) / 128; - - rv = bq24192_read(BQ24192_REG_PRE_CHG_CURRENT, ®_val); - if (rv) - return rv; - reg_val = (reg_val & ~0xf) | (val & 0xf); - return bq24192_write(BQ24192_REG_PRE_CHG_CURRENT, reg_val); -} - -#ifdef CONFIG_CHARGER_OTG -int charger_enable_otg_power(int enabled) -{ - int val, rv; - - gpio_set_level(GPIO_BCHGR_OTG, enabled); - rv = bq24192_read(BQ24192_REG_POWER_ON_CFG, &val); - if (rv) - return rv; - val = (val & ~0x30) | (enabled ? 0x20 : 0x10); - return bq24192_write(BQ24192_REG_POWER_ON_CFG, val); -} -#endif - -int charger_set_input_current(int input_current) -{ - int i, value, rv; - - for (i = 1; i < ARRAY_SIZE(input_current_steps); ++i) - if (input_current_steps[i] > input_current) { - --i; - break; - } - if (i == ARRAY_SIZE(input_current_steps)) - --i; - - rv = bq24192_read(BQ24192_REG_INPUT_CTRL, &value); - if (rv) - return rv; - value = value & ~(0x7); - value |= (i & 0x7); - return bq24192_write(BQ24192_REG_INPUT_CTRL, value); -} - -int charger_get_input_current(int *input_current) -{ - int rv, value; - - rv = bq24192_read(BQ24192_REG_INPUT_CTRL, &value); - if (rv) - return rv; - *input_current = input_current_steps[value & 0x7]; - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_device_id(int *id) -{ - return bq24192_read(BQ24192_REG_ID, id); -} - -int charger_get_option(int *option) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_set_option(int option) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -const struct charger_info *charger_get_info(void) -{ - return &bq24192_charger_info; -} - -int charger_get_status(int *status) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_set_mode(int mode) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_get_current(int *current) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - rv = bq24192_read(BQ24192_REG_CHG_CURRENT, &val); - if (rv) - return rv; - val = (val >> 2) & 0x3f; - *current = val * info->current_step + info->current_min; - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - current = charger_closest_current(current); - rv = bq24192_read(BQ24192_REG_CHG_CURRENT, &val); - if (rv) - return rv; - val = val & 0x3; - val |= ((current - info->current_min) / info->current_step) << 2; - return bq24192_write(BQ24192_REG_CHG_CURRENT, val); -} - -int charger_get_voltage(int *voltage) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - rv = bq24192_read(BQ24192_REG_CHG_VOLTAGE, &val); - if (rv) - return rv; - val = (val >> 2) & 0x3f; - *voltage = val * info->voltage_step + info->voltage_min; - return EC_SUCCESS; -} - -int charger_set_voltage(int voltage) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - rv = bq24192_read(BQ24192_REG_CHG_VOLTAGE, &val); - if (rv) - return rv; - val = val & 0x3; - val |= ((voltage - info->voltage_min) / info->voltage_step) << 2; - return bq24192_write(BQ24192_REG_CHG_VOLTAGE, val); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - /* Input current controlled by extpower module. Do nothing here. */ - return EC_SUCCESS; -} - - -/*****************************************************************************/ -/* Hooks */ - -static void bq24192_init(void) -{ - int val; - - if (charger_device_id(&val) || val != BQ24192_DEVICE_ID) { - CPRINTF("BQ24192 incorrent ID: 0x%02x\n", val); - return; - } - - /* - * Disable I2C watchdog timer. - * - * TODO(crosbug.com/p/22238): Re-enable watchdog timer and kick it - * periodically in charger task. - */ - if (bq24192_read(BQ24192_REG_CHG_TERM_TMR, &val)) - return; - - val &= ~0x30; - - if (bq24192_write(BQ24192_REG_CHG_TERM_TMR, val)) - return; - - if (bq24192_set_terminate_current(128)) - return; - - if (bq24192_watchdog_reset()) - return; - - CPRINTF("BQ24192 initialized\n"); -} -DECLARE_HOOK(HOOK_INIT, bq24192_init, HOOK_PRIO_LAST); - -/*****************************************************************************/ -/* Console commands */ -#ifdef CONFIG_CMD_CHARGER -static int command_bq24192(int argc, char **argv) -{ - int i; - int value; - int rv; - - ccprintf("REG:"); - for (i = 0; i <= 0xa; ++i) - ccprintf(" %02x", i); - ccprintf("\n"); - - ccprintf("VAL:"); - for (i = 0; i <= 0xa; ++i) { - rv = bq24192_read(i, &value); - if (rv) - return rv; - ccprintf(" %02x", value); - } - ccprintf("\n"); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(bq24192, command_bq24192, - NULL, NULL); -#endif diff --git a/driver/charger/bq24192.h b/driver/charger/bq24192.h deleted file mode 100644 index b82fe93a02..0000000000 --- a/driver/charger/bq24192.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2013 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. - * - * TI bq24192 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24192_H -#define __CROS_EC_BQ24192_H - -#define BQ24192_ADDR_FLAGS 0x6b - -/* Registers */ -#define BQ24192_REG_INPUT_CTRL 0x0 -#define BQ24192_REG_POWER_ON_CFG 0x1 -#define BQ24192_REG_CHG_CURRENT 0x2 -#define BQ24192_REG_PRE_CHG_CURRENT 0x3 -#define BQ24192_REG_CHG_VOLTAGE 0x4 -#define BQ24192_REG_CHG_TERM_TMR 0x5 -#define BQ24192_REG_IR_COMP 0x6 -#define BQ24192_REG_MISC_OP 0x7 -#define BQ24192_REG_STATUS 0x8 -#define BQ24192_REG_FAULT 0x9 -#define BQ24192_REG_ID 0xa - -#define BQ24192_DEVICE_ID 0x2b - -#endif /* __CROS_EC_BQ24192_H */ diff --git a/driver/charger/bq24707a.c b/driver/charger/bq24707a.c deleted file mode 100644 index 53e3f5b531..0000000000 --- a/driver/charger/bq24707a.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24707A battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24707a.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "i2c.h" -#include "util.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) - -/* - * charge voltage bitmask: 0111 1111 1111 0000 - * charge current bitmask: 0001 1111 1100 0000 - * input current bitmask : 0001 1111 1000 0000 - */ -static const struct charger_info bq24707a_charger_info = { - .name = "bq24707A", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = REG_TO_CURRENT(0x1fc0, R_SNS), - .current_min = REG_TO_CURRENT(0x40, R_SNS), - .current_step = REG_TO_CURRENT(0x40, R_SNS), - .input_current_max = REG_TO_CURRENT(0x1F80, R_AC), - .input_current_min = REG_TO_CURRENT(0x80, R_AC), - .input_current_step = REG_TO_CURRENT(0x80, R_AC), -}; - -/* bq24707a specific interfaces */ - -static inline int sbc_read(int cmd, int *param) -{ - return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); -} - -static inline int sbc_write(int cmd, int param) -{ - return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); -} - -int charger_set_input_current(int input_current) -{ - return sbc_write(BQ24707_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = sbc_read(BQ24707_INPUT_CURRENT, ®); - if (rv) - return rv; - - *input_current = REG_TO_CURRENT(reg, R_AC); - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return sbc_read(BQ24707_MANUFACTURE_ID, id); -} - -int charger_device_id(int *id) -{ - return sbc_read(BQ24707_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - return sbc_read(BQ24707_CHARGE_OPTION, option); -} - -int charger_set_option(int option) -{ - return sbc_write(BQ24707_CHARGE_OPTION, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq24707a_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & OPTION_CHARGE_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPTION_CHARGE_INHIBIT; - else - option &= ~OPTION_CHARGE_INHIBIT; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = sbc_read(SB_CHARGING_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -int charger_get_voltage(int *voltage) -{ - return sbc_read(SB_CHARGING_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return sbc_write(SB_CHARGING_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - /* - * Note: bq24725 power on reset state is: - * watch dog timer = 175 sec - * input current limit = ~1/2 maximum setting - * charging voltage = 0 mV - * charging current = 0 mA - * IOUT = 20x adapter current sense - */ - - /* Set charger input current limit */ - return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); -} diff --git a/driver/charger/bq24707a.h b/driver/charger/bq24707a.h deleted file mode 100644 index c26a0eea35..0000000000 --- a/driver/charger/bq24707a.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24707A battery charger driver. - */ - -#ifndef __CROS_EC_BQ24707A_H -#define __CROS_EC_BQ24707A_H - -/* Chip specific commands */ -#define BQ24707_CHARGE_OPTION 0x12 -#define BQ24707_INPUT_CURRENT 0x3f -#define BQ24707_MANUFACTURE_ID 0xfe -#define BQ24707_DEVICE_ID 0xff - -/* ChargeOption 0x12 */ -#define OPTION_CHARGE_INHIBIT BIT(0) -#define OPTION_ACOC_THRESHOLD (3 << 1) -#define OPTION_COMPARATOR_THRESHOLD BIT(4) -#define OPTION_IOUT_SELECTION BIT(5) -#define OPTION_IFAULT_HI_THRESHOLD (3 << 7) -#define OPTION_EMI_FREQ_ENABLE BIT(9) -#define OPTION_EMI_FREQ_ADJ BIT(10) -#define OPTION_WATCHDOG_TIMER (3 << 13) -#define OPTION_AOC_DELITCH_TIME BIT(15) -/* OPTION_ACOC_THRESHOLD */ -#define ACOC_THRESHOLD_DISABLE (0 << 1) -#define ACOC_THRESHOLD_133X BIT(1) -#define ACOC_THRESHOLD_166X_DEFAULT (2 << 1) -#define ACOC_THRESHOLD_222X (3 << 1) -/* OPTION_IFAULT_HI_THRESHOLD */ -#define IFAULT_THRESHOLD_300MV (0 << 7) -#define IFAULT_THRESHOLD_500MV BIT(7) -#define IFAULT_THRESHOLD_700MV_DEFAULT (2 << 7) -#define IFAULT_THRESHOLD_900MV (3 << 7) -/* OPTION_WATCHDOG_TIMER */ -#define CHARGE_WATCHDOG_DISABLE (0 << 13) -#define CHARGE_WATCHDOG_44SEC BIT(13) -#define CHARGE_WATCHDOG_88SEC (2 << 13) -#define CHARGE_WATCHDOG_175SEC_DEFAULT (3 << 13) - -#endif /* __CROS_EC_BQ24707A_H */ - diff --git a/driver/charger/bq24715.c b/driver/charger/bq24715.c deleted file mode 100644 index 8a8d9b894f..0000000000 --- a/driver/charger/bq24715.c +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright 2013 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. - * - * TI bq24715 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24715.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "i2c.h" -#include "util.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) - -/* Note: it is assumed that the sense resistors are 10mOhm. */ - -static const struct charger_info bq24725_charger_info = { - .name = "bq24715", - .voltage_max = CHARGE_V_MAX, - .voltage_min = CHARGE_V_MIN, - .voltage_step = CHARGE_V_STEP, - .current_max = REG_TO_CURRENT(CHARGE_I_MAX, R_SNS), - .current_min = REG_TO_CURRENT(CHARGE_I_MIN, R_SNS), - .current_step = REG_TO_CURRENT(CHARGE_I_STEP, R_SNS), - .input_current_max = REG_TO_CURRENT(INPUT_I_MAX, R_AC), - .input_current_min = REG_TO_CURRENT(INPUT_I_MIN, R_AC), - .input_current_step = REG_TO_CURRENT(INPUT_I_STEP, R_AC), -}; - -static inline int sbc_read(int cmd, int *param) -{ - return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR_FLAGS, - cmd, param); -} - -static inline int sbc_write(int cmd, int param) -{ - return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR_FLAGS, - cmd, param); -} - -int charger_set_input_current(int input_current) -{ - return sbc_write(BQ24715_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = sbc_read(BQ24715_INPUT_CURRENT, ®); - if (rv) - return rv; - - *input_current = REG_TO_CURRENT(reg, R_AC); - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return sbc_read(BQ24715_MANUFACTURER_ID, id); -} - -int charger_device_id(int *id) -{ - return sbc_read(BQ24715_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - return sbc_read(BQ24715_CHARGE_OPTION, option); -} - -int charger_set_option(int option) -{ - return sbc_write(BQ24715_CHARGE_OPTION, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq24725_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if ((option & OPT_CHARGE_INHIBIT_MASK) == OPT_CHARGE_DISABLE) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - option &= ~OPT_CHARGE_INHIBIT_MASK; - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPT_CHARGE_DISABLE; - else - option |= OPT_CHARGE_ENABLE; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = sbc_read(SB_CHARGING_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -/* The voltage setting needs to be cached to work with the current - * charging infrastructure and state machine. The reason is that - * the state machine expects to be able to set a 0V charging voltage. - * The bq24715 does not allow this in the hardware register. Therefore - * 0V is handled specially to appease the state machine. */ -static int cached_voltage; - -int charger_get_voltage(int *voltage) -{ - int ret; - - if (cached_voltage == 0) { - *voltage = cached_voltage; - return EC_SUCCESS; - } - - ret = sbc_read(SB_CHARGING_VOLTAGE, &cached_voltage); - - if (ret == EC_SUCCESS) - *voltage = cached_voltage; - - return ret; -} - -int charger_set_voltage(int voltage) -{ - cached_voltage = voltage; - return sbc_write(SB_CHARGING_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Don't be noisy */ - option |= OPT_AUDIO_FREQ_40KHZ_LIMIT; - - /* Always monitor adapter current (40X multiplier). */ - option |= OPT_FIX_IOUT_ALWAYS; - option &= ~OPT_IOUT_MASK; - option &= ~OPT_LEARN_MASK; - - /* Enable dynamic power management */ - option |= OPT_IDPM_ENABLE; - - rv = charger_set_option(option); - if (rv) - return rv; - - rv = charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); - return rv; -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - option &= ~OPT_LEARN_MASK; - if (enable) - option |= OPT_LEARN_ENABLE; - else - option |= OPT_LEARN_DISABLE; - rv = charger_set_option(option); - - return rv; -} diff --git a/driver/charger/bq24715.h b/driver/charger/bq24715.h deleted file mode 100644 index ca07da053f..0000000000 --- a/driver/charger/bq24715.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24715 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24715_H -#define __CROS_EC_BQ24715_H - -/* NOTES: - * If battery is not present keep charge current register (0x14) at 0. - * Max charge voltage (0x15) needs to be programmed before 0x14. - */ - -/* Chip specific registers */ -#define BQ24715_CHARGE_OPTION 0x12 -#define BQ24715_CHARGE_CURRENT 0x14 -#define BQ24715_MAX_CHARGE_VOLTAGE 0x15 -#define BQ24715_MIN_SYSTEM_VOLTAGE 0x3e -#define BQ24715_INPUT_CURRENT 0x3f -#define BQ24715_MANUFACTURER_ID 0xfe -#define BQ24715_DEVICE_ID 0xff - -/* ChargeOption Register - 0x12 */ -#define OPT_LOWPOWER_MASK BIT(15) -#define OPT_LOWPOWER_DSCHRG_I_MON_ON (0 << 15) -#define OPT_LOWPOWER_DSCHRG_I_MON_OFF BIT(15) -#define OPT_WATCHDOG_MASK (3 << 13) -#define OPT_WATCHDOG_DISABLE (0 << 13) -#define OPT_WATCHDOG_44SEC BIT(13) -#define OPT_WATCHDOG_88SEC (2 << 13) -#define OPT_WATCHDOG_175SEC (3 << 13) -#define OPT_SYSOVP_MASK BIT(12) -#define OPT_SYSOVP_15P1_3SEC_10P1_2SEC (0 << 12) -#define OPT_SYSOVP_17P0_3SEC_11P3_2SEC BIT(12) -#define OPT_SYSOVP_STATUS_MASK BIT(11) -#define OPT_SYSOVP_STATUS BIT(11) -#define OPT_AUDIO_FREQ_LIMIT_MASK BIT(10) -#define OPT_AUDIO_FREQ_NO_LIMIT (0 << 10) -#define OPT_AUDIO_FREQ_40KHZ_LIMIT BIT(10) -#define OPT_SWITCH_FREQ_MASK (3 << 8) -#define OPT_SWITCH_FREQ_600KHZ (0 << 8) -#define OPT_SWITCH_FREQ_800KHZ BIT(8) -#define OPT_SWITCH_FREQ_1MHZ (2 << 8) -#define OPT_SWITCH_FREQ_800KHZ_DUP (3 << 8) -#define OPT_ACOC_MASK BIT(7) -#define OPT_ACOC_DISABLED (0 << 7) -#define OPT_ACOC_333PCT_IPDM BIT(7) -#define OPT_LSFET_OCP_MASK BIT(6) -#define OPT_LSFET_OCP_250MV (0 << 6) -#define OPT_LSFET_OCP_350MV BIT(6) -#define OPT_LEARN_MASK BIT(5) -#define OPT_LEARN_DISABLE (0 << 5) -#define OPT_LEARN_ENABLE BIT(5) -#define OPT_IOUT_MASK BIT(4) -#define OPT_IOUT_40X (0 << 4) -#define OPT_IOUT_16X BIT(4) -#define OPT_FIX_IOUT_MASK BIT(3) -#define OPT_FIX_IOUT_IDPM_EN (0 << 3) -#define OPT_FIX_IOUT_ALWAYS BIT(3) -#define OPT_LDO_MODE_MASK BIT(2) -#define OPT_LDO_DISABLE (0 << 2) -#define OPT_LDO_ENABLE BIT(2) -#define OPT_IDPM_MASK BIT(1) -#define OPT_IDPM_DISABLE (0 << 1) -#define OPT_IDPM_ENABLE BIT(1) -#define OPT_CHARGE_INHIBIT_MASK BIT(0) -#define OPT_CHARGE_ENABLE (0 << 0) -#define OPT_CHARGE_DISABLE BIT(0) - - -/* ChargeCurrent Register - 0x14 - * The ChargeCurrent register controls a DAC. Therefore - * the below definitions are cummulative. */ -#define CHARGE_I_64MA BIT(6) -#define CHARGE_I_128MA BIT(7) -#define CHARGE_I_256MA BIT(8) -#define CHARGE_I_512MA BIT(9) -#define CHARGE_I_1024MA BIT(10) -#define CHARGE_I_2048MA BIT(11) -#define CHARGE_I_4096MA BIT(12) -#define CHARGE_I_OFF (0) -#define CHARGE_I_MIN (128) -#define CHARGE_I_MAX (8128) -#define CHARGE_I_STEP (64) - -/* MaxChargeVoltage Register - 0x15 - * The MaxChargeVoltage register controls a DAC. Therefore - * the below definitions are cummulative. */ -#define CHARGE_V_16MV BIT(4) -#define CHARGE_V_32MV BIT(5) -#define CHARGE_V_64MV BIT(6) -#define CHARGE_V_128MV BIT(7) -#define CHARGE_V_256MV BIT(8) -#define CHARGE_V_512MV BIT(9) -#define CHARGE_V_1024MV BIT(10) -#define CHARGE_V_2048MV BIT(11) -#define CHARGE_V_4096MV BIT(12) -#define CHARGE_V_8192MV BIT(13) -#define CHARGE_V_MIN (4096) -#define CHARGE_V_MAX (0x3ff0) -#define CHARGE_V_STEP (16) - -/* MinSystemVoltage Register - 0x3e - * The MinSystemVoltage register controls a DAC. Therefore - * the below definitions are cummulative. */ -#define MIN_SYS_V_256MV BIT(8) -#define MIN_SYS_V_512MV BIT(9) -#define MIN_SYS_V_1024MV BIT(10) -#define MIN_SYS_V_2048MV BIT(11) -#define MIN_SYS_V_4096MV BIT(12) -#define MIN_SYS_V_8192MV BIT(13) -#define MIN_SYS_V_MIN (4096) - -/* InputCurrent Register - 0x3f - * The InputCurrent register controls a DAC. Therefore - * the below definitions are cummulative. */ -#define INPUT_I_64MA BIT(6) -#define INPUT_I_128MA BIT(7) -#define INPUT_I_256MA BIT(8) -#define INPUT_I_512MA BIT(9) -#define INPUT_I_1024MA BIT(10) -#define INPUT_I_2048MA BIT(11) -#define INPUT_I_4096MA BIT(12) -#define INPUT_I_MIN (128) -#define INPUT_I_MAX (8064) -#define INPUT_I_STEP (64) - -#endif /* __CROS_EC_BQ24715_H */ diff --git a/driver/charger/bq24725.c b/driver/charger/bq24725.c deleted file mode 100644 index 48f53a05c4..0000000000 --- a/driver/charger/bq24725.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24725 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24725.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "util.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) - -/* Charger information - * charge voltage bitmask: 0111 1111 1111 0000 - * charge current bitmask: 0001 1111 1000 0000 - * input current bitmask : 0000 0000 1000 0000 - */ -static const struct charger_info bq24725_charger_info = { - .name = "bq24725", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = REG_TO_CURRENT(8128, R_SNS), - .current_min = REG_TO_CURRENT(128, R_SNS), - .current_step = REG_TO_CURRENT(128, R_SNS), - .input_current_max = REG_TO_CURRENT(8064, R_AC), - .input_current_min = REG_TO_CURRENT(128, R_AC), - .input_current_step = REG_TO_CURRENT(128, R_AC), -}; - -/* bq24725 specific interfaces */ - -int charger_set_input_current(int input_current) -{ - return sbc_write(BQ24725_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = sbc_read(BQ24725_INPUT_CURRENT, ®); - if (rv) - return rv; - - *input_current = REG_TO_CURRENT(reg, R_AC); - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return sbc_read(BQ24725_MANUFACTURE_ID, id); -} - -int charger_device_id(int *id) -{ - return sbc_read(BQ24725_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - return sbc_read(BQ24725_CHARGE_OPTION, option); -} - -int charger_set_option(int option) -{ - return sbc_write(BQ24725_CHARGE_OPTION, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq24725_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & OPTION_CHARGE_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPTION_CHARGE_INHIBIT; - else - option &= ~OPTION_CHARGE_INHIBIT; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = sbc_read(SB_CHARGING_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -int charger_get_voltage(int *voltage) -{ - return sbc_read(SB_CHARGING_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return sbc_write(SB_CHARGING_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - /* - * Note: bq24725 power on reset state is: - * watch dog timer = 175 sec - * input current limit = ~1/2 maximum setting - * charging voltage = 0 mV - * charging current = 0 mA - */ - - int rv, option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - option &= ~OPTION_LEARN_ENABLE; - rv = charger_set_option(option); - if (rv) - return rv; - - /* Set charger input current limit */ - return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - rv = charger_set_option(option | OPTION_LEARN_ENABLE); - else - rv = charger_set_option(option & ~OPTION_LEARN_ENABLE); - - return rv; -} diff --git a/driver/charger/bq24725.h b/driver/charger/bq24725.h deleted file mode 100644 index ad6c508a4f..0000000000 --- a/driver/charger/bq24725.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2012 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. - * - * TI bq24725 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24725_H -#define __CROS_EC_BQ24725_H - -/* Chip specific commands */ -#define BQ24725_CHARGE_OPTION 0x12 -#define BQ24725_INPUT_CURRENT 0x3f -#define BQ24725_MANUFACTURE_ID 0xfe -#define BQ24725_DEVICE_ID 0xff - -/* ChargeOption 0x12 */ -#define OPTION_CHARGE_INHIBIT BIT(0) -#define OPTION_ACOC_THRESHOLD (3 << 1) -#define OPTION_IOUT_SELECTION BIT(5) -#define OPTION_LEARN_ENABLE BIT(6) -#define OPTION_IFAULT_HI_THRESHOLD (3 << 7) -#define OPTION_EMI_FREQ_ENABLE BIT(9) -#define OPTION_EMI_FREQ_ADJ BIT(10) -#define OPTION_BAT_DEPLETION_THRESHOLD (3 << 11) -#define OPTION_WATCHDOG_TIMER (3 << 13) -#define OPTION_AOC_DELITCH_TIME BIT(15) -/* OPTION_ACOC_THRESHOLD */ -#define ACOC_THRESHOLD_DISABLE (0 << 1) -#define ACOC_THRESHOLD_133X BIT(1) -#define ACOC_THRESHOLD_166X_DEFAULT (2 << 1) -#define ACOC_THRESHOLD_222X (3 << 1) -/* OPTION_IFAULT_HI_THRESHOLD */ -#define IFAULT_THRESHOLD_300MV (0 << 7) -#define IFAULT_THRESHOLD_500MV BIT(7) -#define IFAULT_THRESHOLD_700MV_DEFAULT (2 << 7) -#define IFAULT_THRESHOLD_900MV (3 << 7) -/* OPTION_BAT_DEPLETION_THRESHOLD */ -#define FALLING_THRESHOLD_5919 (0 << 11) -#define FALLING_THRESHOLD_6265 BIT(11) -#define FALLING_THRESHOLD_6655 (2 << 11) -#define FALLING_THRESHOLD_7097_DEFAULT (3 << 11) -/* OPTION_WATCHDOG_TIMER */ -#define CHARGE_WATCHDOG_DISABLE (0 << 13) -#define CHARGE_WATCHDOG_44SEC BIT(13) -#define CHARGE_WATCHDOG_88SEC (2 << 13) -#define CHARGE_WATCHDOG_175SEC_DEFAULT (3 << 13) - -#endif /* __CROS_EC_BQ24725_H */ - diff --git a/driver/charger/bq24735.c b/driver/charger/bq24735.c deleted file mode 100644 index 65fe353f9d..0000000000 --- a/driver/charger/bq24735.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright 2014 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. - * - * TI bq24735 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24735.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "i2c.h" -#include "util.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) - -/* Charger information - * charge voltage bitmask: 0111 1111 1111 0000 - * charge current bitmask: 0001 1111 1000 0000 - * input current bitmask : 0000 0000 1000 0000 - */ -static const struct charger_info bq24735_charger_info = { - .name = "bq24735", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = REG_TO_CURRENT(8128, R_SNS), - .current_min = REG_TO_CURRENT(128, R_SNS), - .current_step = REG_TO_CURRENT(128, R_SNS), - .input_current_max = REG_TO_CURRENT(8064, R_AC), - .input_current_min = REG_TO_CURRENT(128, R_AC), - .input_current_step = REG_TO_CURRENT(128, R_AC), -}; - -/* bq24735 specific interfaces */ - -static inline int sbc_read(int cmd, int *param) -{ - return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); -} - -static inline int sbc_write(int cmd, int param) -{ - return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); -} - -int charger_set_input_current(int input_current) -{ - return sbc_write(BQ24735_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = sbc_read(BQ24735_INPUT_CURRENT, ®); - if (rv) - return rv; - - *input_current = REG_TO_CURRENT(reg, R_AC); - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return sbc_read(BQ24735_MANUFACTURE_ID, id); -} - -int charger_device_id(int *id) -{ - return sbc_read(BQ24735_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - return sbc_read(BQ24735_CHARGE_OPTION, option); -} - -int charger_set_option(int option) -{ - return sbc_write(BQ24735_CHARGE_OPTION, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq24735_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & OPTION_CHARGE_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPTION_CHARGE_INHIBIT; - else - option &= ~OPTION_CHARGE_INHIBIT; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = sbc_read(SB_CHARGING_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -int charger_get_voltage(int *voltage) -{ - return sbc_read(SB_CHARGING_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return sbc_write(SB_CHARGING_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - /* - * Note: bq24735 power on reset state is: - * watch dog timer = 175 sec - * input current limit = ~1/2 maximum setting - * charging voltage = 0 mV - * charging current = 0 mA - */ - - int rv, option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - option &= ~OPTION_LEARN_ENABLE; - rv = charger_set_option(option); - if (rv) - return rv; - - /* Set charger input current limit */ - return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - rv = charger_set_option(option | OPTION_LEARN_ENABLE); - else - rv = charger_set_option(option & ~OPTION_LEARN_ENABLE); - - return rv; -} diff --git a/driver/charger/bq24735.h b/driver/charger/bq24735.h deleted file mode 100644 index 62d3365306..0000000000 --- a/driver/charger/bq24735.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2014 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. - * - * TI bq24735 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24735_H -#define __CROS_EC_BQ24735_H - -/* Chip specific commands */ -#define BQ24735_CHARGE_OPTION 0x12 -#define BQ24735_INPUT_CURRENT 0x3f -#define BQ24735_MANUFACTURE_ID 0xfe -#define BQ24735_DEVICE_ID 0xff - -/* ChargeOption 0x12 */ -#define OPTION_CHARGE_INHIBIT BIT(0) -#define OPTION_ACOC_THRESHOLD BIT(1) -#define OPTION_BOOST_MODE_STATE BIT(2) -#define OPTION_BOOST_MODE_ENABLE BIT(3) -#define OPTION_ACDET_STATE BIT(4) -#define OPTION_IOUT_SELECTION BIT(5) -#define OPTION_LEARN_ENABLE BIT(6) -#define OPTION_IFAULT_LOW_THRESHOLD BIT(7) -#define OPTION_IFAULT_HI_ENABLE BIT(8) -#define OPTION_EMI_FREQ_ENABLE BIT(9) -#define OPTION_EMI_FREQ_ADJ BIT(10) -#define OPTION_BAT_DEPLETION_THRESHOLD (3 << 11) -#define OPTION_WATCHDOG_TIMER (3 << 13) -#define OPTION_ACPRES_DEGLITCH_TIME BIT(15) - -/* OPTION_ACOC_THRESHOLD */ -#define ACOC_THRESHOLD_DISABLE (0 << 1) -#define ACOC_THRESHOLD_133X BIT(1) - -/* OPTION_IFAULT_LOW_THRESHOLD */ -#define IFAULT_LOW_135MV_DEFAULT (0 << 7) -#define IFAULT_LOW_230MV BIT(7) - -/* OPTION_BAT_DEPLETION_THRESHOLD */ -#define FALLING_THRESHOLD_5919 (0 << 11) -#define FALLING_THRESHOLD_6265 BIT(11) -#define FALLING_THRESHOLD_6655 (2 << 11) -#define FALLING_THRESHOLD_7097_DEFAULT (3 << 11) - -/* OPTION_WATCHDOG_TIMER */ -#define CHARGE_WATCHDOG_DISABLE (0 << 13) -#define CHARGE_WATCHDOG_44SEC BIT(13) -#define CHARGE_WATCHDOG_88SEC (2 << 13) -#define CHARGE_WATCHDOG_175SEC_DEFAULT (3 << 13) - -/* OPTION_ACPRES_DEGLITCH_TIME */ -#define ACPRES_DEGLITCH_150MS (0 << 15) -#define ACPRES_DEGLITCH_1300MS_DEFAULT BIT(15) - -#endif /* __CROS_EC_BQ24735_H */ diff --git a/driver/charger/bq24738.c b/driver/charger/bq24738.c deleted file mode 100644 index 507ee3bf62..0000000000 --- a/driver/charger/bq24738.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright 2013 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. - * - * TI bq24738 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24738.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "util.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) - -/* Charger information - * charge voltage bitmask: 0111 1111 1111 0000 - * charge current bitmask: 0001 1111 1100 0000 - * input current bitmask : 0000 0000 1000 0000 - */ -static const struct charger_info bq24738_charger_info = { - .name = "bq24738", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = REG_TO_CURRENT(8128, R_SNS), - .current_min = REG_TO_CURRENT(128, R_SNS), - .current_step = REG_TO_CURRENT(64, R_SNS), - .input_current_max = REG_TO_CURRENT(8064, R_AC), - .input_current_min = REG_TO_CURRENT(128, R_AC), - .input_current_step = REG_TO_CURRENT(128, R_AC), -}; - -/* bq24738 specific interfaces */ - -int charger_set_input_current(int input_current) -{ - return sbc_write(BQ24738_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = sbc_read(BQ24738_INPUT_CURRENT, ®); - if (rv) - return rv; - - *input_current = REG_TO_CURRENT(reg, R_AC); - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return sbc_read(BQ24738_MANUFACTURE_ID, id); -} - -int charger_device_id(int *id) -{ - return sbc_read(BQ24738_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - return sbc_read(BQ24738_CHARGE_OPTION, option); -} - -int charger_set_option(int option) -{ - return sbc_write(BQ24738_CHARGE_OPTION, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq24738_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & OPTION_CHARGE_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPTION_CHARGE_INHIBIT; - else - option &= ~OPTION_CHARGE_INHIBIT; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = sbc_read(SB_CHARGING_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -int charger_get_voltage(int *voltage) -{ - return sbc_read(SB_CHARGING_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return sbc_write(SB_CHARGING_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - int rv; - int val; - - /* Disable IFAULT_HI. See crosbug.com/p/19868 */ - rv = charger_get_option(&val); - if (rv) - return rv; - val &= ~OPTION_IFAULT_HI_ENABLE; - val &= ~OPTION_LEARN_ENABLE; - rv = charger_set_option(val); - if (rv) - return rv; - - /* Set charger input current limit */ - rv = charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); - return rv; -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - rv = charger_set_option(option | OPTION_LEARN_ENABLE); - else - rv = charger_set_option(option & ~OPTION_LEARN_ENABLE); - - return rv; -} diff --git a/driver/charger/bq24738.h b/driver/charger/bq24738.h deleted file mode 100644 index c06d1729b0..0000000000 --- a/driver/charger/bq24738.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2013 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. - * - * TI bq24738 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24738_H -#define __CROS_EC_BQ24738_H - -/* Chip specific commands */ -#define BQ24738_CHARGE_OPTION 0x12 -#define BQ24738_INPUT_CURRENT 0x3f -#define BQ24738_MANUFACTURE_ID 0xfe -#define BQ24738_DEVICE_ID 0xff - -/* ChargeOption 0x12 */ -#define OPTION_CHARGE_INHIBIT BIT(0) -#define OPTION_ACOC_THRESHOLD BIT(1) -#define OPTION_BOOST_MODE_STATE BIT(2) -#define OPTION_BOOST_MODE_ENABLE BIT(3) -#define OPTION_ACDET_STATE BIT(4) -#define OPTION_IOUT_SELECTION BIT(5) -#define OPTION_LEARN_ENABLE BIT(6) -#define OPTION_IFAULT_LOW_THRESHOLD BIT(7) -#define OPTION_IFAULT_HI_ENABLE BIT(8) -#define OPTION_EMI_FREQ_ENABLE BIT(9) -#define OPTION_EMI_FREQ_ADJ BIT(10) -#define OPTION_BAT_DEPLETION_THRESHOLD (3 << 11) -#define OPTION_WATCHDOG_TIMER (3 << 13) -#define OPTION_ACPRES_DEGLITCH_TIME BIT(15) - -/* OPTION_ACOC_THRESHOLD */ -#define ACOC_THRESHOLD_DISABLE (0 << 1) -#define ACOC_THRESHOLD_133X BIT(1) - -/* OPTION_IFAULT_LOW_THRESHOLD */ -#define IFAULT_LOW_135MV_DEFAULT (0 << 7) -#define IFAULT_LOW_230MV BIT(7) - -/* OPTION_BAT_DEPLETION_THRESHOLD */ -#define FALLING_THRESHOLD_5919 (0 << 11) -#define FALLING_THRESHOLD_6265 BIT(11) -#define FALLING_THRESHOLD_6655 (2 << 11) -#define FALLING_THRESHOLD_7097_DEFAULT (3 << 11) - -/* OPTION_WATCHDOG_TIMER */ -#define CHARGE_WATCHDOG_DISABLE (0 << 13) -#define CHARGE_WATCHDOG_44SEC BIT(13) -#define CHARGE_WATCHDOG_88SEC (2 << 13) -#define CHARGE_WATCHDOG_175SEC_DEFAULT (3 << 13) - -/* OPTION_ACPRES_DEGLITCH_TIME */ -#define ACPRES_DEGLITCH_150MS (0 << 15) -#define ACPRES_DEGLITCH_1300MS_DEFAULT BIT(15) - -#endif /* __CROS_EC_BQ24738_H */ diff --git a/driver/charger/bq24773.c b/driver/charger/bq24773.c deleted file mode 100644 index 4cd85b5ff1..0000000000 --- a/driver/charger/bq24773.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2014 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. - * - * TI bq24773 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq24773.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "util.h" - -/* - * on the I2C version of the charger, - * some registers are 8-bit only (eg input current) - * and they are shifted by 6 bits compared to the SMBUS version (bq24770). - */ -#define REG8_SHIFT 6 -#define R8 (1 << (REG8_SHIFT)) -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define R_AC (CONFIG_CHARGER_SENSE_RESISTOR_AC) -#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) -#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) -#define REG8_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS) * R8) -#define CURRENT_TO_REG8(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR / R8) - -/* Charger parameters */ -static const struct charger_info bq2477x_charger_info = { - .name = CHARGER_NAME, - .voltage_max = CHARGE_V_MAX, - .voltage_min = CHARGE_V_MIN, - .voltage_step = CHARGE_V_STEP, - .current_max = REG_TO_CURRENT(CHARGE_I_MAX, R_SNS), - .current_min = REG_TO_CURRENT(CHARGE_I_MIN, R_SNS), - .current_step = REG_TO_CURRENT(CHARGE_I_STEP, R_SNS), - .input_current_max = REG_TO_CURRENT(INPUT_I_MAX, R_AC), - .input_current_min = REG_TO_CURRENT(INPUT_I_MIN, R_AC), - .input_current_step = REG_TO_CURRENT(INPUT_I_STEP, R_AC), -}; - -/* chip specific interfaces */ - -int charger_set_input_current(int input_current) -{ -#ifdef CONFIG_CHARGER_BQ24770 - return raw_write16(REG_INPUT_CURRENT, - CURRENT_TO_REG(input_current, R_AC)); -#elif defined(CONFIG_CHARGER_BQ24773) - return raw_write8(REG_INPUT_CURRENT, - CURRENT_TO_REG8(input_current, R_AC)); -#endif -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - -#ifdef CONFIG_CHARGER_BQ24770 - rv = raw_read16(REG_INPUT_CURRENT, ®); -#elif defined(CONFIG_CHARGER_BQ24773) - rv = raw_read8(REG_INPUT_CURRENT, ®); -#endif - if (rv) - return rv; - -#ifdef CONFIG_CHARGER_BQ24770 - *input_current = REG_TO_CURRENT(reg, R_AC); -#elif defined(CONFIG_CHARGER_BQ24773) - *input_current = REG8_TO_CURRENT(reg, R_AC); -#endif - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ -#ifdef CONFIG_CHARGER_BQ24770 - return raw_read16(REG_MANUFACTURE_ID, id); -#elif defined(CONFIG_CHARGER_BQ24773) - *id = 0x40; /* TI */ - return EC_SUCCESS; -#endif -} - -int charger_device_id(int *id) -{ -#ifdef CONFIG_CHARGER_BQ24770 - return raw_read16(REG_DEVICE_ADDRESS, id); -#elif defined(CONFIG_CHARGER_BQ24773) - return raw_read8(REG_DEVICE_ADDRESS, id); -#endif -} - -int charger_get_option(int *option) -{ - return raw_read16(REG_CHARGE_OPTION0, option); -} - -int charger_set_option(int option) -{ - return raw_write16(REG_CHARGE_OPTION0, option); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq2477x_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & OPTION0_CHARGE_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGE_FLAG_INHIBIT_CHARGE) - option |= OPTION0_CHARGE_INHIBIT; - else - option &= ~OPTION0_CHARGE_INHIBIT; - return charger_set_option(option); -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = raw_read16(REG_CHARGE_CURRENT, ®); - - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg, R_SNS); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - current = charger_closest_current(current); - return raw_write16(REG_CHARGE_CURRENT, CURRENT_TO_REG(current, R_SNS)); -} - -int charger_get_voltage(int *voltage) -{ - return raw_read16(REG_MAX_CHARGE_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - voltage = charger_closest_voltage(voltage); - return raw_write16(REG_MAX_CHARGE_VOLTAGE, voltage); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ - int rv, option; -#ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED - int option2; -#endif - - rv = charger_get_option(&option); - if (rv) - return rv; - - option &= ~OPTION0_LEARN_ENABLE; - rv = charger_set_option(option); - if (rv) - return rv; - -#ifndef BOARD_SAMUS - /* Turn off PROCHOT warning */ - rv = raw_read16(REG_PROCHOT_OPTION1, &option); - if (rv) - return rv; - - option &= ~PROCHOT_OPTION1_SELECTOR_MASK; - - rv = raw_write16(REG_PROCHOT_OPTION1, option); -#else - /* On Samus, use PROCHOT warning to detect charging problems */ - /* Turn on PROCHOT warning */ - rv = raw_write16(REG_PROCHOT_OPTION1, 0x8120); - /* Set PROCHOT ICRIT warning when IADP is >120% of IDPM */ - rv |= raw_write16(REG_PROCHOT_OPTION0, 0x1b54); -#endif - - if (rv) - return rv; - -#ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED - /* Read the external ILIM pin enabled flag. */ - rv = raw_read16(REG_CHARGE_OPTION2, &option2); - if (rv) - return rv; - - /* Set ILIM pin disabled if it is currently enabled. */ - if (option2 & OPTION2_EN_EXTILIM) { - option2 &= ~OPTION2_EN_EXTILIM; - rv = raw_write16(REG_CHARGE_OPTION2, option2); - } - return rv; -#else - return EC_SUCCESS; -#endif -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - rv = charger_set_option(option | OPTION0_LEARN_ENABLE); - else - rv = charger_set_option(option & ~OPTION0_LEARN_ENABLE); - - return rv; -} diff --git a/driver/charger/bq24773.h b/driver/charger/bq24773.h deleted file mode 100644 index 910ad8da25..0000000000 --- a/driver/charger/bq24773.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright 2014 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. - * - * TI bq24773 battery charger driver. - */ - -#ifndef __CROS_EC_BQ24773_H -#define __CROS_EC_BQ24773_H - -/* for i2c_read and i2c_write functions. */ -#include "i2c.h" - -/* I2C address */ -#define BQ24770_ADDR_FLAGS 0x09 -#define BQ24773_ADDR_FLAGS 0x6a - -/* Chip specific commands */ -#define BQ24770_CHARGE_OPTION0 0x12 -#define BQ24770_CHARGE_OPTION1 0x3B -#define BQ24770_CHARGE_OPTION2 0x38 -#define BQ24770_PROCHOT_OPTION0 0x3C -#define BQ24770_PROCHOT_OPTION1 0x3D -#define BQ24770_CHARGE_CURRENT 0x14 -#define BQ24770_MAX_CHARGE_VOLTAGE 0x15 -#define BQ24770_MIN_SYSTEM_VOLTAGE 0x3E -#define BQ24770_INPUT_CURRENT 0x3F -#define BQ24770_MANUFACTURE_ID 0xFE -#define BQ24770_DEVICE_ADDRESS 0xFF - -#define BQ24773_CHARGE_OPTION0 0x00 -#define BQ24773_CHARGE_OPTION1 0x02 -#define BQ24773_PROCHOT_OPTION0 0x04 -#define BQ24773_PROCHOT_OPTION1 0x06 -#define BQ24773_PROCHOT_STATUS 0x08 -#define BQ24773_DEVICE_ADDRESS 0x09 -#define BQ24773_CHARGE_CURRENT 0x0A -#define BQ24773_MAX_CHARGE_VOLTAGE 0x0C -#define BQ24773_MIN_SYSTEM_VOLTAGE 0x0E -#define BQ24773_INPUT_CURRENT 0x0F -#define BQ24773_CHARGE_OPTION2 0x10 - -/* Option bits */ -#define OPTION0_CHARGE_INHIBIT BIT(0) -#define OPTION0_LEARN_ENABLE BIT(5) -#define OPTION0_SWITCHING_FREQ_MASK (3 << 8) -#define OPTION0_SWITCHING_FREQ_600KHZ (0 << 8) -#define OPTION0_SWITCHING_FREQ_800KHZ BIT(8) -#define OPTION0_SWITCHING_FREQ_1000KHZ (2 << 8) -#define OPTION0_SWITCHING_FREQ_1200KHZ (3 << 8) - -#define OPTION2_EN_EXTILIM BIT(7) - -/* Prochot Option bits */ -#define PROCHOT_OPTION1_SELECTOR_MASK 0x7f /* [6:0] PROCHOT SELECTOR */ - -/* ChargeCurrent Register - 0x14 (mA) */ -#define CHARGE_I_OFF 0 -#define CHARGE_I_MIN 128 -#define CHARGE_I_MAX 8128 -#define CHARGE_I_STEP 64 - -/* MaxChargeVoltage Register - 0x15 (mV) */ -#define CHARGE_V_MIN 1024 -#define CHARGE_V_MAX 19200 -#define CHARGE_V_STEP 16 - -/* InputCurrent Register - 0x3f (mA) */ -#define INPUT_I_MIN 128 -#define INPUT_I_MAX 8128 -#define INPUT_I_STEP 64 - -#ifdef CONFIG_CHARGER_BQ24770 - #define CHARGER_NAME "bq24770" - #define I2C_ADDR_CHARGER_FLAGS BQ24770_ADDR_FLAGS - - #define REG_CHARGE_OPTION0 BQ24770_CHARGE_OPTION0 - #define REG_CHARGE_OPTION1 BQ24770_CHARGE_OPTION1 - #define REG_CHARGE_OPTION2 BQ24770_CHARGE_OPTION2 - #define REG_PROCHOT_OPTION0 BQ24770_PROCHOT_OPTION0 - #define REG_PROCHOT_OPTION1 BQ24770_PROCHOT_OPTION1 - #define REG_CHARGE_CURRENT BQ24770_CHARGE_CURRENT - #define REG_MAX_CHARGE_VOLTAGE BQ24770_MAX_CHARGE_VOLTAGE - #define REG_MIN_SYSTEM_VOLTAGE BQ24770_MIN_SYSTEM_VOLTAGE - #define REG_INPUT_CURRENT BQ24770_INPUT_CURRENT - #define REG_MANUFACTURE_ID BQ24770_MANUFACTURE_ID - #define REG_DEVICE_ADDRESS BQ24770_DEVICE_ADDRESS - -#elif defined(CONFIG_CHARGER_BQ24773) - #define CHARGER_NAME "bq24773" - #define I2C_ADDR_CHARGER_FLAGS BQ24773_ADDR_FLAGS - - #define REG_CHARGE_OPTION0 BQ24773_CHARGE_OPTION0 - #define REG_CHARGE_OPTION1 BQ24773_CHARGE_OPTION1 - #define REG_CHARGE_OPTION2 BQ24773_CHARGE_OPTION2 - #define REG_PROCHOT_OPTION0 BQ24773_PROCHOT_OPTION0 - #define REG_PROCHOT_OPTION1 BQ24773_PROCHOT_OPTION1 - #define REG_CHARGE_CURRENT BQ24773_CHARGE_CURRENT - #define REG_MAX_CHARGE_VOLTAGE BQ24773_MAX_CHARGE_VOLTAGE - #define REG_MIN_SYSTEM_VOLTAGE BQ24773_MIN_SYSTEM_VOLTAGE - #define REG_INPUT_CURRENT BQ24773_INPUT_CURRENT - #define REG_DEVICE_ADDRESS BQ24773_DEVICE_ADDRESS -#endif - -#ifdef CONFIG_CHARGER_BQ24773 -static inline int raw_read8(int offset, int *value) -{ - return i2c_read8(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static inline int raw_write8(int offset, int value) -{ - return i2c_write8(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} -#endif - -static inline int raw_read16(int offset, int *value) -{ - return i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static inline int raw_write16(int offset, int value) -{ - return i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -#endif /* __CROS_EC_BQ24773_H */ diff --git a/driver/charger/bq25703.c b/driver/charger/bq25703.c deleted file mode 100644 index 4d9fd2edcd..0000000000 --- a/driver/charger/bq25703.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright 2018 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. - * - * TI bq25703 battery charger driver. - */ - -#include "battery_smart.h" -#include "bq25703.h" -#include "charge_ramp.h" -#include "charger.h" -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "i2c.h" -#include "timer.h" - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 - -#define INPUT_RESISTOR_RATIO \ - ((CONFIG_CHARGER_SENSE_RESISTOR_AC) / DEFAULT_SENSE_RESISTOR) -#define REG_TO_INPUT_CURRENT(REG) ((REG + 1) * 50 / INPUT_RESISTOR_RATIO) -#define INPUT_CURRENT_TO_REG(CUR) (((CUR) * INPUT_RESISTOR_RATIO / 50) - 1) - -#define CHARGING_RESISTOR_RATIO \ - ((CONFIG_CHARGER_SENSE_RESISTOR) / DEFAULT_SENSE_RESISTOR) -#define REG_TO_CHARGING_CURRENT(REG) ((REG) / CHARGING_RESISTOR_RATIO) -#define CHARGING_CURRENT_TO_REG(CUR) ((CUR) * CHARGING_RESISTOR_RATIO) - - -/* Console output macros */ -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) - -/* Charger parameters */ -static const struct charger_info bq25703_charger_info = { - .name = "bq25703", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = 8128 / CHARGING_RESISTOR_RATIO, - .current_min = 64 / CHARGING_RESISTOR_RATIO, - .current_step = 64 / CHARGING_RESISTOR_RATIO, - .input_current_max = 6400 / INPUT_RESISTOR_RATIO, - .input_current_min = 50 / INPUT_RESISTOR_RATIO, - .input_current_step = 50 / INPUT_RESISTOR_RATIO, -}; - -static inline int raw_read8(int offset, int *value) -{ - return i2c_read8(I2C_PORT_CHARGER, BQ25703_I2C_ADDR1, offset, value); -} - -static inline int raw_write8(int offset, int value) -{ - return i2c_write8(I2C_PORT_CHARGER, BQ25703_I2C_ADDR1, offset, value); -} - -static inline int raw_read16(int offset, int *value) -{ - return i2c_read16(I2C_PORT_CHARGER, BQ25703_I2C_ADDR1, offset, value); -} - -static inline int raw_write16(int offset, int value) -{ - return i2c_write16(I2C_PORT_CHARGER, BQ25703_I2C_ADDR1, offset, value); -} - -#ifdef CONFIG_CHARGE_RAMP_HW -static int bq25703_get_low_power_mode(int *mode) -{ - int rv; - int reg; - - rv = raw_read16(BQ25703_REG_CHARGE_OPTION_0, ®); - if (rv) - return rv; - - *mode = !!(reg & BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE); - - return EC_SUCCESS; -} - -static int bq25703_set_low_power_mode(int enable) -{ - int rv; - int reg; - - rv = raw_read16(BQ25703_REG_CHARGE_OPTION_0, ®); - if (rv) - return rv; - - if (enable) - reg |= BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE; - else - reg &= ~BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE; - - rv = raw_write16(BQ25703_REG_CHARGE_OPTION_0, reg); - if (rv) - return rv; - - return EC_SUCCESS; -} -#endif - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &bq25703_charger_info; -} - -int charger_post_init(void) -{ - /* - * Note: bq25703 power on reset state is: - * watch dog timer = 175 sec - * input current limit = ~1/2 maximum setting - * charging voltage = 0 mV - * charging current = 0 mA - * discharge on AC = disabled - */ - - /* Set charger input current limit */ - return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & BQ25703_CHARGE_OPTION_0_CHRG_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGER_CHARGE_INHIBITED) - option |= BQ25703_CHARGE_OPTION_0_CHRG_INHIBIT; - else - option &= ~BQ25703_CHARGE_OPTION_0_CHRG_INHIBIT; - - return charger_set_option(option); -} - -int charger_enable_otg_power(int enabled) -{ - /* This is controlled with the EN_OTG pin. Support not added yet. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_set_otg_current_voltage(int output_current, int output_voltage) -{ - /* Add when needed. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_is_sourcing_otg_power(int port) -{ - /* Add when needed. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_get_current(int *current) -{ - int rv, reg; - - rv = raw_read16(BQ25703_REG_CHARGE_CURRENT, ®); - if (!rv) - *current = REG_TO_CHARGING_CURRENT(reg); - - return rv; -} - -int charger_set_current(int current) -{ - return raw_write16(BQ25703_REG_CHARGE_CURRENT, - CHARGING_CURRENT_TO_REG(current)); -} - -/* Get/set charge voltage limit in mV */ -int charger_get_voltage(int *voltage) -{ - return raw_read16(BQ25703_REG_MAX_CHARGE_VOLTAGE, voltage); -} -int charger_set_voltage(int voltage) -{ - return raw_write16(BQ25703_REG_MAX_CHARGE_VOLTAGE, voltage); -} - -/* Discharge battery when on AC power. */ -int charger_discharge_on_ac(int enable) -{ - int rv, option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - option |= BQ25703_CHARGE_OPTION_0_EN_LEARN; - else - option &= ~BQ25703_CHARGE_OPTION_0_EN_LEARN; - - return charger_set_option(option); -} - -int charger_set_input_current(int input_current) -{ - return raw_write8(BQ25703_REG_IIN_HOST, - INPUT_CURRENT_TO_REG(input_current)); -} - -int charger_get_input_current(int *input_current) -{ - int rv, reg; - - /* - * IIN_DPM register reflects the actual input current limit programmed - * in the register, either from host or from ICO. After ICO, the - * current limit used by DPM regulation may differ from the IIN_HOST - * register settings. - */ - rv = raw_read8(BQ25703_REG_IIN_DPM, ®); - if (!rv) - *input_current = REG_TO_INPUT_CURRENT(reg); - - return rv; -} - -int charger_manufacturer_id(int *id) -{ - return raw_read8(BQ25703_REG_MANUFACTURER_ID, id); -} -int charger_device_id(int *id) -{ - return raw_read8(BQ25703_REG_DEVICE_ADDRESS, id); -} - -int charger_get_option(int *option) -{ - /* There are 4 option registers, but we only need the first for now. */ - return raw_read16(BQ25703_REG_CHARGE_OPTION_0, option); -} - -int charger_set_option(int option) -{ - /* There are 4 option registers, but we only need the first for now. */ - return raw_write16(BQ25703_REG_CHARGE_OPTION_0, option); -} - -#ifdef CONFIG_CHARGE_RAMP_HW - -static void bq25703_chg_ramp_handle(void) -{ - int ramp_curr; - - /* - * Once the charge ramp is stable write back the stable ramp - * current to input current register. - */ - if (chg_ramp_is_stable()) { - ramp_curr = chg_ramp_get_current_limit(); - if (ramp_curr && !charger_set_input_current(ramp_curr)) - CPRINTF("stable ramp current=%d\n", ramp_curr); - } -} -DECLARE_DEFERRED(bq25703_chg_ramp_handle); - -int charger_set_hw_ramp(int enable) -{ - int option3_reg, option2_reg, rv; - - rv = raw_read16(BQ25703_REG_CHARGE_OPTION_3, &option3_reg); - if (rv) - return rv; - rv = raw_read16(BQ25703_REG_CHARGE_OPTION_2, &option2_reg); - if (rv) - return rv; - - if (enable) { - /* Set InputVoltage register to BC1.2 minimum ramp voltage */ - rv = raw_write16(BQ25703_REG_INPUT_VOLTAGE, - BQ25703_BC12_MIN_VOLTAGE_MV); - if (rv) - return rv; - - /* Enable ICO algorithm */ - option3_reg |= BQ25703_CHARGE_OPTION_3_EN_ICO_MODE; - - /* 0b: Input current limit is set by BQ25703_REG_IIN_HOST */ - option2_reg &= ~BQ25703_CHARGE_OPTION_2_EN_EXTILIM; - - /* Charge ramp may take up to 2s to settle down */ - hook_call_deferred(&bq25703_chg_ramp_handle_data, (4 * SECOND)); - } else { - /* Disable ICO algorithm */ - option3_reg &= ~BQ25703_CHARGE_OPTION_3_EN_ICO_MODE; - - /* - * 1b: Input current limit is set by the lower value of - * ILIM_HIZ pin and BQ25703_REG_IIN_HOST - */ - option2_reg |= BQ25703_CHARGE_OPTION_2_EN_EXTILIM; - } - - rv = raw_write16(BQ25703_REG_CHARGE_OPTION_2, option2_reg); - if (rv) - return rv; - return raw_write16(BQ25703_REG_CHARGE_OPTION_3, option3_reg); -} - -int chg_ramp_is_stable(void) -{ - int reg; - - if (raw_read16(BQ25703_REG_CHARGER_STATUS, ®)) - return 0; - - return reg & BQ25703_CHARGE_STATUS_ICO_DONE; -} - -int chg_ramp_get_current_limit(void) -{ - int reg; - int mode; - int tries_left = 8; - - /* Save current mode to restore same state after ADC read */ - if (bq25703_get_low_power_mode(&mode)) - goto error; - - /* Exit low power mode so ADC conversion takes typical time */ - if (bq25703_set_low_power_mode(0)) - goto error; - - /* Turn on the ADC for one reading */ - reg = BQ25703_ADC_OPTION_ADC_START | BQ25703_ADC_OPTION_EN_ADC_IIN; - if (raw_write16(BQ25703_REG_ADC_OPTION, reg)) - goto error; - - /* - * Wait until the ADC operation completes. The spec says typical - * conversion time is 10 msec. If low power mode isn't exited first, - * then the conversion time jumps to ~60 msec. - */ - do { - msleep(2); - raw_read16(BQ25703_REG_ADC_OPTION, ®); - } while (--tries_left && (reg & BQ25703_ADC_OPTION_ADC_START)); - - /* ADC reading attempt complete, go back to low power mode */ - if (bq25703_set_low_power_mode(mode)) - goto error; - - /* Could not complete read */ - if (reg & BQ25703_ADC_OPTION_ADC_START) - goto error; - - /* Read ADC value */ - if (raw_read8(BQ25703_REG_ADC_IIN, ®)) - goto error; - - /* LSB => 50mA */ - return reg * BQ25703_ADC_IIN_STEP_MA; - -error: - CPRINTF("Could not read input current limit ADC!\n"); - return 0; -} -#endif /* CONFIG_CHARGE_RAMP_HW */ diff --git a/driver/charger/bq25703.h b/driver/charger/bq25703.h deleted file mode 100644 index f715824f63..0000000000 --- a/driver/charger/bq25703.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2018 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. - * - * TI bq25703 battery charger driver. - */ - -#ifndef __CROS_EC_BQ25703_H -#define __CROS_EC_BQ25703_H - -/* I2C Interface */ -#define BQ25703_I2C_ADDR1_FLAGS 0x6B - -/* - * BC1.2 minimum voltage threshold for BQ25703. - * BC1.2 charging port output voltage range is 4.75V to 5.25V, - * BQ25703 Input Voltage Accuracy is -2% to +2% (-95mV to +95mV) - * 4750mV - 95mV => 4655mV - 3200 (offset reg 0x0A) => 1455mv - * 1455mv & 0x1FC0 = 1408 (data for register 0x0A) - */ -#define BQ25703_BC12_MIN_VOLTAGE_MV 1408 - -/* Registers */ - -/* ChargeOption0 Register */ -#define BQ25703_REG_CHARGE_OPTION_0 0x00 -#define BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE BIT(15) -#define BQ25703_CHARGE_OPTION_0_EN_LEARN BIT(5) -#define BQ25703_CHARGE_OPTION_0_CHRG_INHIBIT BIT(0) - -#define BQ25703_REG_CHARGE_CURRENT 0x02 -#define BQ25703_REG_MAX_CHARGE_VOLTAGE 0x04 -#define BQ25703_REG_CHARGE_OPTION_1 0x30 - -/* ChargeOption2 Register */ -#define BQ25703_REG_CHARGE_OPTION_2 0x32 -#define BQ25703_CHARGE_OPTION_2_EN_EXTILIM BIT(7) - -/* ChargeOption3 Register */ -#define BQ25703_REG_CHARGE_OPTION_3 0x34 -#define BQ25703_CHARGE_OPTION_3_EN_ICO_MODE BIT(11) - -#define BQ25703_REG_PROCHOT_OPTION_0 0x36 -#define BQ25703_REG_PROCHOT_OPTION_1 0x38 - -/* ADCOption Register */ -#define BQ25703_REG_ADC_OPTION 0x3A -#define BQ25703_ADC_OPTION_ADC_START BIT(14) -#define BQ25703_ADC_OPTION_EN_ADC_IIN BIT(4) - -/* ChargeStatus Register */ -#define BQ25703_REG_CHARGER_STATUS 0x20 -#define BQ25703_CHARGE_STATUS_ICO_DONE BIT(14) - -#define BQ25703_REG_PROCHOT_STATUS 0x22 -#define BQ25703_REG_IIN_DPM 0x25 -#define BQ25703_REG_ADC_PSYS 0x26 -#define BQ25703_REG_ADC_VBUS 0x27 -#define BQ25703_REG_ADC_IBAT 0x28 -#define BQ25703_REG_ADC_CMPIN 0x2A - -/* ADCIIN Register */ -#define BQ25703_REG_ADC_IIN 0x2B -#define BQ25703_ADC_IIN_STEP_MA 50 - -#define BQ25703_REG_ADC_VSYS_VBAT 0x2C -#define BQ25703_REG_OTG_VOLTAGE 0x06 -#define BQ25703_REG_OTG_CURRENT 0x08 -#define BQ25703_REG_INPUT_VOLTAGE 0x0A -#define BQ25703_REG_MIN_SYSTEM_VOLTAGE 0x0C -#define BQ25703_REG_IIN_HOST 0x0F -#define BQ25703_REG_MANUFACTURER_ID 0x2E -#define BQ25703_REG_DEVICE_ADDRESS 0x2F - -#endif /* __CROS_EC_BQ25703_H */ diff --git a/driver/charger/bq25710.c b/driver/charger/bq25710.c deleted file mode 100644 index 8e418ea103..0000000000 --- a/driver/charger/bq25710.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright 2018 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. - * - * TI bq25710 battery charger driver. - */ - -#include "battery.h" -#include "battery_smart.h" -#include "bq25710.h" -#include "charge_ramp.h" -#include "charger.h" -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "i2c.h" -#include "task.h" -#include "timer.h" - -#ifndef CONFIG_CHARGER_NARROW_VDC -#error "BQ25710 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC." -#endif - -/* Sense resistor configurations and macros */ -#define DEFAULT_SENSE_RESISTOR 10 - -#define INPUT_RESISTOR_RATIO \ - ((CONFIG_CHARGER_SENSE_RESISTOR_AC) / DEFAULT_SENSE_RESISTOR) -#define REG_TO_INPUT_CURRENT(REG) ((REG + 1) * 50 / INPUT_RESISTOR_RATIO) -#define INPUT_CURRENT_TO_REG(CUR) (((CUR) * INPUT_RESISTOR_RATIO / 50) - 1) - -#define CHARGING_RESISTOR_RATIO \ - ((CONFIG_CHARGER_SENSE_RESISTOR) / DEFAULT_SENSE_RESISTOR) -#define REG_TO_CHARGING_CURRENT(REG) ((REG) / CHARGING_RESISTOR_RATIO) -#define CHARGING_CURRENT_TO_REG(CUR) ((CUR) * CHARGING_RESISTOR_RATIO) - -/* Console output macros */ -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) - -#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA -/* - * If this config option is defined, then the bq25710 needs to remain in - * performance mode when the AP is in S0. Performance mode is active whenever AC - * power is connected or when the EN_LWPWR bit in ChargeOption0 is clear. - */ -static uint32_t bq25710_perf_mode_req; -static struct mutex bq25710_perf_mode_mutex; -#endif - -/* Charger parameters */ -static const struct charger_info bq25710_charger_info = { - .name = "bq25710", - .voltage_max = 19200, - .voltage_min = 1024, - .voltage_step = 16, - .current_max = 8128 / CHARGING_RESISTOR_RATIO, - .current_min = 64 / CHARGING_RESISTOR_RATIO, - .current_step = 64 / CHARGING_RESISTOR_RATIO, - .input_current_max = 6400 / INPUT_RESISTOR_RATIO, - .input_current_min = 50 / INPUT_RESISTOR_RATIO, - .input_current_step = 50 / INPUT_RESISTOR_RATIO, -}; - -static inline int raw_read16(int offset, int *value) -{ - return i2c_read16(I2C_PORT_CHARGER, BQ25710_SMBUS_ADDR1_FLAGS, - offset, value); -} - -static inline int raw_write16(int offset, int value) -{ - return i2c_write16(I2C_PORT_CHARGER, BQ25710_SMBUS_ADDR1_FLAGS, - offset, value); -} - -#if defined(CONFIG_CHARGE_RAMP_HW) || \ - defined(CONFIG_USB_PD_VBUS_MEASURE_CHARGER) -static int bq25710_get_low_power_mode(int *mode) -{ - int rv; - int reg; - - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_0, ®); - if (rv) - return rv; - - *mode = !!(reg & BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE); - - return EC_SUCCESS; -} - -static int bq25710_set_low_power_mode(int enable) -{ - int rv; - int reg; - - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_0, ®); - if (rv) - return rv; - -#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA - mutex_lock(&bq25710_perf_mode_mutex); - /* - * Performance mode means not in low power mode. The bit that controls - * this is EN_LWPWR in ChargeOption0. The 'enable' param in this - * function is refeerring to low power mode, so enabling low power mode - * means disabling performance mode and vice versa. - */ - if (enable) - bq25710_perf_mode_req &= ~(1 << task_get_current()); - else - bq25710_perf_mode_req |= (1 << task_get_current()); - enable = !bq25710_perf_mode_req; -#endif - - if (enable) - reg |= BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE; - else - reg &= ~BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE; - - rv = raw_write16(BQ25710_REG_CHARGE_OPTION_0, reg); -#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA - mutex_unlock(&bq25710_perf_mode_mutex); -#endif - if (rv) - return rv; - - return EC_SUCCESS; -} - -static int bq25710_adc_start(int adc_en_mask) -{ - int reg; - int mode; - int tries_left = 8; - - /* Save current mode to restore same state after ADC read */ - if (bq25710_get_low_power_mode(&mode)) - return EC_ERROR_UNKNOWN; - - /* Exit low power mode so ADC conversion takes typical time */ - if (bq25710_set_low_power_mode(0)) - return EC_ERROR_UNKNOWN; - - /* - * Turn on the ADC for one reading. Note that adc_en_mask - * maps to bit[7:0] in ADCOption register. - */ - reg = (adc_en_mask & BQ25710_ADC_OPTION_EN_ADC_ALL) | - BQ25710_ADC_OPTION_ADC_START; - if (raw_write16(BQ25710_REG_ADC_OPTION, reg)) - return EC_ERROR_UNKNOWN; - - /* - * Wait until the ADC operation completes. The spec says typical - * conversion time is 10 msec. If low power mode isn't exited first, - * then the conversion time jumps to ~60 msec. - */ - do { - msleep(2); - raw_read16(BQ25710_REG_ADC_OPTION, ®); - } while (--tries_left && (reg & BQ25710_ADC_OPTION_ADC_START)); - - /* ADC reading attempt complete, go back to low power mode */ - if (bq25710_set_low_power_mode(mode)) - return EC_ERROR_UNKNOWN; - - /* Could not complete read */ - if (reg & BQ25710_ADC_OPTION_ADC_START) - return EC_ERROR_TIMEOUT; - - return EC_SUCCESS; -} -#endif - -static void bq25710_init(void) -{ - int reg; - int vsys; - int rv; - - /* - * Reset registers to their default settings. There is no reset pin for - * this chip so without a full power cycle, some registers may not be at - * their default values. Note, need to save the POR value of - * MIN_SYSTEM_VOLTAGE register prior to setting the reset so that the - * correct value is preserved. - */ - rv = raw_read16(BQ25710_REG_MIN_SYSTEM_VOLTAGE, &vsys); - rv |= raw_read16(BQ25710_REG_CHARGE_OPTION_3, ®); - if (!rv) { - reg |= BQ25710_CHARGE_OPTION_3_RESET_REG; - /* Set all registers to default values */ - raw_write16(BQ25710_REG_CHARGE_OPTION_3, reg); - /* Restore VSYS_MIN voltage to POR reset value */ - raw_write16(BQ25710_REG_MIN_SYSTEM_VOLTAGE, vsys); - } - - if (!raw_read16(BQ25710_REG_PROCHOT_OPTION_1, ®)) { - /* Disbale VDPM prochot profile at initialization */ - reg &= ~BQ25710_PROCHOT_PROFILE_VDPM; - /* - * Enable PROCHOT to be asserted with VSYS min detection. Note - * that when no battery is present, then VSYS will be set to the - * value in register 0x3E (MinSysVoltage) which means that when - * no battery is present prochot will continuosly be asserted. - */ - reg |= BQ25710_PROCHOT_PROFILE_VSYS; -#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA - /* - * Set the IDCHG limit who's value is defined in the config - * option in mA. Also, enable IDCHG trigger for prochot. - */ - reg &= ~BQ25710_PROCHOT_IDCHG_VTH_MASK; - /* - * IDCHG limit is in 512 mA steps. Note there is a 128 mA offset - * so the actual IDCHG limit will be the value stored in bits - * 15:10 + 128 mA. - */ - reg |= ((CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA << 1) & - BQ25710_PROCHOT_IDCHG_VTH_MASK); - reg |= BQ25710_PROCHOT_PROFILE_IDCHG; -#endif - raw_write16(BQ25710_REG_PROCHOT_OPTION_1, reg); - } - - /* Reduce ILIM from default of 150% to 105% */ - if (!raw_read16(BQ25710_REG_PROCHOT_OPTION_0, ®)) { - reg &= ~BQ25710_PROCHOT0_ILIM_VTH_MASK; - raw_write16(BQ25710_REG_PROCHOT_OPTION_0, reg); - } - - /* - * Reduce peak power mode overload and relax cycle time from default 20 - * msec to the minimum of 5 msec. - */ - if (!raw_read16(BQ25710_REG_CHARGE_OPTION_2, ®)) { - reg &= ~BQ25710_CHARGE_OPTION_2_TMAX_MASK; - raw_write16(BQ25710_REG_CHARGE_OPTION_2, reg); - } -} -DECLARE_HOOK(HOOK_INIT, bq25710_init, HOOK_PRIO_INIT_I2C + 1); - -/* Charger interfaces */ -const struct charger_info *charger_get_info(void) -{ - return &bq25710_charger_info; -} - -int charger_post_init(void) -{ - /* - * Note: bq25710 power on reset state is: - * watch dog timer = 175 sec - * input current limit = ~1/2 maximum setting - * charging voltage = 0 mV - * charging current = 0 mA - * discharge on AC = disabled - */ - - return EC_SUCCESS; -} - -int charger_get_status(int *status) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - /* Default status */ - *status = CHARGER_LEVEL_2; - - if (option & BQ25710_CHARGE_OPTION_0_CHRG_INHIBIT) - *status |= CHARGER_CHARGE_INHIBITED; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - int option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (mode & CHARGER_CHARGE_INHIBITED) - option |= BQ25710_CHARGE_OPTION_0_CHRG_INHIBIT; - else - option &= ~BQ25710_CHARGE_OPTION_0_CHRG_INHIBIT; - - return charger_set_option(option); -} - -int charger_enable_otg_power(int enabled) -{ - /* This is controlled with the EN_OTG pin. Support not added yet. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_set_otg_current_voltage(int output_current, int output_voltage) -{ - /* Add when needed. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_is_sourcing_otg_power(int port) -{ - /* Add when needed. */ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_get_current(int *current) -{ - int rv, reg; - - rv = raw_read16(BQ25710_REG_CHARGE_CURRENT, ®); - if (!rv) - *current = REG_TO_CHARGING_CURRENT(reg); - - return rv; -} - -int charger_set_current(int current) -{ - return raw_write16(BQ25710_REG_CHARGE_CURRENT, - CHARGING_CURRENT_TO_REG(current)); -} - -/* Get/set charge voltage limit in mV */ -int charger_get_voltage(int *voltage) -{ - return raw_read16(BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return raw_write16(BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); -} - -/* Discharge battery when on AC power. */ -int charger_discharge_on_ac(int enable) -{ - int rv, option; - - rv = charger_get_option(&option); - if (rv) - return rv; - - if (enable) - option |= BQ25710_CHARGE_OPTION_0_EN_LEARN; - else - option &= ~BQ25710_CHARGE_OPTION_0_EN_LEARN; - - return charger_set_option(option); -} - -int charger_set_input_current(int input_current) -{ - int num_steps = INPUT_CURRENT_TO_REG(input_current); - - return raw_write16(BQ25710_REG_IIN_HOST, num_steps << - BQ25710_CHARGE_IIN_BIT_0FFSET); -} - -int charger_get_input_current(int *input_current) -{ - int rv, reg; - - /* - * IIN_DPM register reflects the actual input current limit programmed - * in the register, either from host or from ICO. After ICO, the - * current limit used by DPM regulation may differ from the IIN_HOST - * register settings. - */ - rv = raw_read16(BQ25710_REG_IIN_DPM, ®); - if (!rv) - *input_current = - REG_TO_INPUT_CURRENT((reg >> - BQ25710_CHARGE_IIN_BIT_0FFSET)); - - return rv; -} - -int charger_manufacturer_id(int *id) -{ - return raw_read16(BQ25710_REG_MANUFACTURER_ID, id); -} - -int charger_device_id(int *id) -{ - return raw_read16(BQ25710_REG_DEVICE_ADDRESS, id); -} - -#ifdef CONFIG_USB_PD_VBUS_MEASURE_CHARGER -int charger_get_vbus_voltage(int port) -{ - int reg, rv; - - rv = bq25710_adc_start(BQ25710_ADC_OPTION_EN_ADC_VBUS); - if (rv) - goto error; - - /* Read ADC value */ - rv = raw_read16(BQ25710_REG_ADC_VBUS_PSYS, ®); - if (rv) - goto error; - - reg >>= BQ25710_ADC_VBUS_STEP_BIT_OFFSET; - /* - * LSB => 64mV. - * Return 0 when VBUS <= 3.2V as ADC can't measure it. - */ - return reg ? - (reg * BQ25710_ADC_VBUS_STEP_MV + BQ25710_ADC_VBUS_BASE_MV) : 0; - -error: - CPRINTF("Could not read VBUS ADC! Error: %d\n", rv); - return 0; -} -#endif - -int charger_get_option(int *option) -{ - /* There are 4 option registers, but we only need the first for now. */ - return raw_read16(BQ25710_REG_CHARGE_OPTION_0, option); -} - -int charger_set_option(int option) -{ - /* There are 4 option registers, but we only need the first for now. */ - return raw_write16(BQ25710_REG_CHARGE_OPTION_0, option); -} - -#ifdef CONFIG_CHARGE_RAMP_HW - -static void bq25710_chg_ramp_handle(void) -{ - int ramp_curr; - - /* - * Once the charge ramp is stable write back the stable ramp - * current to the host input current limit register - */ - ramp_curr = chg_ramp_get_current_limit(); - if (chg_ramp_is_stable()) { - if (ramp_curr && !charger_set_input_current(ramp_curr)) - CPRINTF("bq25710: stable ramp current=%d\n", ramp_curr); - } else { - CPRINTF("bq25710: ICO stall, ramp current=%d\n", ramp_curr); - } - /* - * Disable ICO mode. When ICO mode is active the input current limit is - * given by the value in register IIN_DPM (0x22) - */ - charger_set_hw_ramp(0); -} -DECLARE_DEFERRED(bq25710_chg_ramp_handle); - -int charger_set_hw_ramp(int enable) -{ - int option3_reg, option2_reg, rv; - - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_3, &option3_reg); - if (rv) - return rv; - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_2, &option2_reg); - if (rv) - return rv; - - if (enable) { - /* - * ICO mode can only be used when a battery is present. If there - * is no battery, then enabling ICO mode will lead to VSYS - * dropping out. - */ - if (!battery_is_present()) { - CPRINTF("bq25710: no battery, skip ICO enable\n"); - return EC_ERROR_UNKNOWN; - } - - /* Set InputVoltage register to BC1.2 minimum ramp voltage */ - rv = raw_write16(BQ25710_REG_INPUT_VOLTAGE, - BQ25710_BC12_MIN_VOLTAGE_MV); - if (rv) - return rv; - - /* Enable ICO algorithm */ - option3_reg |= BQ25710_CHARGE_OPTION_3_EN_ICO_MODE; - - /* 0b: Input current limit is set by BQ25710_REG_IIN_HOST */ - option2_reg &= ~BQ25710_CHARGE_OPTION_2_EN_EXTILIM; - - /* Charge ramp may take up to 2s to settle down */ - hook_call_deferred(&bq25710_chg_ramp_handle_data, (4 * SECOND)); - } else { - /* Disable ICO algorithm */ - option3_reg &= ~BQ25710_CHARGE_OPTION_3_EN_ICO_MODE; - - /* - * 1b: Input current limit is set by the lower value of - * ILIM_HIZ pin and BQ25710_REG_IIN_HOST - */ - option2_reg |= BQ25710_CHARGE_OPTION_2_EN_EXTILIM; - } - - rv = raw_write16(BQ25710_REG_CHARGE_OPTION_2, option2_reg); - if (rv) - return rv; - return raw_write16(BQ25710_REG_CHARGE_OPTION_3, option3_reg); -} - -int chg_ramp_is_stable(void) -{ - int reg; - - if (raw_read16(BQ25710_REG_CHARGER_STATUS, ®)) - return 0; - - return reg & BQ25710_CHARGE_STATUS_ICO_DONE; -} - -int chg_ramp_get_current_limit(void) -{ - int reg, rv; - - rv = raw_read16(BQ25710_REG_IIN_DPM, ®); - if (rv) { - CPRINTF("Could not read iin_dpm current limit! Error: %d\n", - rv); - return 0; - } - - return ((reg >> BQ25710_IIN_DPM_BIT_SHIFT) * BQ25710_IIN_DPM_STEP_MA + - BQ25710_IIN_DPM_STEP_MA); -} -#endif /* CONFIG_CHARGE_RAMP_HW */ - -#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA -/* Called on AP S5 -> S3 and S3/S0iX -> S0 transition */ -static void bq25710_chipset_startup(void) -{ - bq25710_set_low_power_mode(0); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, bq25710_chipset_startup, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, bq25710_chipset_startup, HOOK_PRIO_DEFAULT); - - -/* Called on AP S0 -> S0iX/S3 or S3 -> S5 transition */ -static void bq25710_chipset_suspend(void) -{ - bq25710_set_low_power_mode(1); -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT); -#endif - -#ifdef CONFIG_CMD_CHARGER_DUMP -static int console_bq25710_dump_regs(int argc, char **argv) -{ - int i; - int val; - - /* Dump all readable registers on bq25710. */ - static const uint8_t regs[] = { - BQ25710_REG_CHARGE_OPTION_0, - BQ25710_REG_CHARGE_CURRENT, - BQ25710_REG_MAX_CHARGE_VOLTAGE, - BQ25710_REG_CHARGE_OPTION_1, - BQ25710_REG_CHARGE_OPTION_2, - BQ25710_REG_CHARGE_OPTION_3, - BQ25710_REG_PROCHOT_OPTION_0, - BQ25710_REG_PROCHOT_OPTION_1, - BQ25710_REG_ADC_OPTION, - BQ25710_REG_CHARGER_STATUS, - BQ25710_REG_PROCHOT_STATUS, - BQ25710_REG_IIN_DPM, - BQ25710_REG_ADC_VBUS_PSYS, - BQ25710_REG_ADC_IBAT, - BQ25710_REG_ADC_CMPIN_IIN, - BQ25710_REG_ADC_VSYS_VBAT, - BQ25710_REG_PROCHOT_OPTION_1, - BQ25710_REG_OTG_VOLTAGE, - BQ25710_REG_OTG_CURRENT, - BQ25710_REG_INPUT_VOLTAGE, - BQ25710_REG_MIN_SYSTEM_VOLTAGE, - BQ25710_REG_IIN_HOST, - BQ25710_REG_MANUFACTURER_ID, - BQ25710_REG_DEVICE_ADDRESS, - }; - - for (i = 0; i < ARRAY_SIZE(regs); ++i) { - if (raw_read16(regs[i], &val)) - continue; - ccprintf("BQ25710 REG 0x%02x: 0x%04x\n", regs[i], val); - } - - return 0; -} -DECLARE_CONSOLE_COMMAND(charger_dump, console_bq25710_dump_regs, - "", - "Dump all charger registers"); - -#endif /* CONFIG_CMD_CHARGER_DUMP */ diff --git a/driver/charger/bq25710.h b/driver/charger/bq25710.h deleted file mode 100644 index 014799a832..0000000000 --- a/driver/charger/bq25710.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright 2018 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. - * - * TI bq25710 battery charger driver. - */ - -#ifndef __CROS_EC_BQ25710_H -#define __CROS_EC_BQ25710_H - -/* SMBUS Interface */ -#define BQ25710_SMBUS_ADDR1_FLAGS 0x09 - -#define BQ25710_BC12_MIN_VOLTAGE_MV 1408 - -/* Registers */ -#define BQ25710_REG_CHARGE_OPTION_0 0x12 -#define BQ25710_REG_CHARGE_CURRENT 0x14 -#define BQ25710_REG_MAX_CHARGE_VOLTAGE 0x15 -#define BQ25710_REG_CHARGE_OPTION_1 0x30 -#define BQ25710_REG_CHARGE_OPTION_2 0x31 -#define BQ25710_REG_CHARGE_OPTION_3 0x32 -#define BQ25710_REG_PROCHOT_OPTION_0 0x33 -#define BQ25710_REG_PROCHOT_OPTION_1 0x34 -#define BQ25710_REG_ADC_OPTION 0x35 -#define BQ25710_REG_CHARGER_STATUS 0x20 -#define BQ25710_REG_PROCHOT_STATUS 0x21 -#define BQ25710_REG_IIN_DPM 0x22 -#define BQ25710_REG_ADC_VBUS_PSYS 0x23 -#define BQ25710_REG_ADC_IBAT 0x24 -#define BQ25710_REG_ADC_CMPIN_IIN 0x25 -#define BQ25710_REG_ADC_VSYS_VBAT 0x2C -#define BQ25710_REG_PROCHOT_OPTION_1 0x34 -#define BQ25710_REG_OTG_VOLTAGE 0x3B -#define BQ25710_REG_OTG_CURRENT 0x3C -#define BQ25710_REG_INPUT_VOLTAGE 0x3D -#define BQ25710_REG_MIN_SYSTEM_VOLTAGE 0x3E -#define BQ25710_REG_IIN_HOST 0x3F -#define BQ25710_REG_MANUFACTURER_ID 0xFE -#define BQ25710_REG_DEVICE_ADDRESS 0xFF - -/* ChargeOption0 Register */ -#define BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE BIT(15) -#define BQ25710_CHARGE_OPTION_0_IDPM_AUTO_DIS BIT(12) -#define BQ25710_CHARGE_OPTION_0_EN_LEARN BIT(5) -#define BQ25710_CHARGE_OPTION_0_EN_IDPM BIT(1) -#define BQ25710_CHARGE_OPTION_0_CHRG_INHIBIT BIT(0) - -/* ChargeOption2 Register */ -#define BQ25710_CHARGE_OPTION_2_EN_EXTILIM BIT(7) -#define BQ25710_CHARGE_OPTION_2_TMAX_SHIFT 8 -#define BQ25710_CHARGE_OPTION_2_TMAX_MASK (0x3 << \ - BQ25710_CHARGE_OPTION_2_TMAX_SHIFT) - -/* ChargeOption3 Register */ -#define BQ25710_CHARGE_OPTION_3_RESET_REG BIT(14) -#define BQ25710_CHARGE_OPTION_3_EN_ICO_MODE BIT(11) - -/* ChargeStatus Register */ -#define BQ25710_CHARGE_STATUS_ICO_DONE BIT(14) - -/* IIN_DPM Register */ -#define BQ25710_CHARGE_IIN_BIT_0FFSET 8 -#define BQ25710_CHARGE_MA_PER_STEP 50 - -/* ADCOption Register */ -#define BQ25710_ADC_OPTION_ADC_START BIT(14) -#define BQ25710_ADC_OPTION_EN_ADC_VBUS BIT(6) -#define BQ25710_ADC_OPTION_EN_ADC_IIN BIT(4) -#define BQ25710_ADC_OPTION_EN_ADC_ALL 0xFF - -/* ADCVBUS/PSYS Register */ -#define BQ25710_ADC_VBUS_STEP_MV 64 -#define BQ25710_ADC_VBUS_BASE_MV 3200 -#define BQ25710_ADC_VBUS_STEP_BIT_OFFSET 8 - -/* ADCIIN Register */ -#define BQ25710_ADC_IIN_STEP_MA 50 -#define BQ25710_ADC_IIN_STEP_BIT_OFFSET 8 - -/* ProchotOption0 Register */ -#define BQ25710_PROCHOT0_ILIM_VTH_SHIFT 11 -#define BQ25710_PROCHOT0_ILIM_VTH_MASK (0x1f << \ - BQ25710_PROCHOT0_ILIM_VTH_SHIFT) - -/* ProchotOption1 Register */ -#define BQ25710_PROCHOT_PROFILE_VDPM BIT(7) -#define BQ25710_PROCHOT_PROFILE_IDCHG BIT(3) -#define BQ25710_PROCHOT_PROFILE_VSYS BIT(2) -#define BQ25710_PROCHOT_IDCHG_VTH_MASK 0xFC00 - -/* IIN_DPM Register */ -#define BQ25710_IIN_DPM_BIT_SHIFT 8 -#define BQ25710_IIN_DPM_STEP_MA 50 - -#endif /* __CROS_EC_BQ25710_H */ diff --git a/driver/charger/bq2589x.c b/driver/charger/bq2589x.c deleted file mode 100644 index 966a0d0016..0000000000 --- a/driver/charger/bq2589x.c +++ /dev/null @@ -1,394 +0,0 @@ -/* Copyright 2015 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. - * - * TI bq25890/bq25892/bq25895 battery charger driver. - */ - -#include "config.h" -#include "bq2589x.h" -#include "charger.h" -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "i2c.h" -#include "printf.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHARGER, outstr) -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) - -/* 5V Boost settings */ -#ifndef CONFIG_CHARGER_BQ2589X_BOOST -#define CONFIG_CHARGER_BQ2589X_BOOST BQ2589X_BOOST_DEFAULT -#endif - -/* IR compensation settings */ -#ifndef CONFIG_CHARGER_BQ2589X_IR_COMP -#define CONFIG_CHARGER_BQ2589X_IR_COMP BQ2589X_IR_COMP_DEFAULT -#endif - -/* Termination current limit setting */ -#ifndef CONFIG_CHARGER_TERM_CURRENT_LIMIT -#define CONFIG_CHARGER_TERM_CURRENT_LIMIT BQ2589X_TERM_CURRENT_LIMIT_DEFAULT -#endif - -/* Charger information */ -static const struct charger_info bq2589x_charger_info = { - .name = "bq2589x", - .voltage_max = 4608, - .voltage_min = 3840, - .voltage_step = 16, - .current_max = 5056, - .current_min = 0, - .current_step = 64, - .input_current_max = 3250, - .input_current_min = 100, - .input_current_step = 50, -}; - -static int bq2589x_read(int reg, int *value) -{ - return i2c_read8(I2C_PORT_CHARGER, BQ2589X_ADDR, reg, value); -} - -static int bq2589x_write(int reg, int value) -{ - return i2c_write8(I2C_PORT_CHARGER, BQ2589X_ADDR, reg, value); -} - -static int bq2589x_watchdog_reset(void) -{ - int rv, val; - - rv = bq2589x_read(BQ2589X_REG_CFG2, &val); - if (rv) - return rv; - val |= BQ2589X_CFG2_WD_RST; - return bq2589x_write(BQ2589X_REG_CFG2, val); -} - -static int bq2589x_set_terminate_current(int current) -{ - int reg_val, rv; - int val = (current - 64) / 64; - - rv = bq2589x_read(BQ2589X_REG_PRE_CHG_CURR, ®_val); - if (rv) - return rv; - reg_val = (reg_val & ~0xf) | (val & 0xf); - return bq2589x_write(BQ2589X_REG_PRE_CHG_CURR, reg_val); -} - -#ifdef CONFIG_CHARGER_OTG -int charger_enable_otg_power(int enabled) -{ - int val, rv; - - rv = bq2589x_read(BQ2589X_REG_CFG2, &val); - if (rv) - return rv; - val = (val & ~(BQ2589X_CFG2_CHG_CONFIG | BQ2589X_CFG2_OTG_CONFIG)) - | (enabled ? BQ2589X_CFG2_OTG_CONFIG : BQ2589X_CFG2_CHG_CONFIG); - return bq2589x_write(BQ2589X_REG_CFG2, val); -} -#endif - -int charger_set_input_current(int input_current) -{ - int value, rv; - const struct charger_info * const info = charger_get_info(); - - input_current -= info->input_current_min; - if (input_current < 0) - input_current = 0; - - rv = bq2589x_read(BQ2589X_REG_INPUT_CURR, &value); - if (rv) - return rv; - value = value & ~(0x3f); - value |= (input_current / info->input_current_step) & 0x3f; - return bq2589x_write(BQ2589X_REG_INPUT_CURR, value); -} - -int charger_get_input_current(int *input_current) -{ - int rv, value; - const struct charger_info * const info = charger_get_info(); - - rv = bq2589x_read(BQ2589X_REG_INPUT_CURR, &value); - if (rv) - return rv; - - *input_current = (value & 0x3f) * info->input_current_step - + info->input_current_min; - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_device_id(int *id) -{ - int res = bq2589x_read(BQ2589X_REG_ID, id); - - if (res == EC_SUCCESS) - *id &= BQ2589X_DEVICE_ID_MASK; - - return res; -} - -int charger_get_option(int *option) -{ - /* Ignored: does not exist */ - *option = 0; - return EC_SUCCESS; -} - -int charger_set_option(int option) -{ - /* Ignored: does not exist */ - return EC_SUCCESS; -} - -const struct charger_info *charger_get_info(void) -{ - return &bq2589x_charger_info; -} - -int charger_get_status(int *status) -{ - /* TODO(crosbug.com/p/38603) implement using REG0C value */ - *status = 0; - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - return EC_SUCCESS; -} - -int charger_get_current(int *current) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - rv = bq2589x_read(BQ2589X_REG_CHG_CURR, &val); - if (rv) - return rv; - *current = val * info->current_step + info->current_min; - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - const struct charger_info * const info = charger_get_info(); - - current = charger_closest_current(current); - - return bq2589x_write(BQ2589X_REG_CHG_CURR, - current / info->current_step); -} - -int charger_get_voltage(int *voltage) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - rv = bq2589x_read(BQ2589X_REG_CHG_VOLT, &val); - if (rv) - return rv; - val = (val >> 2) & 0x3f; - *voltage = val * info->voltage_step + info->voltage_min; - return EC_SUCCESS; -} - -int charger_set_voltage(int voltage) -{ - int rv, val; - const struct charger_info * const info = charger_get_info(); - - voltage = charger_closest_voltage(voltage); - - rv = bq2589x_read(BQ2589X_REG_CHG_VOLT, &val); - if (rv) - return rv; - val = val & 0x3; - val |= ((voltage - info->voltage_min) / info->voltage_step) << 2; - return bq2589x_write(BQ2589X_REG_CHG_VOLT, val); -} - -int charger_discharge_on_ac(int enable) -{ - int rv, val; - - rv = bq2589x_read(BQ2589X_REG_INPUT_CURR, &val); - if (rv) - return rv; - - if (enable) - val |= BQ2589X_INPUT_CURR_EN_HIZ; - else - val &= ~BQ2589X_INPUT_CURR_EN_HIZ; - - return bq2589x_write(BQ2589X_REG_INPUT_CURR, val); -} - -/* Charging power state initialization */ -int charger_post_init(void) -{ -#ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED - int val, rv; - /* Ignore ILIM pin value */ - rv = bq2589x_read(BQ2589X_REG_INPUT_CURR, &val); - if (rv) - return rv; - val &= ~BQ2589X_INPUT_CURR_EN_ILIM; - rv = bq2589x_write(BQ2589X_REG_INPUT_CURR, val); - if (rv) - return rv; -#endif /* CONFIG_CHARGER_ILIM_PIN_DISABLED */ - - /* Input current controlled by extpower module. Do nothing here. */ - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* Hardware current ramping (aka ICO: Input Current Optimizer) */ - -#ifdef CONFIG_CHARGE_RAMP_HW -int charger_set_hw_ramp(int enable) -{ - int val, rv; - - rv = i2c_read8(I2C_PORT_CHARGER, BQ2589X_ADDR, BQ2589X_REG_CFG1, &val); - if (rv) - return rv; - - if (enable) - val |= BQ2589X_CFG1_ICO_EN; - else - val &= ~BQ2589X_CFG1_ICO_EN; - - return i2c_write8(I2C_PORT_CHARGER, BQ2589X_ADDR, BQ2589X_REG_CFG1, - val); -} - -int chg_ramp_is_stable(void) -{ - int val, rv; - - rv = bq2589x_read(BQ2589X_REG_ID, &val); - if (!rv && (val & BQ2589X_ID_ICO_OPTIMIZED)) - return 1; - else - return 0; -} - -int chg_ramp_is_detected(void) -{ - return 1; -} - -int chg_ramp_get_current_limit(void) -{ - int input_ma, rv; - - rv = bq2589x_read(BQ2589X_REG_ADC_INPUT_CURR, &input_ma); - - return rv ? -1 : 100 + (input_ma & 0x3f) * 50; -} -#endif /* CONFIG_CHARGE_RAMP_HW */ - -/*****************************************************************************/ -/* Hooks */ - -static void bq2589x_init(void) -{ - int val; - - if (charger_device_id(&val) || val != BQ2589X_DEVICE_ID) { - CPRINTF("BQ2589X incorrent ID: 0x%02x\n", val); - return; - } - - /* - * Disable I2C watchdog timer. - * - * TODO(crosbug.com/p/38603): Re-enable watchdog timer and kick it - * periodically in charger task. - */ - if (bq2589x_read(BQ2589X_REG_TIMER, &val)) - return; - val &= ~0x30; - if (bq2589x_write(BQ2589X_REG_TIMER, val)) - return; - - if (bq2589x_set_terminate_current(CONFIG_CHARGER_TERM_CURRENT_LIMIT)) - return; - - if (bq2589x_watchdog_reset()) - return; - - if (bq2589x_write(BQ2589X_REG_IR_COMP, CONFIG_CHARGER_BQ2589X_IR_COMP)) - return; - - if (bq2589x_write(BQ2589X_REG_BOOST_MODE, CONFIG_CHARGER_BQ2589X_BOOST)) - return; - - CPRINTF("BQ2589%c initialized\n", - BQ2589X_DEVICE_ID == BQ25890_DEVICE_ID ? '0' : - (BQ2589X_DEVICE_ID == BQ25895_DEVICE_ID ? '5' : '2')); -} -DECLARE_HOOK(HOOK_INIT, bq2589x_init, HOOK_PRIO_LAST); - -/*****************************************************************************/ -/* Console commands */ -#ifdef CONFIG_CMD_CHARGER -static int command_bq2589x(int argc, char **argv) -{ - int i; - int value; - int rv; - int batt_mv, sys_mv, vbus_mv, chg_ma, input_ma; - - /* Trigger one ADC conversion */ - bq2589x_read(BQ2589X_REG_CFG1, &value); - bq2589x_write(BQ2589X_REG_CFG1, value | BQ2589X_CFG1_CONV_START); - do { - bq2589x_read(BQ2589X_REG_CFG1, &value); - } while (value & BQ2589X_CFG1_CONV_START); /* Wait for End of Conv. */ - - bq2589x_read(BQ2589X_REG_ADC_BATT_VOLT, &batt_mv); - bq2589x_read(BQ2589X_REG_ADC_SYS_VOLT, &sys_mv); - bq2589x_read(BQ2589X_REG_ADC_VBUS_VOLT, &vbus_mv); - bq2589x_read(BQ2589X_REG_ADC_CHG_CURR, &chg_ma); - bq2589x_read(BQ2589X_REG_ADC_INPUT_CURR, &input_ma); - ccprintf("ADC Batt %dmV Sys %dmV VBUS %dmV Chg %dmA Input %dmA\n", - 2304 + (batt_mv & 0x7f) * 20, 2304 + sys_mv * 20, - 2600 + (vbus_mv & 0x7f) * 100, - chg_ma * 50, 100 + (input_ma & 0x3f) * 50); - - ccprintf("REG:"); - for (i = 0; i <= 0x14; ++i) - ccprintf(" %02x", i); - ccprintf("\n"); - - ccprintf("VAL:"); - for (i = 0; i <= 0x14; ++i) { - rv = bq2589x_read(i, &value); - if (rv) - return rv; - ccprintf(" %02x", value); - } - ccprintf("\n"); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(bq2589x, command_bq2589x, - NULL, NULL); -#endif diff --git a/driver/charger/bq2589x.h b/driver/charger/bq2589x.h deleted file mode 100644 index 95bbf4c226..0000000000 --- a/driver/charger/bq2589x.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright 2015 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. - * - * TI bq25890/bq25892/bq25895 battery charger driver. - */ - -#ifndef __CROS_EC_BQ2589X_H -#define __CROS_EC_BQ2589X_H - -/* Registers */ -#define BQ2589X_REG_INPUT_CURR 0x00 -#define BQ2589X_REG_VINDPM 0x01 -#define BQ2589X_REG_CFG1 0x02 -#define BQ2589X_REG_CFG2 0x03 -#define BQ2589X_REG_CHG_CURR 0x04 -#define BQ2589X_REG_PRE_CHG_CURR 0x05 -#define BQ2589X_REG_CHG_VOLT 0x06 -#define BQ2589X_REG_TIMER 0x07 -#define BQ2589X_REG_IR_COMP 0x08 -#define BQ2589X_REG_FORCE 0x09 -#define BQ2589X_REG_BOOST_MODE 0x0A -#define BQ2589X_REG_STATUS 0x0B /* Read-only */ -#define BQ2589X_REG_FAULT 0x0C /* Read-only */ -#define BQ2589X_REG_VINDPM_THRESH 0x0D -#define BQ2589X_REG_ADC_BATT_VOLT 0x0E /* Read-only */ -#define BQ2589X_REG_ADC_SYS_VOLT 0x0F /* Read-only */ -#define BQ2589X_REG_ADC_TS 0x10 /* Read-only */ -#define BQ2589X_REG_ADC_VBUS_VOLT 0x11 /* Read-only */ -#define BQ2589X_REG_ADC_CHG_CURR 0x12 /* Read-only */ -#define BQ2589X_REG_ADC_INPUT_CURR 0x13 /* Read-only */ -#define BQ2589X_REG_ID 0x14 - -/* REG00 : input current register bit definitions */ -#define BQ2589X_INPUT_CURR_EN_HIZ (1<<7) -#define BQ2589X_INPUT_CURR_EN_ILIM (1<<6) - -/* REG02 : first configuration register bit definitions */ -#define BQ2589X_CFG1_CONV_START (1<<7) -#define BQ2589X_CFG1_ICO_EN (1<<4) -#define BQ2589X_CFG1_AUTO_DPDM_EN (1<<0) - -/* REG03 : second configuration register bit definitions */ -#define BQ2589X_CFG2_CHG_CONFIG (1<<4) -#define BQ2589X_CFG2_OTG_CONFIG (1<<5) -#define BQ2589X_CFG2_WD_RST (1<<6) - -/* REG08 : IR compensation definitions */ -#define BQ2589X_IR_BAT_COMP_140MOHM (7 << 5) -#define BQ2589X_IR_BAT_COMP_120MOHM (6 << 5) -#define BQ2589X_IR_BAT_COMP_100MOHM (5 << 5) -#define BQ2589X_IR_BAT_COMP_80MOHM (4 << 5) -#define BQ2589X_IR_BAT_COMP_60MOHM (3 << 5) -#define BQ2589X_IR_BAT_COMP_40MOHM (2 << 5) -#define BQ2589X_IR_BAT_COMP_20MOHM BIT(5) -#define BQ2589X_IR_BAT_COMP_0MOHM (0 << 5) -#define BQ2589X_IR_VCLAMP_224MV (7 << 2) -#define BQ2589X_IR_VCLAMP_192MV (6 << 2) -#define BQ2589X_IR_VCLAMP_160MV (5 << 2) -#define BQ2589X_IR_VCLAMP_128MV (4 << 2) -#define BQ2589X_IR_VCLAMP_96MV (3 << 2) -#define BQ2589X_IR_VCLAMP_64MV (2 << 2) -#define BQ2589X_IR_VCLAMP_32MV BIT(2) -#define BQ2589X_IR_VCLAMP_0MV (0 << 2) -#define BQ2589X_IR_TREG_120C (3 << 0) -#define BQ2589X_IR_TREG_100C (2 << 0) -#define BQ2589X_IR_TREG_80C BIT(0) -#define BQ2589X_IR_TREG_60C (0 << 0) - -#define BQ2589X_IR_COMP_DEFAULT (BQ2589X_IR_TREG_120C | BQ2589X_IR_VCLAMP_0MV |\ - BQ2589X_IR_BAT_COMP_0MOHM) - -#define BQ2589X_TERM_CURRENT_LIMIT_DEFAULT 256 - -/* 5V VBUS Boost settings */ -#define BQ2589X_BOOSTV_MV(mv) (((((mv) - 4550)/64) & 0xF) << 4) -#define BQ2589X_BOOSTV_DEFAULT BQ2589X_BOOSTV_MV(4998) -#define BQ2589X_BOOST_LIM_500MA 0x00 -#define BQ2589X_BOOST_LIM_750MA 0x01 -#define BQ2589X_BOOST_LIM_1200MA 0x02 -#define BQ2589X_BOOST_LIM_1400MA 0x03 -#define BQ2589X_BOOST_LIM_1650MA 0x04 -#define BQ2589X_BOOST_LIM_1875MA 0x05 -#define BQ2589X_BOOST_LIM_2150MA 0x06 -#define BQ2589X_BOOST_LIM_2450MA 0x07 -#define BQ2589X_BOOST_LIM_DEFAULT BQ2589X_BOOST_LIM_1400MA -#define BQ2589X_BOOST_DEFAULT (BQ2589X_BOOST_LIM_DEFAULT |\ - BQ2589X_BOOSTV_DEFAULT) - -/* REG14: Device ID, reset and ICO status */ -#define BQ2589X_DEVICE_ID_MASK 0x38 -#define BQ25890_DEVICE_ID 0x18 -#define BQ25892_DEVICE_ID 0x00 -#define BQ25895_DEVICE_ID 0x38 - -#define BQ2589X_ID_ICO_OPTIMIZED 0x40 - - -/* Variant-specific configuration */ -#if defined(CONFIG_CHARGER_BQ25890) -#define BQ2589X_DEVICE_ID BQ25890_DEVICE_ID -#define BQ2589X_ADDR_FLAGS 0x6A -#elif defined(CONFIG_CHARGER_BQ25895) -#define BQ2589X_DEVICE_ID BQ25895_DEVICE_ID -#define BQ2589X_ADDR_FLAGS 0x6A -#elif defined(CONFIG_CHARGER_BQ25892) -#define BQ2589X_DEVICE_ID BQ25892_DEVICE_ID -#define BQ2589X_ADDR_FLAGS 0x6B -#else -#error BQ2589X unknown variant -#endif - -#endif /* __CROS_EC_BQ2589X_H */ diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c deleted file mode 100644 index 7a02f62ca0..0000000000 --- a/driver/charger/isl923x.c +++ /dev/null @@ -1,741 +0,0 @@ -/* Copyright 2015 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. - * - * Intersil ISL-9237/8 battery charger driver. - */ - -#include "adc.h" -#include "battery.h" -#include "battery_smart.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "hooks.h" -#include "i2c.h" -#include "isl923x.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#ifndef CONFIG_CHARGER_NARROW_VDC -#error "ISL9237/8 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC." -#endif - -#define DEFAULT_R_AC 20 -#define DEFAULT_R_SNS 10 -#define R_AC CONFIG_CHARGER_SENSE_RESISTOR_AC -#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR -#define REG_TO_CURRENT(REG) ((REG) * DEFAULT_R_SNS / R_SNS) -#define CURRENT_TO_REG(CUR) ((CUR) * R_SNS / DEFAULT_R_SNS) -#define AC_REG_TO_CURRENT(REG) ((REG) * DEFAULT_R_AC / R_AC) -#define AC_CURRENT_TO_REG(CUR) ((CUR) * R_AC / DEFAULT_R_AC) - -/* Console output macros */ -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) -#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) - -static int learn_mode; - -/* Mutex for CONTROL1 register, that can be updated from multiple tasks. */ -static struct mutex control1_mutex; - -/* Charger parameters */ -static const struct charger_info isl9237_charger_info = { - .name = CHARGER_NAME, - .voltage_max = CHARGE_V_MAX, - .voltage_min = CHARGE_V_MIN, - .voltage_step = CHARGE_V_STEP, - .current_max = REG_TO_CURRENT(CHARGE_I_MAX), - .current_min = REG_TO_CURRENT(CHARGE_I_MIN), - .current_step = REG_TO_CURRENT(CHARGE_I_STEP), - .input_current_max = AC_REG_TO_CURRENT(INPUT_I_MAX), - .input_current_min = AC_REG_TO_CURRENT(INPUT_I_MIN), - .input_current_step = AC_REG_TO_CURRENT(INPUT_I_STEP), -}; - -static inline int raw_read8(int offset, int *value) -{ - return i2c_read8(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static inline int raw_read16(int offset, int *value) -{ - return i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static inline int raw_write16(int offset, int value) -{ - return i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static int isl9237_set_current(uint16_t current) -{ - return raw_write16(ISL923X_REG_CHG_CURRENT, CURRENT_TO_REG(current)); -} - -static int isl9237_set_voltage(uint16_t voltage) -{ - return raw_write16(ISL923X_REG_SYS_VOLTAGE_MAX, voltage); -} - -/* chip specific interfaces */ - -int charger_set_input_current(int input_current) -{ - int rv; - uint16_t reg = AC_CURRENT_TO_REG(input_current); - - rv = raw_write16(ISL923X_REG_ADAPTER_CURRENT1, reg); - if (rv) - return rv; - - return raw_write16(ISL923X_REG_ADAPTER_CURRENT2, reg); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int reg; - - rv = raw_read16(ISL923X_REG_ADAPTER_CURRENT1, ®); - if (rv) - return rv; - - *input_current = AC_REG_TO_CURRENT(reg); - return EC_SUCCESS; -} - -#if defined(CONFIG_CHARGER_OTG) && defined(CONFIG_CHARGER_ISL9238) -int charger_enable_otg_power(int enabled) -{ - int rv, control1; - - mutex_lock(&control1_mutex); - - rv = raw_read16(ISL923X_REG_CONTROL1, &control1); - if (rv) - goto out; - - if (enabled) - control1 |= ISL923X_C1_OTG; - else - control1 &= ~ISL923X_C1_OTG; - - rv = raw_write16(ISL923X_REG_CONTROL1, control1); - -out: - mutex_unlock(&control1_mutex); - - return rv; -} - -/* - * TODO(b:67920792): OTG is not implemented for ISL9237 that has different - * register scale and range. - */ -int charger_set_otg_current_voltage(int output_current, int output_voltage) -{ - int rv; - uint16_t volt_reg = (output_voltage / ISL9238_OTG_VOLTAGE_STEP) - << ISL9238_OTG_VOLTAGE_SHIFT; - uint16_t current_reg = - DIV_ROUND_UP(output_current, ISL923X_OTG_CURRENT_STEP) - << ISL923X_OTG_CURRENT_SHIFT; - - if (output_current < 0 || output_current > ISL923X_OTG_CURRENT_MAX || - output_voltage > ISL9238_OTG_VOLTAGE_MAX) - return EC_ERROR_INVAL; - - /* Set voltage. */ - rv = raw_write16(ISL923X_REG_OTG_VOLTAGE, volt_reg); - if (rv) - return rv; - - /* Set current. */ - return raw_write16(ISL923X_REG_OTG_CURRENT, current_reg); -} -#endif /* CONFIG_CHARGER_OTG && CONFIG_CHARGER_ISL9238 */ - -int charger_manufacturer_id(int *id) -{ - int rv; - int reg; - - rv = raw_read16(ISL923X_REG_MANUFACTURER_ID, ®); - if (rv) - return rv; - - *id = reg; - return EC_SUCCESS; -} - -int charger_device_id(int *id) -{ - int rv; - int reg; - - rv = raw_read16(ISL923X_REG_DEVICE_ID, ®); - if (rv) - return rv; - - *id = reg; - return EC_SUCCESS; -} - -int charger_get_option(int *option) -{ - int rv; - uint32_t controls; - int reg; - - rv = raw_read16(ISL923X_REG_CONTROL0, ®); - if (rv) - return rv; - - controls = reg; - rv = raw_read16(ISL923X_REG_CONTROL1, ®); - if (rv) - return rv; - - controls |= reg << 16; - *option = controls; - return EC_SUCCESS; -} - -int charger_set_option(int option) -{ - int rv; - uint16_t reg; - - reg = option & 0xffff; - rv = raw_write16(ISL923X_REG_CONTROL0, reg); - - if (rv) - return rv; - - reg = (option >> 16) & 0xffff; - return raw_write16(ISL923X_REG_CONTROL1, reg); -} - -/* Charger interfaces */ - -const struct charger_info *charger_get_info(void) -{ - return &isl9237_charger_info; -} - -int charger_get_status(int *status) -{ - *status = CHARGER_LEVEL_2; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv = EC_SUCCESS; - - /* - * See crosbug.com/p/51196. Always disable learn mode unless it was set - * explicitly. - */ - if (!learn_mode) - rv = charger_discharge_on_ac(0); - - /* ISL923X does not support inhibit mode setting. */ - return rv; -} - -int charger_get_current(int *current) -{ - int rv; - int reg; - - rv = raw_read16(ISL923X_REG_CHG_CURRENT, ®); - if (rv) - return rv; - - *current = REG_TO_CURRENT(reg); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - return isl9237_set_current(current); -} - -int charger_get_voltage(int *voltage) -{ - return raw_read16(ISL923X_REG_SYS_VOLTAGE_MAX, voltage); -} - -int charger_set_voltage(int voltage) -{ - /* The ISL923X will drop voltage to as low as requested. As the - * charger state machine will pass in 0 voltage, protect the system - * voltage by capping to the minimum. The reason is that the ISL923X - * only can regulate the system voltage which will kill the board's - * power if below 0. */ - if (voltage == 0) { - const struct battery_info *bi = battery_get_info(); - voltage = bi->voltage_min; - } - - return isl9237_set_voltage(voltage); -} - -int charger_post_init(void) -{ - /* - * charger_post_init() is called every time AC becomes present in the - * system. It's called this frequently because there are some charger - * ICs which become unpowered when AC is not present. Therefore, upon - * AC becoming present again, the chargers need to be reinitialized. - * The ISL9237/8 can be powered from VSYS and therefore do not need to - * be reinitialized everytime. This is why isl923x_init() is called - * once at HOOK_INIT time. - */ - return EC_SUCCESS; -} - -int isl923x_set_ac_prochot(uint16_t ma) -{ - int rv; - - if (ma > ISL923X_AC_PROCHOT_CURRENT_MAX) { - CPRINTS("%s: invalid current (%d mA)\n", __func__, ma); - return EC_ERROR_INVAL; - } - - rv = raw_write16(ISL923X_REG_PROCHOT_AC, ma); - if (rv) - CPRINTS("%s failed (%d)", __func__, rv); - return rv; -} - -int isl923x_set_dc_prochot(uint16_t ma) -{ - int rv; - - if (ma > ISL923X_DC_PROCHOT_CURRENT_MAX) { - CPRINTS("%s: invalid current (%d mA)\n", __func__, ma); - return EC_ERROR_INVAL; - } - - rv = raw_write16(ISL923X_REG_PROCHOT_DC, ma); - if (rv) - CPRINTS("%s failed (%d)", __func__, rv); - return rv; -} - -static void isl923x_init(void) -{ - int reg; - -#ifdef CONFIG_TRICKLE_CHARGING - const struct battery_info *bi = battery_get_info(); - int precharge_voltage = bi->precharge_voltage ? - bi->precharge_voltage : bi->voltage_min; - - if (raw_write16(ISL923X_REG_SYS_VOLTAGE_MIN, precharge_voltage)) - goto init_fail; -#endif - - /* - * [10:9]: Prochot# Debounce time - * 11b: 1ms - */ - if (raw_read16(ISL923X_REG_CONTROL2, ®)) - goto init_fail; - - if (raw_write16(ISL923X_REG_CONTROL2, - reg | - ISL923X_C2_OTG_DEBOUNCE_150 | - ISL923X_C2_PROCHOT_DEBOUNCE_1000 | - ISL923X_C2_ADAPTER_DEBOUNCE_150)) - goto init_fail; - -#ifdef CONFIG_CHARGE_RAMP_HW -#ifdef CONFIG_CHARGER_ISL9237 - if (raw_read16(ISL923X_REG_CONTROL0, ®)) - goto init_fail; - - /* Set input voltage regulation reference voltage for charge ramp */ - reg &= ~ISL9237_C0_VREG_REF_MASK; - reg |= ISL9237_C0_VREG_REF_4200; - - if (raw_write16(ISL923X_REG_CONTROL0, reg)) - goto init_fail; -#else /* !defined(CONFIG_CHARGER_ISL9237) */ - /* - * For the ISL9238, set the input voltage regulation to 4.439V. Note, - * the voltage is set in 341.3 mV steps. - */ - reg = (4439 / ISL9238_INPUT_VOLTAGE_REF_STEP) - << ISL9238_INPUT_VOLTAGE_REF_SHIFT; - - if (raw_write16(ISL9238_REG_INPUT_VOLTAGE, reg)) - goto init_fail; -#endif /* defined(CONFIG_CHARGER_ISL9237) */ -#else /* !defined(CONFIG_CHARGE_RAMP_HW) */ - if (raw_read16(ISL923X_REG_CONTROL0, ®)) - goto init_fail; - - /* Disable voltage regulation loop to disable charge ramp */ - reg |= ISL923X_C0_DISABLE_VREG; - - if (raw_write16(ISL923X_REG_CONTROL0, reg)) - goto init_fail; -#endif /* defined(CONFIG_CHARGE_RAMP_HW) */ - -#ifdef CONFIG_CHARGER_ISL9238 - /* - * Don't reread the prog pin and don't reload the ILIM on ACIN. - */ - if (raw_read16(ISL9238_REG_CONTROL3, ®)) - goto init_fail; - reg |= ISL9238_C3_NO_RELOAD_ACLIM_ON_ACIN | - ISL9238_C3_NO_REREAD_PROG_PIN; - /* - * Disable autonomous charging initially since 1) it causes boot loop - * issues with 2S batteries, and 2) it will automatically get disabled - * as soon as we manually set the current limit anyway. - */ - reg |= ISL9238_C3_DISABLE_AUTO_CHARING; - if (raw_write16(ISL9238_REG_CONTROL3, reg)) - goto init_fail; - - /* - * No need to proceed with the rest of init if we sysjump'd to this - * image as the input current limit has already been set. - */ - if (system_jumped_to_this_image()) - return; - - /* - * Initialize the input current limit to the board's default. - */ - if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) - goto init_fail; -#endif /* defined(CONFIG_CHARGER_ISL9238) */ - - return; -init_fail: - CPRINTS("%s failed!", __func__); -} -DECLARE_HOOK(HOOK_INIT, isl923x_init, HOOK_PRIO_INIT_I2C + 1); - -int charger_discharge_on_ac(int enable) -{ - int rv; - int control1; - - mutex_lock(&control1_mutex); - - rv = raw_read16(ISL923X_REG_CONTROL1, &control1); - if (rv) - goto out; - - control1 &= ~ISL923X_C1_LEARN_MODE_AUTOEXIT; - if (enable) - control1 |= ISL923X_C1_LEARN_MODE_ENABLE; - else - control1 &= ~ISL923X_C1_LEARN_MODE_ENABLE; - - rv = raw_write16(ISL923X_REG_CONTROL1, control1); - - learn_mode = !rv && enable; - -out: - mutex_unlock(&control1_mutex); - return rv; -} - -/*****************************************************************************/ -/* Hardware current ramping */ - -#ifdef CONFIG_CHARGE_RAMP_HW -int charger_set_hw_ramp(int enable) -{ - int rv, reg; - - rv = raw_read16(ISL923X_REG_CONTROL0, ®); - if (rv) - return rv; - - /* HW ramp is controlled by input voltage regulation reference bits */ - if (enable) - reg &= ~ISL923X_C0_DISABLE_VREG; - else - reg |= ISL923X_C0_DISABLE_VREG; - - return raw_write16(ISL923X_REG_CONTROL0, reg); -} - -int chg_ramp_is_stable(void) -{ - /* - * Since ISL cannot read the current limit that the ramp has settled - * on, then we can never consider the ramp stable, because we never - * know what the stable limit is. - */ - return 0; -} - -int chg_ramp_is_detected(void) -{ - return 1; -} - -int chg_ramp_get_current_limit(void) -{ - /* - * ISL doesn't have a way to get this info, so return the nominal - * current limit as an estimate. - */ - int input_current; - - if (charger_get_input_current(&input_current) != EC_SUCCESS) - return 0; - return input_current; -} -#endif /* CONFIG_CHARGE_RAMP_HW */ - - -#ifdef CONFIG_CHARGER_PSYS -static int psys_enabled; - -static void charger_enable_psys(void) -{ - int val; - - mutex_lock(&control1_mutex); - - /* - * enable system power monitor PSYS function - */ - if (raw_read16(ISL923X_REG_CONTROL1, &val)) - goto out; - - val |= ISL923X_C1_ENABLE_PSYS; - - if (raw_write16(ISL923X_REG_CONTROL1, val)) - goto out; - - psys_enabled = 1; - -out: - mutex_unlock(&control1_mutex); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, charger_enable_psys, HOOK_PRIO_DEFAULT); - -static void charger_disable_psys(void) -{ - int val; - - mutex_lock(&control1_mutex); - - /* - * disable system power monitor PSYS function - */ - if (raw_read16(ISL923X_REG_CONTROL1, &val)) - goto out; - - val &= ~ISL923X_C1_ENABLE_PSYS; - - if (raw_write16(ISL923X_REG_CONTROL1, val)) - goto out; - - psys_enabled = 0; - -out: - mutex_unlock(&control1_mutex); -} -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, charger_disable_psys, HOOK_PRIO_DEFAULT); - -#ifdef CONFIG_CHARGER_PSYS_READ -int charger_get_system_power(void) -{ - int adc; - - /* - * If PSYS is not enabled, AP is probably off, and the value is usually - * too small to be measured acurately anyway. - */ - if (!psys_enabled) - return -1; - - /* - * We assume that the output gain is always left to the default - * 1.44 uA/W, and that the ADC scaling values are setup accordingly in - * board file, so that the value is indicated in uW. - */ - adc = adc_read_channel(ADC_PSYS); - - return adc; -} - -static int console_command_psys(int argc, char **argv) -{ - ccprintf("PSYS = %d uW\n", charger_get_system_power()); - return 0; -} -DECLARE_CONSOLE_COMMAND(psys, console_command_psys, - NULL, - "Get the system power in mW"); -#endif /* CONFIG_CHARGER_PSYS_READ */ -#endif /* CONFIG_CHARGER_PSYS */ - -#ifdef CONFIG_CMD_CHARGER_ADC_AMON_BMON -enum amon_bmon { AMON, BMON }; - -static int print_amon_bmon(enum amon_bmon amon, int direction, - int resistor) -{ - int adc, curr, reg, ret; - -#ifdef CONFIG_CHARGER_ISL9238 - ret = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - ISL9238_REG_CONTROL3, ®); - if (ret) - return ret; - - /* Switch direction */ - if (direction) - reg |= ISL9238_C3_AMON_BMON_DIRECTION; - else - reg &= ~ISL9238_C3_AMON_BMON_DIRECTION; - ret = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - ISL9238_REG_CONTROL3, reg); - if (ret) - return ret; -#endif - - mutex_lock(&control1_mutex); - - ret = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - ISL923X_REG_CONTROL1, ®); - if (!ret) { - /* Switch between AMON/BMON */ - if (amon == AMON) - reg &= ~ISL923X_C1_SELECT_BMON; - else - reg |= ISL923X_C1_SELECT_BMON; - - /* Enable monitor */ - reg &= ~ISL923X_C1_DISABLE_MON; - ret = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - ISL923X_REG_CONTROL1, reg); - } - - mutex_unlock(&control1_mutex); - - if (ret) - return ret; - - adc = adc_read_channel(ADC_AMON_BMON); - curr = adc / resistor; - ccprintf("%cMON(%sharging): %d uV, %d mA\n", amon == AMON ? 'A' : 'B', - direction ? "Disc" : "C", adc, curr); - - return ret; -} - -/** - * Get charger AMON and BMON current. - */ -static int console_command_amon_bmon(int argc, char **argv) -{ - int ret = EC_SUCCESS; - int print_ac = 1; - int print_battery = 1; - int print_charge = 1; - int print_discharge = 1; - - if (argc >= 2) { - print_ac = (argv[1][0] == 'a'); - print_battery = (argv[1][0] == 'b'); -#ifdef CONFIG_CHARGER_ISL9238 - if (argv[1][1] != '\0') { - print_charge = (argv[1][1] == 'c'); - print_discharge = (argv[1][1] == 'd'); - } -#endif - } - - if (print_ac) { - if (print_charge) - ret |= print_amon_bmon(AMON, 0, - CONFIG_CHARGER_SENSE_RESISTOR_AC); -#ifdef CONFIG_CHARGER_ISL9238 - if (print_discharge) - ret |= print_amon_bmon(AMON, 1, - CONFIG_CHARGER_SENSE_RESISTOR_AC); -#endif - } - - if (print_battery) { -#ifdef CONFIG_CHARGER_ISL9238 - if (print_charge) - ret |= print_amon_bmon(BMON, 0, - /* - * charging current monitor has - * 2x amplification factor - */ - 2*CONFIG_CHARGER_SENSE_RESISTOR); -#endif - if (print_discharge) - ret |= print_amon_bmon(BMON, 1, - CONFIG_CHARGER_SENSE_RESISTOR); - } - - return ret; -} -DECLARE_CONSOLE_COMMAND(amonbmon, console_command_amon_bmon, -#ifdef CONFIG_CHARGER_ISL9237 - "amonbmon [a|b]", -#else - "amonbmon [a[c|d]|b[c|d]]", -#endif - "Get charger AMON/BMON voltage diff, current"); -#endif /* CONFIG_CMD_CHARGER_ADC_AMON_BMON */ - -#ifdef CONFIG_CMD_CHARGER_DUMP -static void dump_reg_range(int low, int high) -{ - int reg; - int regval; - int rv; - - for (reg = low; reg <= high; reg++) { - CPRINTF("[%Xh] = ", reg); - rv = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - reg, ®val); - if (!rv) - CPRINTF("0x%04x\n", regval); - else - CPRINTF("ERR (%d)\n", rv); - cflush(); - } -} - -static int command_isl923x_dump(int argc, char **argv) -{ - dump_reg_range(0x14, 0x15); - dump_reg_range(0x38, 0x3F); - dump_reg_range(0x47, 0x4A); -#ifdef CONFIG_CHARGER_ISL9238 - dump_reg_range(0x4B, 0x4E); -#endif /* CONFIG_CHARGER_ISL9238 */ - dump_reg_range(0xFE, 0xFF); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(charger_dump, command_isl923x_dump, "", - "Dumps ISL923x registers"); -#endif /* CONFIG_CMD_CHARGER_DUMP */ diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h deleted file mode 100644 index 8076b72e38..0000000000 --- a/driver/charger/isl923x.h +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright 2015 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. - * - * Intersil ISL-9237/8 battery charger driver. - */ - -#ifndef __CROS_EC_ISL923X_H -#define __CROS_EC_ISL923X_H - -#define ISL923X_ADDR_FLAGS (0x09) - -/* Registers */ -#define ISL923X_REG_CHG_CURRENT 0x14 -#define ISL923X_REG_ADAPTER_CURRENT1 0x3f -#define ISL923X_REG_ADAPTER_CURRENT2 0x3b -#define ISL923X_REG_SYS_VOLTAGE_MAX 0x15 -#define ISL923X_REG_SYS_VOLTAGE_MIN 0x3e -#define ISL923X_REG_PROCHOT_AC 0x47 -#define ISL923X_REG_PROCHOT_DC 0x48 -#define ISL923X_REG_T1_T2 0x38 -#define ISL923X_REG_CONTROL0 0x39 -#define ISL923X_REG_CONTROL1 0x3c -#define ISL923X_REG_CONTROL2 0x3d -#define ISL9238_REG_CONTROL3 0x4c -#define ISL9238_REG_CONTROL4 0x4e -#define ISL923X_REG_INFO 0x3a -#define ISL9238_REG_INFO2 0x4d -#define ISL923X_REG_OTG_VOLTAGE 0x49 -#define ISL923X_REG_OTG_CURRENT 0x4a -#define ISL9238_REG_INPUT_VOLTAGE 0x4b -#define ISL923X_REG_MANUFACTURER_ID 0xfe -#define ISL923X_REG_DEVICE_ID 0xff - -/* Sense resistor default values in mOhm */ -#define ISL923X_DEFAULT_SENSE_RESISTOR_AC 20 -#define ISL923X_DEFAULT_SENSE_RESISTOR 10 - -/* Maximum charging current register value */ -#define ISL923X_CURRENT_REG_MAX 0x17c0 /* bit<12:2> 10111110000 */ - -/* 2-level adpater current limit duration T1 & T2 in micro seconds */ -#define ISL923X_T1_10000 0x00 -#define ISL923X_T1_20000 0x01 -#define ISL923X_T1_15000 0x02 -#define ISL923X_T1_5000 0x03 -#define ISL923X_T1_1000 0x04 -#define ISL923X_T1_500 0x05 -#define ISL923X_T1_100 0x06 -#define ISL923X_T1_0 0x07 -#define ISL923X_T2_10 (0x00 << 8) -#define ISL923X_T2_100 (0x01 << 8) -#define ISL923X_T2_500 (0x02 << 8) -#define ISL923X_T2_1000 (0x03 << 8) -#define ISL923X_T2_300 (0x04 << 8) -#define ISL923X_T2_750 (0x05 << 8) -#define ISL923X_T2_2000 (0x06 << 8) -#define ISL923X_T2_10000 (0x07 << 8) - -#define ISL9237_SYS_VOLTAGE_REG_MAX 13824 -#define ISL9238_SYS_VOLTAGE_REG_MAX 18304 -#define ISL923X_SYS_VOLTAGE_REG_MIN 2048 - -/* PROCHOT# debounce time and duration time in micro seconds */ -#define ISL923X_PROCHOT_DURATION_10000 (0 << 6) -#define ISL923X_PROCHOT_DURATION_20000 BIT(6) -#define ISL923X_PROCHOT_DURATION_15000 (2 << 6) -#define ISL923X_PROCHOT_DURATION_5000 (3 << 6) -#define ISL923X_PROCHOT_DURATION_1000 (4 << 6) -#define ISL923X_PROCHOT_DURATION_500 (5 << 6) -#define ISL923X_PROCHOT_DURATION_100000 (6 << 6) -#define ISL923X_PROCHOT_DURATION_0 (7 << 6) -#define ISL923X_PROCHOT_DURATION_MASK (7 << 6) - -#define ISL923X_PROCHOT_DEBOUNCE_10 (0 << 9) -#define ISL923X_PROCHOT_DEBOUNCE_100 BIT(9) -#define ISL923X_PROCHOT_DEBOUNCE_500 (2 << 9) -#define ISL923X_PROCHOT_DEBOUNCE_1000 (3 << 9) -#define ISL923X_PROCHOT_DEBOUNCE_MASK (3 << 9) - -/* Maximum PROCHOT register value */ -#define ISL923X_PROCHOT_AC_REG_MAX 6400 -#define ISL923X_PROCHOT_DC_REG_MAX 12800 - -/* Control0: adapter voltage regulation reference */ -#define ISL9237_C0_VREG_REF_3900 0 -#define ISL9237_C0_VREG_REF_4200 1 -#define ISL9237_C0_VREG_REF_4500 2 -#define ISL9237_C0_VREG_REF_4800 3 -#define ISL9237_C0_VREG_REF_MASK 0x03 - -/* Control0: disable adapter voltaqe regulation */ -#define ISL923X_C0_DISABLE_VREG BIT(2) - -/* Control0: battery DCHOT reference for RS2 == 20mOhm */ -#define ISL923X_C0_DCHOT_6A (0 << 3) -#define ISL923X_C0_DCHOT_5A BIT(3) -#define ISL923X_C0_DCHOT_4A (2 << 3) -#define ISL923X_C0_DCHOT_3A (3 << 3) -#define ISL923X_C0_DCHOT_MASK (3 << 3) - -/* Control1: general purpose comparator debounce time in micro second */ -#define ISL923X_C1_GP_DEBOUNCE_2 (0 << 14) -#define ISL923X_C1_GP_DEBOUNCE_12 BIT(14) -#define ISL923X_C1_GP_DEBOUNCE_2000 (2 << 14) -#define ISL923X_C1_GP_DEBOUNCE_5000000 (3 << 14) -#define ISL923X_C1_GP_DEBOUNCE_MASK (3 << 14) - -/* Control1: learn mode */ -#define ISL923X_C1_LEARN_MODE_AUTOEXIT BIT(13) -#define ISL923X_C1_LEARN_MODE_ENABLE BIT(12) - -/* Control1: OTG enable */ -#define ISL923X_C1_OTG BIT(11) - -/* Control1: audio filter */ -#define ISL923X_C1_AUDIO_FILTER BIT(10) - -/* Control1: switch frequency, ISL9238 defines bit 7 as unused */ -#define ISL923X_C1_SWITCH_FREQ_PROG (0 << 7) /* 1000kHz or PROG */ -#define ISL9237_C1_SWITCH_FREQ_913K BIT(7) -#define ISL923X_C1_SWITCH_FREQ_839K (2 << 7) -#define ISL9237_C1_SWITCH_FREQ_777K (3 << 7) -#define ISL923X_C1_SWITCH_FREQ_723K (4 << 7) -#define ISL9237_C1_SWITCH_FREQ_676K (5 << 7) -#define ISL923X_C1_SWITCH_FREQ_635K (6 << 7) -#define ISL9237_C1_SWITCH_FREQ_599K (7 << 7) -#define ISL923X_C1_SWITCH_FREQ_MASK (7 << 7) - -/* Control1: turbo mode */ -#define ISL923X_C1_TURBO_MODE BIT(6) - -/* Control1: AMON & BMON */ -#define ISL923X_C1_DISABLE_MON BIT(5) -#define ISL923X_C1_SELECT_BMON BIT(4) - -/* Control1: PSYS, VSYS, VSYSLO */ -#define ISL923X_C1_ENABLE_PSYS BIT(3) -#define ISL923X_C1_ENABLE_VSYS BIT(2) -#define ISL923X_C1_VSYSLO_REF_6000 0 -#define ISL923X_C1_VSYSLO_REF_6300 1 -#define ISL923X_C1_VSYSLO_REF_6600 2 -#define ISL923X_C1_VSYSLO_REF_6900 3 -#define ISL923X_C1_VSYSLO_REF_MASK 3 - -/* Control2: trickle charging current in mA */ -#define ISL923X_C2_TRICKLE_256 (0 << 14) -#define ISL923X_C2_TRICKLE_128 BIT(14) -#define ISL923X_C2_TRICKLE_64 (2 << 14) -#define ISL923X_C2_TRICKLE_512 (3 << 14) -#define ISL923X_C2_TRICKLE_MASK (3 << 14) - -/* Control2: OTGEN debounce time in ms */ -#define ISL923X_C2_OTG_DEBOUNCE_1300 (0 << 13) -#define ISL923X_C2_OTG_DEBOUNCE_150 BIT(13) -#define ISL923X_C2_OTG_DEBOUNCE_MASK BIT(13) - -/* Control2: 2-level adapter over current */ -#define ISL923X_C2_2LVL_OVERCURRENT BIT(12) - -/* Control2: adapter insertion debounce time in ms */ -#define ISL923X_C2_ADAPTER_DEBOUNCE_1300 (0 << 11) -#define ISL923X_C2_ADAPTER_DEBOUNCE_150 BIT(11) -#define ISL923X_C2_ADAPTER_DEBOUNCE_MASK BIT(11) - -/* Control2: PROCHOT debounce time in uS */ -#define ISL9238_C2_PROCHOT_DEBOUNCE_7 (0 << 9) -#define ISL9237_C2_PROCHOT_DEBOUNCE_10 (0 << 9) -#define ISL923X_C2_PROCHOT_DEBOUNCE_100 BIT(9) -#define ISL923X_C2_PROCHOT_DEBOUNCE_500 (2 << 9) -#define ISL923X_C2_PROCHOT_DEBOUNCE_1000 (3 << 9) -#define ISL923X_C2_PROCHOT_DEBOUNCE_MASK (3 << 9) - -/* Control2: min PROCHOT duration in uS */ -#define ISL923X_C2_PROCHOT_DURATION_10000 (0 << 6) -#define ISL923X_C2_PROCHOT_DURATION_20000 BIT(6) -#define ISL923X_C2_PROCHOT_DURATION_15000 (2 << 6) -#define ISL923X_C2_PROCHOT_DURATION_5000 (3 << 6) -#define ISL923X_C2_PROCHOT_DURATION_1000 (4 << 6) -#define ISL923X_C2_PROCHOT_DURATION_500 (5 << 6) -#define ISL923X_C2_PROCHOT_DURATION_100 (6 << 6) -#define ISL923X_C2_PROCHOT_DURATION_0 (7 << 6) -#define ISL923X_C2_PROCHOT_DURATION_MASK (7 << 6) - -/* Control2: turn off ASGATE in OTG mode */ -#define ISL923X_C2_ASGATE_OFF BIT(5) - -/* Control2: CMIN, general purpose comparator reference in mV */ -#define ISL923X_C2_CMIN_2000 (0 << 4) -#define ISL923X_C2_CMIN_1200 BIT(4) - -/* Control2: general purpose comparator enable */ -#define ISL923X_C2_COMPARATOR BIT(3) - -/* Control2: invert CMOUT, general purpose comparator output, polarity */ -#define ISL923X_C2_INVERT_CMOUT BIT(2) - -/* Control2: disable WOC, way over current */ -#define ISL923X_C2_WOC_OFF BIT(1) - -/* Control2: PSYS gain in uA/W (ISL9237 only) */ -#define ISL9237_C2_PSYS_GAIN BIT(0) - -/* - * Control3: Buck-Boost switching period - * 0: x1 frequency, 1: half frequency. - */ -#define ISL9238_C3_BB_SWITCHING_PERIOD BIT(1) - -/* - * Control3: AMON/BMON direction. - * 0: adapter/charging, 1:OTG/discharging (ISL9238 only) - */ -#define ISL9238_C3_AMON_BMON_DIRECTION BIT(3) - -/* - * Control3: Disables Autonomous Charing - * - * Note: This is disabled automatically when ever we set the current limit - * manually (which we always do). - */ -#define ISL9238_C3_DISABLE_AUTO_CHARING BIT(7) - -/* Control3: PSYS gain in uA/W (ISL9238 only) */ -#define ISL9238_C3_PSYS_GAIN BIT(9) - -/* Control3: Don't reload ACLIM on ACIN. */ -#define ISL9238_C3_NO_RELOAD_ACLIM_ON_ACIN BIT(14) - -/* Control3: Don't reread PROG pin. */ -#define ISL9238_C3_NO_REREAD_PROG_PIN BIT(15) - -/* OTG voltage limit in mV, current limit in mA */ -#define ISL9237_OTG_VOLTAGE_MIN 4864 -#define ISL9237_OTG_VOLTAGE_MAX 5376 -#define ISL9238_OTG_VOLTAGE_MAX 27456 -#define ISL923X_OTG_CURRENT_MAX 4096 - -#define ISL9238_OTG_VOLTAGE_STEP 12 -#define ISL9238_OTG_VOLTAGE_SHIFT 3 -#define ISL923X_OTG_CURRENT_STEP 128 -#define ISL923X_OTG_CURRENT_SHIFT 7 - -/* Input voltage regulation voltage reference */ -#define ISL9238_INPUT_VOLTAGE_REF_STEP 341 -#define ISL9238_INPUT_VOLTAGE_REF_SHIFT 8 - -/* Info register fields */ -#define ISL9237_INFO_PROG_RESISTOR_MASK 0xf -#define ISL923X_INFO_TRICKLE_ACTIVE_MASK BIT(4) -#define ISL9237_INFO_PSTATE_SHIFT 5 -#define ISL9237_INFO_PSTATE_MASK 3 - -enum isl9237_power_stage { - BUCK_MODE, - BOOST_MODE, - BUCK_BOOST_MODE, - REVERSE_BUCK_MODE -}; - -#define ISL9237_INFO_FSM_STATE_SHIFT 7 -#define ISL9237_INFO_FSM_STATE_MASK 7 - -enum isl9237_fsm_state { - FSM_OFF, - FSM_BAT, - FSM_ADPT, - FSM_ACOK, - FSM_VSYS, - FSM_CHRG, - FSM_ENTOG, - FSM_OTG -}; - -#define ISL923X_INFO_VSYSLO BIT(10) -#define ISL923X_INFO_DCHOT BIT(11) -#define ISL9237_INFO_ACHOT BIT(12) - -#if defined(CONFIG_CHARGER_ISL9237) -#define CHARGER_NAME "isl9237" -#define CHARGE_V_MAX ISL9237_SYS_VOLTAGE_REG_MAX -#define CHARGE_V_MIN ISL923X_SYS_VOLTAGE_REG_MIN -#define CHARGE_V_STEP 8 -#elif defined(CONFIG_CHARGER_ISL9238) -#define CHARGER_NAME "isl9238" -#define CHARGE_V_MAX ISL9238_SYS_VOLTAGE_REG_MAX -#define CHARGE_V_MIN ISL923X_SYS_VOLTAGE_REG_MIN -#define CHARGE_V_STEP 8 -#endif - -#define CHARGE_I_MAX ISL923X_CURRENT_REG_MAX -#define CHARGE_I_MIN 4 -#define CHARGE_I_OFF 0 -#define CHARGE_I_STEP 4 -#define INPUT_I_MAX ISL923X_CURRENT_REG_MAX -#define INPUT_I_MIN 4 -#define INPUT_I_STEP 4 - -#define I2C_ADDR_CHARGER_FLAGS ISL923X_ADDR_FLAGS -#endif /* __CROS_EC_ISL923X_H */ - -/** - * Initialize AC & DC prochot threshold - * - * @param AC Porchot threshold current in mA: - * multiple of 128 up to 6400 mA - * DC Porchot threshold current in mA: - * multiple of 128 up to 12800 mA - * Bits below 128mA are truncated (ignored). - * @return enum ec_error_list - */ -int isl923x_set_ac_prochot(uint16_t ma); -int isl923x_set_dc_prochot(uint16_t ma); - -#define ISL923X_AC_PROCHOT_CURRENT_MAX 6400 /* mA */ -#define ISL923X_DC_PROCHOT_CURRENT_MAX 12800 /* mA */ diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c deleted file mode 100644 index 436b1bc981..0000000000 --- a/driver/charger/isl9241.c +++ /dev/null @@ -1,466 +0,0 @@ -/* Copyright 2019 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. - * - * Renesas (Intersil) ISL-9241 battery charger driver. - */ - -#include "adc.h" -#include "battery.h" -#include "battery_smart.h" -#include "charger.h" -#include "console.h" -#include "common.h" -#include "hooks.h" -#include "i2c.h" -#include "isl9241.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#ifndef CONFIG_CHARGER_NARROW_VDC -#error "ISL9241 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC." -#endif - -/* Sense resistor default values in milli Ohm */ -#define ISL9241_DEFAULT_RS1 20 /* Input current sense resistor */ -#define ISL9241_DEFAULT_RS2 10 /* Battery charge current sense resistor */ - -#define BOARD_RS1 CONFIG_CHARGER_SENSE_RESISTOR_AC -#define BOARD_RS2 CONFIG_CHARGER_SENSE_RESISTOR - -#define BC_REG_TO_CURRENT(REG) (((REG) * ISL9241_DEFAULT_RS2) / BOARD_RS2) -#define BC_CURRENT_TO_REG(CUR) (((CUR) * BOARD_RS2) / ISL9241_DEFAULT_RS2) - -#define AC_REG_TO_CURRENT(REG) (((REG) * ISL9241_DEFAULT_RS1) / BOARD_RS1) -#define AC_CURRENT_TO_REG(CUR) (((CUR) * BOARD_RS1) / ISL9241_DEFAULT_RS1) - -/* Console output macros */ -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) - -static int learn_mode; - -/* Mutex for CONTROL1 register, that can be updated from multiple tasks. */ -static struct mutex control1_mutex; - -/* Charger parameters */ -static const struct charger_info isl9241_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 inline int isl9241_read(int offset, int *value) -{ - return i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -static inline int isl9241_write(int offset, int value) -{ - return i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - offset, value); -} - -/* chip specific interfaces */ - -/*****************************************************************************/ -/* Charger interfaces */ -int charger_set_input_current(int input_current) -{ - int rv; - uint16_t reg = AC_CURRENT_TO_REG(input_current); - - rv = isl9241_write(ISL9241_REG_ADAPTER_CUR_LIMIT1, reg); - if (rv) - return rv; - - return isl9241_write(ISL9241_REG_ADAPTER_CUR_LIMIT2, reg); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - - rv = isl9241_read(ISL9241_REG_ADAPTER_CUR_LIMIT1, input_current); - if (rv) - return rv; - - *input_current = AC_REG_TO_CURRENT(*input_current); - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return isl9241_read(ISL9241_REG_MANUFACTURER_ID, id); -} - -int charger_device_id(int *id) -{ - return isl9241_read(ISL9241_REG_DEVICE_ID, id); -} - -int charger_get_option(int *option) -{ - int rv; - uint32_t controls; - int reg; - - rv = isl9241_read(ISL9241_REG_CONTROL0, ®); - if (rv) - return rv; - - controls = reg; - rv = isl9241_read(ISL9241_REG_CONTROL1, ®); - if (rv) - return rv; - - controls |= reg << 16; - *option = controls; - return EC_SUCCESS; -} - -int charger_set_option(int option) -{ - int rv; - - rv = isl9241_write(ISL9241_REG_CONTROL0, option & 0xFFFF); - if (rv) - return rv; - - return isl9241_write(ISL9241_REG_CONTROL1, (option >> 16) & 0xFFFF); -} - -const struct charger_info *charger_get_info(void) -{ - return &isl9241_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int reg; - - /* Level 2 charger */ - *status = CHARGER_LEVEL_2; - - /* Charge inhibit status */ - rv = isl9241_read(ISL9241_REG_MIN_SYSTEM_VOLTAGE, ®); - if (rv) - return rv; - if (!reg) - *status |= CHARGER_CHARGE_INHIBITED; - - /* Battery present & AC present status */ - rv = isl9241_read(ISL9241_REG_INFORMATION2, ®); - if (rv) - return rv; - if (!(reg & ISL9241_INFORMATION2_BATGONE_PIN)) - *status |= CHARGER_BATTERY_PRESENT; - if (reg & ISL9241_INFORMATION2_ACOK_PIN) - *status |= CHARGER_AC_PRESENT; - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - - /* - * See crosbug.com/p/51196. Always disable learn mode unless it was set - * explicitly. - */ - if (!learn_mode) { - rv = charger_discharge_on_ac(0); - if (rv) - return rv; - } - - /* - * Charger inhibit - * MinSystemVoltage 0x00h = disables all battery charging - */ - rv = isl9241_write(ISL9241_REG_MIN_SYSTEM_VOLTAGE, - mode & CHARGE_FLAG_INHIBIT_CHARGE ? - 0 : battery_get_info()->voltage_min); - if (rv) - return rv; - - /* POR reset */ - if (mode & CHARGE_FLAG_POR_RESET) { - rv = isl9241_write(ISL9241_REG_CONTROL3, - ISL9241_CONTROL3_DIGITAL_RESET); - } - - return rv; -} - -int charger_get_current(int *current) -{ - int rv; - - rv = isl9241_read(ISL9241_REG_CHG_CURRENT_LIMIT, current); - if (rv) - return rv; - - *current = BC_REG_TO_CURRENT(*current); - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - return isl9241_write(ISL9241_REG_CHG_CURRENT_LIMIT, - BC_CURRENT_TO_REG(current)); -} - -int charger_get_voltage(int *voltage) -{ - return isl9241_read(ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); -} - -int charger_set_voltage(int voltage) -{ - return isl9241_write(ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); -} - -int charger_get_vbus_voltage(int port) -{ - int adc_val = 0; - int ctl3_val; - int rv; - - /* Get current Control3 value */ - rv = isl9241_read(ISL9241_REG_CONTROL3, &ctl3_val); - if (rv) - goto error; - - /* Enable ADC */ - if (!(ctl3_val & ISL9241_CONTROL3_ENABLE_ADC)) { - rv = isl9241_write(ISL9241_REG_CONTROL3, - ctl3_val | ISL9241_CONTROL3_ENABLE_ADC); - if (rv) - goto error; - } - - /* Read voltage ADC value */ - rv = isl9241_read(ISL9241_REG_VIN_ADC_RESULTS, &adc_val); - if (rv) - goto error_restore_ctl3; - - /* - * Adjust adc_val - * - * raw adc_val has VIN_ADC in bits [13:6], so shift this down - * this puts adc_val in the range of 0..255, which maps to 0..24.48V - * each step in adc_val is 96mv - */ - adc_val >>= ISL9241_VIN_ADC_BIT_OFFSET; - adc_val *= ISL9241_VIN_ADC_STEP_MV; - -error_restore_ctl3: - /* Restore Control3 value */ - if (!(ctl3_val & ISL9241_CONTROL3_ENABLE_ADC)) - (void)isl9241_write(ISL9241_REG_CONTROL3, ctl3_val); - -error: - if (rv) - CPRINTF("Could not read VBUS ADC! Error: %d\n", rv); - - return adc_val; -} - -int charger_post_init(void) -{ - return EC_SUCCESS; -} - -int charger_discharge_on_ac(int enable) -{ - int rv; - int control1; - - mutex_lock(&control1_mutex); - - rv = isl9241_read(ISL9241_REG_CONTROL1, &control1); - if (rv) - goto out; - - if (enable) - control1 |= ISL9241_CONTROL1_LEARN_MODE; - else - control1 &= ~ISL9241_CONTROL1_LEARN_MODE; - - rv = isl9241_write(ISL9241_REG_CONTROL1, control1); - if (!rv) - learn_mode = enable; - -out: - mutex_unlock(&control1_mutex); - return rv; -} - -/*****************************************************************************/ -/* ISL-9241 initialization */ -static void isl9241_init(void) -{ - int reg; - - const struct battery_info *bi = battery_get_info(); - - /* - * Set the MaxSystemVoltage to battery maximum, - * 0x00=disables switching charger states - */ - if (isl9241_write(ISL9241_REG_MAX_SYSTEM_VOLTAGE, bi->voltage_max)) - goto init_fail; - - /* - * Set the MinSystemVoltage to battery minimum, - * 0x00=disables all battery charging - */ - if (isl9241_write(ISL9241_REG_MIN_SYSTEM_VOLTAGE, bi->voltage_min)) - goto init_fail; - - /* - * Set control2 register to - * [15:13]: Trickle Charging Current (battery pre-charge current) - * [12] : Two-Level Adapter Current Limit (enable) - * [10:9] : Prochot# Debounce time (1000us) - */ - if (isl9241_read(ISL9241_REG_CONTROL2, ®)) - goto init_fail; - - if (isl9241_write(ISL9241_REG_CONTROL2, - reg | ISL9241_CONTROL2_TRICKLE_CHG_CURR(bi->precharge_current) | - ISL9241_CONTROL2_TWO_LEVEL_ADP_CURR | - ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000)) - goto init_fail; - - /* - * Set control3 register to - * [14]: ACLIM Reload (Do not reload) - */ - if (isl9241_read(ISL9241_REG_CONTROL3, ®)) - goto init_fail; - - if (isl9241_write(ISL9241_REG_CONTROL3, - reg | ISL9241_CONTROL3_ACLIM_RELOAD)) - goto init_fail; - -#ifndef CONFIG_CHARGE_RAMP_HW - if (isl9241_read(ISL9241_REG_CONTROL0, ®)) - goto init_fail; - if (isl9241_write(ISL9241_REG_CONTROL0, - reg | ISL9241_CONTROL0_INPUT_VTG_REGULATION)) - goto init_fail; -#endif - - /* - * No need to proceed with the rest of init if we sysjump'd to this - * image as the input current limit has already been set. - */ - if (system_jumped_to_this_image()) - return; - - /* Initialize the input current limit to the board's default. */ - if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) - goto init_fail; - - return; - -init_fail: - CPRINTF("ISL9241_init failed!"); -} -DECLARE_HOOK(HOOK_INIT, isl9241_init, HOOK_PRIO_INIT_I2C + 1); - -/*****************************************************************************/ -/* Hardware current ramping */ - -#ifdef CONFIG_CHARGE_RAMP_HW -int charger_set_hw_ramp(int enable) -{ - int rv, reg; - - rv = isl9241_read(ISL9241_REG_CONTROL0, ®); - if (rv) - return rv; - - /* HW ramp is controlled by input voltage regulation reference bits */ - if (enable) - reg &= ~ISL9241_CONTROL0_INPUT_VTG_REGULATION; - else - reg |= ISL9241_CONTROL0_INPUT_VTG_REGULATION; - - return isl9241_write(ISL9241_REG_CONTROL0, reg); -} - -int chg_ramp_is_stable(void) -{ - /* - * Since ISL cannot read the current limit that the ramp has settled - * on, then we can never consider the ramp stable, because we never - * know what the stable limit is. - */ - return 0; -} - -int chg_ramp_is_detected(void) -{ - return 1; -} - -int chg_ramp_get_current_limit(void) -{ - int reg; - - if (isl9241_read(ISL9241_REG_IADP_ADC_RESULTS, ®)) - return 0; - - /* LSB value of register = 22.2mA */ - return (reg * 222) / 10; -} -#endif /* CONFIG_CHARGE_RAMP_HW */ - -/*****************************************************************************/ -#ifdef CONFIG_CMD_CHARGER_DUMP -static void dump_reg_range(int low, int high) -{ - int reg; - int regval; - int rv; - - for (reg = low; reg <= high; reg++) { - CPRINTF("[%Xh] = ", reg); - rv = isl9241_read(reg, ®val); - if (!rv) - CPRINTF("0x%04x\n", regval); - else - CPRINTF("ERR (%d)\n", rv); - cflush(); - } -} - -static int command_isl9241_dump(int argc, char **argv) -{ - dump_reg_range(0x14, 0x15); - dump_reg_range(0x38, 0x40); - dump_reg_range(0x43, 0x43); - dump_reg_range(0x47, 0x4F); - dump_reg_range(0x80, 0x87); - dump_reg_range(0x90, 0x91); - dump_reg_range(0xFE, 0xFF); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(charger_dump, command_isl9241_dump, "", - "Dumps ISL9241 registers"); -#endif /* CONFIG_CMD_CHARGER_DUMP */ diff --git a/driver/charger/isl9241.h b/driver/charger/isl9241.h deleted file mode 100644 index b14c15f780..0000000000 --- a/driver/charger/isl9241.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 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. - * - * Renesas (Intersil) ISL-9241 battery charger driver header. - */ - -#ifndef __CROS_EC_ISL9241_H -#define __CROS_EC_ISL9241_H - -#define ISL9241_ADDR_FLAGS 0x09 -#define I2C_ADDR_CHARGER_FLAGS ISL9241_ADDR_FLAGS - -#define CHARGER_NAME "ISL9241" -#define CHARGE_V_MAX 18304 -#define CHARGE_V_MIN 64 -#define CHARGE_V_STEP 8 -#define CHARGE_I_MAX 6140 -#define CHARGE_I_MIN 4 -#define CHARGE_I_STEP 4 -#define INPUT_I_MAX 6140 -#define INPUT_I_MIN 4 -#define INPUT_I_STEP 4 - -/* Registers */ - -/* - * ChargeCurrentLimit [12:2] 11-bit (0x0000h = disables fast charging, - * trickle charging is allowed) - */ -#define ISL9241_REG_CHG_CURRENT_LIMIT 0x14 - -/* MaxSystemVoltage [14:3] 12-bit, (0x0000h = disables switching) */ -#define ISL9241_REG_MAX_SYSTEM_VOLTAGE 0x15 - -#define ISL9241_REG_CONTROL7 0x38 - -/* Configures various charger options */ -#define ISL9241_REG_CONTROL0 0x39 -/* 2: Input Voltage Regulation (0 = Enable (default), 1 = Disable) */ -#define ISL9241_CONTROL0_INPUT_VTG_REGULATION BIT(2) - -#define ISL9241_REG_INFORMATION1 0x3A -#define ISL9241_REG_ADAPTER_CUR_LIMIT2 0x3B - -/* Configures various charger options */ -#define ISL9241_REG_CONTROL1 0x3C -#define ISL9241_CONTROL1_LEARN_MODE BIT(12) - -/* Configures various charger options */ -#define ISL9241_REG_CONTROL2 0x3D -/* - * 15:13 - Trickle Charging Current - * <000> 32mA (do not use) - * <001> 64mA - * <010> 96mA - * <011> 128mA (default) - * <100> 160mA - * <101> 192mA - * <110> 224mA - * <111> 256mA - */ -#define ISL9241_CONTROL2_TRICKLE_CHG_CURR(curr) ((((curr) >> 5) - 1) << 13) -/* 12 - Two-Level Adapter Current Limit */ -#define ISL9241_CONTROL2_TWO_LEVEL_ADP_CURR BIT(12) -/* 10:9 PROCHOT# debounce time in uS */ -#define ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000 (3 << 9) - -/* MinSystemVoltage [13:6] 8-bit (0x0000h = disables all battery charging) */ -#define ISL9241_REG_MIN_SYSTEM_VOLTAGE 0x3E - -#define ISL9241_REG_ADAPTER_CUR_LIMIT1 0x3F -#define ISL9241_REG_ACOK_REFERENCE 0x40 -#define ISL9241_REG_CONTROL6 0x43 -#define ISL9241_REG_AC_PROCHOT 0x47 -#define ISL9241_REG_DC_PROCHOT 0x48 -#define ISL9241_REG_OTG_VOLTAGE 0x49 -#define ISL9241_REG_OTG_CURRENT 0x4A - -/* VIN Voltage (ADP Min Voltage) (default 4.096V) */ -#define ISL9241_REG_VIN_VOLTAGE 0x4B - -/* Configures various charger options */ -#define ISL9241_REG_CONTROL3 0x4C -/* 14: ACLIM Reload (0 - reload, 1 - Do not reload */ -#define ISL9241_CONTROL3_ACLIM_RELOAD BIT(14) -/* 2: Digital Reset (0 - Idle, 1 - Reset */ -#define ISL9241_CONTROL3_DIGITAL_RESET BIT(2) -/* 0: Enable ADC (0 - Active when charging, 1 - Active always) */ -#define ISL9241_CONTROL3_ENABLE_ADC BIT(0) - -/* Indicates various charger status */ -#define ISL9241_REG_INFORMATION2 0x4D -/* 12: BATGONE pin status (0 = Battery is present, 1 = No battery) */ -#define ISL9241_INFORMATION2_BATGONE_PIN BIT(12) -/* 14: ACOK pin status (0 = No adapter, 1 = Adapter is present) */ -#define ISL9241_INFORMATION2_ACOK_PIN BIT(14) - -#define ISL9241_REG_CONTROL4 0x4E -#define ISL9241_REG_CONTROL5 0x4F -#define ISL9241_REG_NTC_ADC_RESULTS 0x80 -#define ISL9241_REG_VBAT_ADC_RESULTS 0x81 -#define ISL9241_REG_TJ_ADC_RESULTS 0x82 - -/* ADC result for adapter current measurements, LSB = 22.2mA */ -#define ISL9241_REG_IADP_ADC_RESULTS 0x83 - -#define ISL9241_REG_DC_ADC_RESULTS 0x84 -#define ISL9241_REG_CC_ADC_RESULTS 0x85 -#define ISL9241_REG_VSYS_ADC_RESULTS 0x86 -#define ISL9241_REG_VIN_ADC_RESULTS 0x87 -#define ISL9241_REG_INFORMATION3 0x90 -#define ISL9241_REG_INFORMATION4 0x91 -#define ISL9241_REG_MANUFACTURER_ID 0xFE -#define ISL9241_REG_DEVICE_ID 0xFF - -#define ISL9241_VIN_ADC_BIT_OFFSET 6 -#define ISL9241_VIN_ADC_STEP_MV 96 - -#endif /* __CROS_EC_ISL9241_H */ diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c deleted file mode 100644 index 342aa704f7..0000000000 --- a/driver/charger/rt946x.c +++ /dev/null @@ -1,1682 +0,0 @@ -/* Copyright 2017 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. - * - * Richtek rt946x, Mediatek mt6370 battery charger driver. - */ - -#include "battery.h" -#include "battery_smart.h" -#include "charger.h" -#include "charge_manager.h" -#include "common.h" -#include "compile_time_macros.h" -#include "config.h" -#include "console.h" -#include "hooks.h" -#include "i2c.h" -#include "printf.h" -#include "driver/wpc/p9221.h" -#include "rt946x.h" -#include "task.h" -#include "timer.h" -#include "usb_charge.h" -#include "util.h" - -/* Console output macros */ -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) -#define CPRINTS(format, args...) cprints(CC_CHARGER, "CHG " format, ## args) - -/* Charger parameters */ -static const struct charger_info rt946x_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 const struct rt946x_init_setting default_init_setting = { - .eoc_current = 400, - .mivr = 4000, - .ircmp_vclamp = 32, - .ircmp_res = 25, - .boost_voltage = 5050, - .boost_current = 1500, -}; - -__attribute__((weak)) -const struct rt946x_init_setting *board_rt946x_init_setting(void) -{ - return &default_init_setting; -} - -enum rt946x_ilmtsel { - RT946X_ILMTSEL_PSEL_OTG, - RT946X_ILMTSEL_AICR = 2, - RT946X_ILMTSEL_LOWER_LEVEL, /* lower of above two */ -}; - -enum rt946x_chg_stat { - RT946X_CHGSTAT_READY = 0, - RT946X_CHGSTAT_IN_PROGRESS, - RT946X_CHGSTAT_DONE, - RT946X_CHGSTAT_FAULT, -}; - -enum rt946x_adc_in_sel { - RT946X_ADC_VBUS_DIV5 = 1, - RT946X_ADC_VBUS_DIV2, - MT6370_ADC_TS_BAT = 6, - MT6370_ADC_IBUS = 8, - MT6370_ADC_TEMP_JC = 12, - MT6370_ADC_MAX, -}; - -static struct mutex adc_access_lock; - -#ifdef CONFIG_CHARGER_MT6370 -/* - * Unit for each ADC parameter - * 0 stands for reserved - */ -static const int mt6370_adc_unit[MT6370_ADC_MAX] = { - 0, - MT6370_ADC_UNIT_VBUS_DIV5, - MT6370_ADC_UNIT_VBUS_DIV2, - MT6370_ADC_UNIT_VSYS, - MT6370_ADC_UNIT_VBAT, - 0, - MT6370_ADC_UNIT_TS_BAT, - 0, - MT6370_ADC_UNIT_IBUS, - MT6370_ADC_UNIT_IBAT, - 0, - MT6370_ADC_UNIT_CHG_VDDP, - MT6370_ADC_UNIT_TEMP_JC, -}; - -static const int mt6370_adc_offset[MT6370_ADC_MAX] = { - 0, - MT6370_ADC_OFFSET_VBUS_DIV5, - MT6370_ADC_OFFSET_VBUS_DIV2, - MT6370_ADC_OFFSET_VSYS, - MT6370_ADC_OFFSET_VBAT, - 0, - MT6370_ADC_OFFSET_TS_BAT, - 0, - MT6370_ADC_OFFSET_IBUS, - MT6370_ADC_OFFSET_IBAT, - 0, - MT6370_ADC_OFFSET_CHG_VDDP, - MT6370_ADC_OFFSET_TEMP_JC, -}; - -static int hidden_mode_cnt = 0; -static struct mutex hidden_mode_lock; -static const unsigned char mt6370_reg_en_hidden_mode[] = { - MT6370_REG_HIDDENPASCODE1, - MT6370_REG_HIDDENPASCODE2, - MT6370_REG_HIDDENPASCODE3, - MT6370_REG_HIDDENPASCODE4, -}; - -static const unsigned char mt6370_val_en_hidden_mode[] = { - 0x96, 0x69, 0xC3, 0x3C, -}; -#endif /* CONFIG_CHARGER_MT6370 */ - -#if defined(CONFIG_CHARGER_RT9466) || defined(CONFIG_CHARGER_RT9467) -enum rt946x_irq { - RT946X_IRQ_CHGSTATC = 0, - RT946X_IRQ_CHGFAULT, - RT946X_IRQ_TSSTATC, - RT946X_IRQ_CHGIRQ1, - RT946X_IRQ_CHGIRQ2, - RT946X_IRQ_CHGIRQ3, -#ifdef CONFIG_CHARGER_RT9467 - RT946X_IRQ_DPDMIRQ, -#endif - RT946X_IRQ_COUNT, -}; - -static uint8_t rt946x_irqmask[RT946X_IRQ_COUNT] = { - 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, -#ifdef CONFIG_CHARGER_RT9467 - 0xFC, -#endif -}; - -static const uint8_t rt946x_irq_maskall[RT946X_IRQ_COUNT] = { - 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, -#ifdef CONFIG_CHARGER_RT9467 - 0xFF, -#endif -}; -#elif defined(CONFIG_CHARGER_MT6370) -enum rt946x_irq { - MT6370_IRQ_CHGSTAT1 = 0, - MT6370_IRQ_CHGSTAT2, - MT6370_IRQ_CHGSTAT3, - MT6370_IRQ_CHGSTAT4, - MT6370_IRQ_CHGSTAT5, - MT6370_IRQ_CHGSTAT6, - MT6370_IRQ_DPDMSTAT, - MT6370_IRQ_DICHGSTAT, - MT6370_IRQ_OVPCTRLSTAT, - MT6370_IRQ_FLEDSTAT1, - MT6370_IRQ_FLEDSTAT2, - MT6370_IRQ_BASESTAT, - MT6370_IRQ_LDOSTAT, - MT6370_IRQ_RGBSTAT, - MT6370_IRQ_BLSTAT, - MT6370_IRQ_DBSTAT, - RT946X_IRQ_COUNT, -}; - -static uint8_t rt946x_irqmask[RT946X_IRQ_COUNT] = { - 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, -}; - -static const uint8_t rt946x_irq_maskall[RT946X_IRQ_COUNT] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, -}; -#endif - -/* Must be in ascending order */ -static const uint16_t rt946x_boost_current[] = { - 500, 700, 1100, 1300, 1800, 2100, 2400, -}; - -static int rt946x_read8(int reg, int *val) -{ - return i2c_read8(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, reg, val); -} - -static int rt946x_write8(int reg, int val) -{ - return i2c_write8(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, reg, val); -} - -static int rt946x_block_write(int reg, const uint8_t *val, int len) -{ - return i2c_write_block(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, - reg, val, len); -} - -static int rt946x_update_bits(int reg, int mask, int val) -{ - int rv; - int reg_val = 0; - - rv = rt946x_read8(reg, ®_val); - if (rv) - return rv; - reg_val &= ~mask; - reg_val |= (mask & val); - rv = rt946x_write8(reg, reg_val); - return rv; -} - -static inline int rt946x_set_bit(int reg, int mask) -{ - return rt946x_update_bits(reg, mask, mask); -} - -static inline int rt946x_clr_bit(int reg, int mask) -{ - return rt946x_update_bits(reg, mask, 0x00); -} - -static inline int mt6370_pmu_reg_test_bit(int cmd, int shift, int *is_one) -{ - int rv, data; - - rv = rt946x_read8(cmd, &data); - if (rv) { - *is_one = 0; - return rv; - } - - *is_one = !!(data & BIT(shift)); - return rv; -} - -static inline uint8_t rt946x_closest_reg(uint16_t min, uint16_t max, - uint16_t step, uint16_t target) -{ - if (target < min) - return 0; - if (target >= max) - return ((max - min) / step); - return (target - min) / step; -} - -static int rt946x_get_ieoc(uint32_t *ieoc) -{ - int ret, reg_ieoc; - - ret = rt946x_read8(RT946X_REG_CHGCTRL9, ®_ieoc); - if (ret) - return ret; - - *ieoc = RT946X_IEOC_MIN + - RT946X_IEOC_STEP * - ((reg_ieoc & RT946X_MASK_IEOC) >> RT946X_SHIFT_IEOC); - - return EC_SUCCESS; -} - -#ifdef CONFIG_CHARGER_MT6370 -static int mt6370_enable_hidden_mode(int en) -{ - int rv = 0; - - if (in_interrupt_context()) { - CPRINTS("Shouldn't use %s in IRQ", __func__); - return EC_ERROR_INVAL; - } - - mutex_lock(&hidden_mode_lock); - if (en) { - if (hidden_mode_cnt == 0) { - rv = rt946x_block_write(mt6370_reg_en_hidden_mode[0], - mt6370_val_en_hidden_mode, - ARRAY_SIZE(mt6370_val_en_hidden_mode)); - if (rv) - goto out; - } - hidden_mode_cnt++; - } else { - if (hidden_mode_cnt == 1) /* last one */ - rv = rt946x_write8(mt6370_reg_en_hidden_mode[0], 0x00); - hidden_mode_cnt--; - if (rv) - goto out; - } - -out: - mutex_unlock(&hidden_mode_lock); - return rv; -} -#endif /* CONFIG_CHARGER_MT6370 */ - -static int rt946x_chip_rev(int *chip_rev) -{ - int rv; - - rv = rt946x_read8(RT946X_REG_DEVICEID, chip_rev); - if (rv == EC_SUCCESS) - *chip_rev &= RT946X_MASK_CHIP_REV; - return rv; -} - -static inline int rt946x_enable_wdt(int en) -{ - return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL13, RT946X_MASK_WDT_EN); -} - -/* Enable high-impedance mode */ -static inline int rt946x_enable_hz(int en) -{ - return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL1, RT946X_MASK_HZ_EN); -} - -int rt946x_por_reset(void) -{ - int rv, val; - -#ifdef CONFIG_CHARGER_MT6370 - /* Soft reset. It takes only 1ns for resetting. b/116682788 */ - val = RT946X_MASK_SOFT_RST; - /* - * MT6370 has to set passcodes before resetting all the registers and - * logics. - */ - rv = rt946x_write8(MT6370_REG_RSTPASCODE1, MT6370_MASK_RSTPASCODE1); - rv |= rt946x_write8(MT6370_REG_RSTPASCODE2, MT6370_MASK_RSTPASCODE2); -#else - /* Hard reset, may take several milliseconds. */ - val = RT946X_MASK_RST; - rv = rt946x_enable_hz(0); -#endif - if (rv) - return rv; - - return rt946x_set_bit(RT946X_REG_CORECTRL_RST, val); -} - -static int rt946x_reset_to_zero(void) -{ - int rv; - - rv = charger_set_current(0); - if (rv) - return rv; - - rv = charger_set_voltage(0); - if (rv) - return rv; - - return rt946x_enable_hz(1); -} - -static int rt946x_enable_bc12_detection(int en) -{ -#if defined(CONFIG_CHARGER_RT9467) || defined(CONFIG_CHARGER_MT6370) - int rv; - - if (en) { -#ifdef CONFIG_CHARGER_MT6370_BC12_GPIO - gpio_set_level(GPIO_BC12_DET_EN, 1); -#endif /* CONFIG_CHARGER_MT6370_BC12_GPIO */ - return rt946x_set_bit(RT946X_REG_DPDM1, RT946X_MASK_USBCHGEN); - } - - rv = rt946x_clr_bit(RT946X_REG_DPDM1, RT946X_MASK_USBCHGEN); -#ifdef CONFIG_CHARGER_MT6370_BC12_GPIO - gpio_set_level(GPIO_BC12_DET_EN, 0); -#endif /* CONFIG_CHARGER_MT6370_BC12_GPIO */ - return rv; -#endif - return 0; -} - -static int rt946x_set_ieoc(unsigned int ieoc) -{ - uint8_t reg_ieoc; - - reg_ieoc = rt946x_closest_reg(RT946X_IEOC_MIN, RT946X_IEOC_MAX, - RT946X_IEOC_STEP, ieoc); - - CPRINTF("%s ieoc = %d(0x%02X)\n", __func__, ieoc, reg_ieoc); - - return rt946x_update_bits(RT946X_REG_CHGCTRL9, RT946X_MASK_IEOC, - reg_ieoc << RT946X_SHIFT_IEOC); -} - -static int rt946x_set_mivr(unsigned int mivr) -{ - uint8_t reg_mivr = 0; - - reg_mivr = rt946x_closest_reg(RT946X_MIVR_MIN, RT946X_MIVR_MAX, - RT946X_MIVR_STEP, mivr); - - CPRINTF("%s: mivr = %d(0x%02X)\n", __func__, mivr, reg_mivr); - - return rt946x_update_bits(RT946X_REG_CHGCTRL6, RT946X_MASK_MIVR, - reg_mivr << RT946X_SHIFT_MIVR); -} - -static int rt946x_set_boost_voltage(unsigned int voltage) -{ - uint8_t reg_voltage = 0; - - reg_voltage = rt946x_closest_reg(RT946X_BOOST_VOLTAGE_MIN, - RT946X_BOOST_VOLTAGE_MAX, RT946X_BOOST_VOLTAGE_STEP, voltage); - - CPRINTF("%s voltage = %d(0x%02X)\n", __func__, voltage, reg_voltage); - - return rt946x_update_bits(RT946X_REG_CHGCTRL5, - RT946X_MASK_BOOST_VOLTAGE, - reg_voltage << RT946X_SHIFT_BOOST_VOLTAGE); -} - -static int rt946x_set_boost_current(unsigned int current) -{ - int i; - - /* - * Find the smallest output current threshold which can support - * our requested output current. Use the greatest achievable - * boost current (2.4A) if requested current is too large. - */ - for (i = 0; i < ARRAY_SIZE(rt946x_boost_current) - 1; i++) { - if (current < rt946x_boost_current[i]) - break; - } - - CPRINTF("%s current = %d(0x%02X)\n", __func__, current, i); - - return rt946x_update_bits(RT946X_REG_CHGCTRL10, - RT946X_MASK_BOOST_CURRENT, - i << RT946X_SHIFT_BOOST_CURRENT); -} - -static int rt946x_set_ircmp_vclamp(unsigned int vclamp) -{ - uint8_t reg_vclamp = 0; - - reg_vclamp = rt946x_closest_reg(RT946X_IRCMP_VCLAMP_MIN, - RT946X_IRCMP_VCLAMP_MAX, RT946X_IRCMP_VCLAMP_STEP, vclamp); - - CPRINTF("%s: vclamp = %d(0x%02X)\n", __func__, vclamp, reg_vclamp); - - return rt946x_update_bits(RT946X_REG_CHGCTRL18, - RT946X_MASK_IRCMP_VCLAMP, - reg_vclamp << RT946X_SHIFT_IRCMP_VCLAMP); -} - -static int rt946x_set_ircmp_res(unsigned int res) -{ - uint8_t reg_res = 0; - - reg_res = rt946x_closest_reg(RT946X_IRCMP_RES_MIN, RT946X_IRCMP_RES_MAX, - RT946X_IRCMP_RES_STEP, res); - - CPRINTF("%s: res = %d(0x%02X)\n", __func__, res, reg_res); - - return rt946x_update_bits(RT946X_REG_CHGCTRL18, RT946X_MASK_IRCMP_RES, - reg_res << RT946X_SHIFT_IRCMP_RES); -} - -static int rt946x_set_vprec(unsigned int vprec) -{ - uint8_t reg_vprec = 0; - - reg_vprec = rt946x_closest_reg(RT946X_VPREC_MIN, RT946X_VPREC_MAX, - RT946X_VPREC_STEP, vprec); - - CPRINTF("%s: vprec = %d(0x%02X)\n", __func__, vprec, reg_vprec); - - return rt946x_update_bits(RT946X_REG_CHGCTRL8, RT946X_MASK_VPREC, - reg_vprec << RT946X_SHIFT_VPREC); -} - -static int rt946x_set_iprec(unsigned int iprec) -{ - uint8_t reg_iprec = 0; - - reg_iprec = rt946x_closest_reg(RT946X_IPREC_MIN, RT946X_IPREC_MAX, - RT946X_IPREC_STEP, iprec); - - CPRINTF("%s: iprec = %d(0x%02X)\n", __func__, iprec, reg_iprec); - - return rt946x_update_bits(RT946X_REG_CHGCTRL8, RT946X_MASK_IPREC, - reg_iprec << RT946X_SHIFT_IPREC); -} - -static int rt946x_init_irq(void) -{ - int rv = 0; - int dummy; - int i; - - /* Mask all interrupts */ - rv = rt946x_block_write(RT946X_REG_CHGSTATCCTRL, rt946x_irq_maskall, - RT946X_IRQ_COUNT); - if (rv) - return rv; - - /* Clear all interrupt flags */ - for (i = 0; i < RT946X_IRQ_COUNT; i++) { - rv = rt946x_read8(RT946X_REG_CHGSTATC + i, &dummy); - if (rv) - return rv; - } - - /* Init interrupt */ - return rt946x_block_write(RT946X_REG_CHGSTATCCTRL, rt946x_irqmask, - ARRAY_SIZE(rt946x_irqmask)); -} - -static int rt946x_init_setting(void) -{ - int rv = 0; - const struct battery_info *batt_info = battery_get_info(); - const struct rt946x_init_setting *setting = board_rt946x_init_setting(); - -#ifdef CONFIG_CHARGER_OTG - /* Disable boost-mode output voltage */ - rv = charger_enable_otg_power(0); - if (rv) - return rv; -#endif - /* Enable/Disable BC 1.2 detection */ -#ifdef HAS_TASK_USB_CHG - rv = rt946x_enable_bc12_detection(1); -#else - rv = rt946x_enable_bc12_detection(0); -#endif - if (rv) - return rv; - /* Disable WDT */ - rv = rt946x_enable_wdt(0); - if (rv) - return rv; - /* Disable battery thermal protection */ - rv = rt946x_clr_bit(RT946X_REG_CHGCTRL16, RT946X_MASK_JEITA_EN); - if (rv) - return rv; - /* Disable charge timer */ - rv = rt946x_clr_bit(RT946X_REG_CHGCTRL12, RT946X_MASK_TMR_EN); - if (rv) - return rv; - rv = rt946x_set_mivr(setting->mivr); - if (rv) - return rv; - rv = rt946x_set_ieoc(setting->eoc_current); - if (rv) - return rv; - rv = rt946x_set_boost_voltage( - setting->boost_voltage); - if (rv) - return rv; - rv = rt946x_set_boost_current( - setting->boost_current); - if (rv) - return rv; - rv = rt946x_set_ircmp_vclamp(setting->ircmp_vclamp); - if (rv) - return rv; - rv = rt946x_set_ircmp_res(setting->ircmp_res); - if (rv) - return rv; - rv = rt946x_set_vprec(batt_info->precharge_voltage ? - batt_info->precharge_voltage : batt_info->voltage_min); - if (rv) - return rv; - rv = rt946x_set_iprec(batt_info->precharge_current); - if (rv) - return rv; - -#ifdef CONFIG_CHARGER_MT6370_BACKLIGHT - rt946x_write8(MT6370_BACKLIGHT_BLEN, - MT6370_MASK_BLED_EXT_EN | MT6370_MASK_BLED_EN | - MT6370_MASK_BLED_1CH_EN | MT6370_MASK_BLED_2CH_EN | - MT6370_MASK_BLED_3CH_EN | MT6370_MASK_BLED_4CH_EN | - MT6370_BLED_CODE_LINEAR); - rt946x_update_bits(MT6370_BACKLIGHT_BLPWM, MT6370_MASK_BLPWM_BLED_PWM, - BIT(MT6370_SHIFT_BLPWM_BLED_PWM)); -#endif - - return rt946x_init_irq(); -} - -#ifdef CONFIG_CHARGER_OTG -int charger_enable_otg_power(int enabled) -{ - return (enabled ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL1, RT946X_MASK_OPA_MODE); -} - -int charger_is_sourcing_otg_power(int port) -{ - int val; - - if (rt946x_read8(RT946X_REG_CHGCTRL1, &val)) - return 0; - - return !!(val & RT946X_MASK_OPA_MODE); -} -#endif - -int charger_set_input_current(int input_current) -{ - uint8_t reg_iin = 0; - const struct charger_info * const info = charger_get_info(); - - reg_iin = rt946x_closest_reg(info->input_current_min, - info->input_current_max, info->input_current_step, - input_current); - - CPRINTF("%s iin = %d(0x%02X)\n", __func__, input_current, reg_iin); - - return rt946x_update_bits(RT946X_REG_CHGCTRL3, RT946X_MASK_AICR, - reg_iin << RT946X_SHIFT_AICR); -} - -int charger_get_input_current(int *input_current) -{ - int rv; - int val = 0; - const struct charger_info * const info = charger_get_info(); - - rv = rt946x_read8(RT946X_REG_CHGCTRL3, &val); - if (rv) - return rv; - - val = (val & RT946X_MASK_AICR) >> RT946X_SHIFT_AICR; - *input_current = val * info->input_current_step - + info->input_current_min; - - return EC_SUCCESS; -} - -int charger_manufacturer_id(int *id) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -int charger_device_id(int *id) -{ - int rv; - - rv = rt946x_read8(RT946X_REG_DEVICEID, id); - if (rv == EC_SUCCESS) - *id &= RT946X_MASK_VENDOR_ID; - return rv; -} - -int charger_get_option(int *option) -{ - /* Ignored: does not exist */ - *option = 0; - return EC_SUCCESS; -} - -int charger_set_option(int option) -{ - /* Ignored: does not exist */ - return EC_SUCCESS; -} - -const struct charger_info *charger_get_info(void) -{ - return &rt946x_charger_info; -} - -int charger_get_status(int *status) -{ - int rv; - int val = 0; - - rv = rt946x_read8(RT946X_REG_CHGCTRL2, &val); - if (rv) - return rv; - val = (val & RT946X_MASK_CHG_EN) >> RT946X_SHIFT_CHG_EN; - if (!val) - *status |= CHARGER_CHARGE_INHIBITED; - - rv = rt946x_read8(RT946X_REG_CHGFAULT, &val); - if (rv) - return rv; - if (val & RT946X_MASK_CHG_VBATOV) - *status |= CHARGER_VOLTAGE_OR; - - - rv = rt946x_read8(RT946X_REG_CHGNTC, &val); - if (rv) - return rv; - val = (val & RT946X_MASK_BATNTC_FAULT) >> RT946X_SHIFT_BATNTC_FAULT; - - switch (val) { - case RT946X_BATTEMP_WARM: - *status |= CHARGER_RES_HOT; - break; - case RT946X_BATTEMP_COOL: - *status |= CHARGER_RES_COLD; - break; - case RT946X_BATTEMP_COLD: - *status |= CHARGER_RES_COLD; - *status |= CHARGER_RES_UR; - break; - case RT946X_BATTEMP_HOT: - *status |= CHARGER_RES_HOT; - *status |= CHARGER_RES_OR; - break; - default: - break; - } - - return EC_SUCCESS; -} - -int charger_set_mode(int mode) -{ - int rv; - - if (mode & CHARGE_FLAG_POR_RESET) { - rv = rt946x_por_reset(); - if (rv) - return rv; - } - - if (mode & CHARGE_FLAG_RESET_TO_ZERO) { - rv = rt946x_reset_to_zero(); - if (rv) - return rv; - } - - return EC_SUCCESS; -} - -int charger_get_current(int *current) -{ - int rv; - int val = 0; - const struct charger_info * const info = charger_get_info(); - - rv = rt946x_read8(RT946X_REG_CHGCTRL7, &val); - if (rv) - return rv; - - val = (val & RT946X_MASK_ICHG) >> RT946X_SHIFT_ICHG; - *current = val * info->current_step + info->current_min; - - return EC_SUCCESS; -} - -int charger_set_current(int current) -{ - int rv; - uint8_t reg_icc; - static int workaround; - const struct charger_info *const info = charger_get_info(); - - /* - * mt6370's minimun regulated current is 500mA REG17[7:2] 0b100, - * values below 0b100 are preserved. - */ - if (IS_ENABLED(CONFIG_CHARGER_MT6370)) - current = MAX(500, current); - - - reg_icc = rt946x_closest_reg(info->current_min, info->current_max, - info->current_step, current); - - rv = rt946x_update_bits(RT946X_REG_CHGCTRL7, RT946X_MASK_ICHG, - reg_icc << RT946X_SHIFT_ICHG); - if (rv) - return rv; - - if (IS_ENABLED(CONFIG_CHARGER_RT9466) || - IS_ENABLED(CONFIG_CHARGER_MT6370)) { - uint32_t curr_ieoc; - - /* - * workaround to make IEOC accurate: - * witht normal charging (ICC >= 900mA), the power path is fully - * turned on. But at low charging current state (ICC < 900mA), - * the power path will only be partially turned on. So under - * such situation, the IEOC is inaccurate. - */ - rv = rt946x_get_ieoc(&curr_ieoc); - if (rv) - return rv; - - if (current < 900 && !workaround) { - /* raise IEOC if charge current is under 900 */ - rv = rt946x_set_ieoc(curr_ieoc + 100); - workaround = 1; - } else if (current >= 900 && workaround) { - /* reset IEOC if charge current is above 900 */ - workaround = 0; - rv = rt946x_set_ieoc(curr_ieoc - 100); - } - } - - return rv; -} - -int charger_get_voltage(int *voltage) -{ - int rv; - int val = 0; - const struct charger_info * const info = charger_get_info(); - - rv = rt946x_read8(RT946X_REG_CHGCTRL4, &val); - if (rv) - return rv; - - val = (val & RT946X_MASK_CV) >> RT946X_SHIFT_CV; - *voltage = val * info->voltage_step + info->voltage_min; - - return EC_SUCCESS; -} - -int charger_set_voltage(int voltage) -{ - uint8_t reg_cv = 0; - const struct charger_info * const info = charger_get_info(); - - reg_cv = rt946x_closest_reg(info->voltage_min, info->voltage_max, - info->voltage_step, voltage); - - return rt946x_update_bits(RT946X_REG_CHGCTRL4, RT946X_MASK_CV, - reg_cv << RT946X_SHIFT_CV); -} - -int charger_discharge_on_ac(int enable) -{ - return rt946x_enable_hz(enable); -} - -/* Setup sourcing current to prevent overload */ -#ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED -static int rt946x_enable_ilim_pin(int en) -{ - int ret; - - ret = (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL3, RT946X_MASK_ILIMEN); - - return ret; -} - -static int rt946x_select_ilmt(enum rt946x_ilmtsel sel) -{ - int ret; - - ret = rt946x_update_bits(RT946X_REG_CHGCTRL2, RT946X_MASK_ILMTSEL, - sel << RT946X_SHIFT_ILMTSEL); - - return ret; -} -#endif /* CONFIG_CHARGER_ILIM_PIN_DISABLED */ - -/* Charging power state initialization */ -int charger_post_init(void) -{ -#ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED - int rv; - - rv = rt946x_select_ilmt(RT946X_ILMTSEL_AICR); - if (rv) - return rv; - /* Disable ILIM pin */ - rv = rt946x_enable_ilim_pin(0); - if (rv) - return rv; -#endif - return EC_SUCCESS; -} - -/* Hardware current ramping (aka AICL: Average Input Current Level) */ -#ifdef CONFIG_CHARGE_RAMP_HW -static int rt946x_get_mivr(int *mivr) -{ - int rv; - int val = 0; - - rv = rt946x_read8(RT946X_REG_CHGCTRL6, &val); - if (rv) - return rv; - - val = (val & RT946X_MASK_MIVR) >> RT946X_SHIFT_MIVR; - *mivr = val * RT946X_MIVR_STEP + RT946X_MIVR_MIN; - - return EC_SUCCESS; -} - -static int rt946x_set_aicl_vth(uint8_t aicl_vth) -{ - uint8_t reg_aicl_vth = 0; - - reg_aicl_vth = rt946x_closest_reg(RT946X_AICLVTH_MIN, - RT946X_AICLVTH_MAX, RT946X_AICLVTH_STEP, aicl_vth); - - return rt946x_update_bits(RT946X_REG_CHGCTRL14, RT946X_MASK_AICLVTH, - reg_aicl_vth << RT946X_SHIFT_AICLVTH); -} - -int charger_set_hw_ramp(int enable) -{ - int rv; - unsigned int mivr = 0; - - if (!enable) { - rv = rt946x_clr_bit(RT946X_REG_CHGCTRL14, RT946X_MASK_AICLMEAS); - return rv; - } - - rv = rt946x_get_mivr(&mivr); - if (rv < 0) - return rv; - - /* - * Check if there's a suitable AICL_VTH. - * The vendor suggests setting AICL_VTH as (MIVR + 200mV). - */ - if ((mivr + 200) > RT946X_AICLVTH_MAX) { - CPRINTF("%s: no suitable vth, mivr = %d\n", __func__, mivr); - return EC_ERROR_INVAL; - } - - rv = rt946x_set_aicl_vth(mivr + 200); - if (rv < 0) - return rv; - - return rt946x_set_bit(RT946X_REG_CHGCTRL14, RT946X_MASK_AICLMEAS); -} - -int chg_ramp_is_stable(void) -{ - int rv; - int val = 0; - - rv = rt946x_read8(RT946X_REG_CHGCTRL14, &val); - val = (val & RT946X_MASK_AICLMEAS) >> RT946X_SHIFT_AICLMEAS; - - return (!rv && !val); -} - -int chg_ramp_is_detected(void) -{ - return 1; -} - -int chg_ramp_get_current_limit(void) -{ - int rv; - int input_current = 0; - - rv = charger_get_input_current(&input_current); - - return rv ? -1 : input_current; -} -#endif /* CONFIG_CHARGE_RAMP_HW */ - -static void rt946x_init(void) -{ - int reg = 0xFFFFFFFF; - - /* Check device id */ - if (charger_device_id(®) || reg != RT946X_VENDOR_ID) { - CPRINTF("RT946X incorrect ID: 0x%02x\n", reg); - return; - } - - /* Check revision id */ - if (rt946x_chip_rev(®)) { - CPRINTF("Failed to read RT946X CHIP REV\n"); - return; - } - CPRINTF("RT946X CHIP REV: 0x%02x\n", reg); - - if (rt946x_init_setting()) { - CPRINTF("RT946X init failed\n"); - return; - } - CPRINTF("RT946X init succeeded\n"); -} -DECLARE_HOOK(HOOK_INIT, rt946x_init, HOOK_PRIO_INIT_I2C + 1); - -#ifdef HAS_TASK_USB_CHG -#ifdef CONFIG_CHARGER_MT6370 -static int mt6370_detect_apple_samsung_ta(int usb_stat) -{ - int ret, reg; - int chg_type = - (usb_stat & MT6370_MASK_USB_STATUS) >> MT6370_SHIFT_USB_STATUS; - int dp_2_3v, dm_2_3v; - - /* Only SDP/CDP/DCP could possibly be Apple/Samsung TA */ - if (chg_type != MT6370_CHG_TYPE_SDPNSTD && - chg_type != MT6370_CHG_TYPE_CDP && - chg_type != MT6370_CHG_TYPE_DCP) - return chg_type; - - if (chg_type == MT6370_CHG_TYPE_SDPNSTD || - chg_type == MT6370_CHG_TYPE_CDP) - if (!(usb_stat & MT6370_MASK_DCD_TIMEOUT)) - return chg_type; - - /* Check D+ > 0.9V */ - ret = rt946x_update_bits(MT6370_REG_QCSTATUS2, MT6360_MASK_CHECK_DPDM, - MT6370_MASK_APP_SS_EN | MT6370_MASK_APP_SS_PL); - ret |= rt946x_read8(MT6370_REG_QCSTATUS2, ®); - - if (ret) - return chg_type; - - /* Normal port (D+ < 0.9V) */ - if (!(reg & MT6370_MASK_SS_OUT)) - return chg_type; - - /* Samsung charger (D+ < 1.5V) */ - if (!(reg & MT6370_MASK_APP_OUT)) - return MT6370_CHG_TYPE_SAMSUNG_CHARGER; - - /* Check D+ > 2.3 V */ - ret = rt946x_update_bits(MT6370_REG_QCSTATUS2, MT6360_MASK_CHECK_DPDM, - MT6370_MASK_APP_REF | MT6370_MASK_APP_SS_PL | - MT6370_MASK_APP_SS_EN); - ret |= rt946x_read8(MT6370_REG_QCSTATUS2, ®); - dp_2_3v = reg & MT6370_MASK_APP_OUT; - - /* Check D- > 2.3 V */ - ret |= rt946x_update_bits( - MT6370_REG_QCSTATUS2, MT6360_MASK_CHECK_DPDM, - MT6370_MASK_APP_REF | MT6370_MASK_APP_DPDM_IN | - MT6370_MASK_APP_SS_PL | MT6370_MASK_APP_SS_EN); - ret |= rt946x_read8(MT6370_REG_QCSTATUS2, ®); - dm_2_3v = reg & MT6370_MASK_APP_OUT; - - if (ret) - return chg_type; - - /* Apple charger */ - if (!dp_2_3v && !dm_2_3v) - /* Apple 2.5W charger */ - return MT6370_CHG_TYPE_APPLE_0_5A_CHARGER; - else if (!dp_2_3v && dm_2_3v) - /* Apple 5W charger */ - return MT6370_CHG_TYPE_APPLE_1_0A_CHARGER; - else if (dp_2_3v && !dm_2_3v) - /* Apple 10W charger */ - return MT6370_CHG_TYPE_APPLE_2_1A_CHARGER; - else - /* Apple 12W charger */ - return MT6370_CHG_TYPE_APPLE_2_4A_CHARGER; -} -#endif - -static int mt6370_get_bc12_device_type(int charger_type) -{ - switch (charger_type) { - case MT6370_CHG_TYPE_SDP: - case MT6370_CHG_TYPE_SDPNSTD: - return CHARGE_SUPPLIER_BC12_SDP; - case MT6370_CHG_TYPE_CDP: - return CHARGE_SUPPLIER_BC12_CDP; - case MT6370_CHG_TYPE_DCP: - case MT6370_CHG_TYPE_SAMSUNG_CHARGER: - case MT6370_CHG_TYPE_APPLE_0_5A_CHARGER: - case MT6370_CHG_TYPE_APPLE_1_0A_CHARGER: - case MT6370_CHG_TYPE_APPLE_2_1A_CHARGER: - case MT6370_CHG_TYPE_APPLE_2_4A_CHARGER: - return CHARGE_SUPPLIER_BC12_DCP; - default: - return CHARGE_SUPPLIER_NONE; - } -} - -/* Returns a mt6370 charger_type. */ -static int mt6370_get_charger_type(void) -{ -#ifdef CONFIG_CHARGER_MT6370 - int reg; - - if (rt946x_read8(MT6370_REG_USBSTATUS1, ®)) - return CHARGE_SUPPLIER_NONE; - return mt6370_detect_apple_samsung_ta(reg); -#else - return CHARGE_SUPPLIER_NONE; -#endif -} - -static int mt6370_get_bc12_ilim(int charge_supplier) -{ - switch (charge_supplier) { - case MT6370_CHG_TYPE_APPLE_0_5A_CHARGER: - return 500; - case MT6370_CHG_TYPE_APPLE_1_0A_CHARGER: - return 1000; - case MT6370_CHG_TYPE_APPLE_2_1A_CHARGER: - if (IS_ENABLED(CONFIG_CHARGE_RAMP_SW) || - IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) - return 2100; - case MT6370_CHG_TYPE_APPLE_2_4A_CHARGER: - if (IS_ENABLED(CONFIG_CHARGE_RAMP_SW) || - IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) - return 2400; - case MT6370_CHG_TYPE_DCP: - if (IS_ENABLED(CONFIG_CHARGE_RAMP_SW) || - IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) - /* A conservative value to prevent a bad charger. */ - return RT946X_AICR_TYP2MAX(2000); - case MT6370_CHG_TYPE_CDP: - case MT6370_CHG_TYPE_SAMSUNG_CHARGER: - return 1500; - case MT6370_CHG_TYPE_SDP: - default: - return USB_CHARGER_MIN_CURR_MA; - } -} - -static int rt946x_get_bc12_device_type(int charger_type) -{ - int reg; - - if (rt946x_read8(RT946X_REG_DPDM1, ®)) - return CHARGE_SUPPLIER_NONE; - - switch (reg & RT946X_MASK_BC12_TYPE) { - case RT946X_MASK_SDP: - return CHARGE_SUPPLIER_BC12_SDP; - case RT946X_MASK_CDP: - return CHARGE_SUPPLIER_BC12_CDP; - case RT946X_MASK_DCP: - return CHARGE_SUPPLIER_BC12_DCP; - default: - return CHARGE_SUPPLIER_NONE; - } -} - -static int rt946x_get_bc12_ilim(int charge_supplier) -{ - switch (charge_supplier) { - case CHARGE_SUPPLIER_BC12_DCP: - if (IS_ENABLED(CONFIG_CHARGE_RAMP_SW) || - IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) - /* A conservative value to prevent a bad charger. */ - return RT946X_AICR_TYP2MAX(2000); - /* fallback */ - case CHARGE_SUPPLIER_BC12_CDP: - return 1500; - case CHARGE_SUPPLIER_BC12_SDP: - default: - return USB_CHARGER_MIN_CURR_MA; - } -} - -void rt946x_interrupt(enum gpio_signal signal) -{ - task_wake(TASK_ID_USB_CHG); -} - -int rt946x_toggle_bc12_detection(void) -{ - int rv; - rv = rt946x_enable_bc12_detection(0); - if (rv) - return rv; - /* mt6370 requires 40us delay to toggle RT946X_MASK_USBCHGEN */ - udelay(40); - return rt946x_enable_bc12_detection(1); -} - -#ifdef CONFIG_CHARGER_MT6370_BC12_GPIO -static void usb_pd_connect(void) -{ - rt946x_toggle_bc12_detection(); -} -DECLARE_HOOK(HOOK_USB_PD_CONNECT, usb_pd_connect, HOOK_PRIO_DEFAULT); -#endif - -static int rt946x_get_adc(enum rt946x_adc_in_sel adc_sel, int *adc_val) -{ - int rv, i, adc_start, adc_result = 0; - int adc_data_h, adc_data_l, aicr; - const int max_wait_times = 6; - - if (in_interrupt_context()) { - CPRINTS("Shouldn't use %s in IRQ", __func__); - return EC_ERROR_INVAL; - } - mutex_lock(&adc_access_lock); -#ifdef CONFIG_CHARGER_MT6370 - mt6370_enable_hidden_mode(1); -#endif - - /* Select ADC to desired channel */ - rv = rt946x_update_bits(RT946X_REG_CHGADC, RT946X_MASK_ADC_IN_SEL, - adc_sel << RT946X_SHIFT_ADC_IN_SEL); - if (rv) - goto out; - - if (adc_sel == MT6370_ADC_IBUS) { - rv = charger_get_input_current(&aicr); - if (rv) - goto out; - } - - /* Start ADC conversation */ - rv = rt946x_set_bit(RT946X_REG_CHGADC, RT946X_MASK_ADC_START); - if (rv) - goto out; - - for (i = 0; i < max_wait_times; i++) { - msleep(35); - rv = mt6370_pmu_reg_test_bit(RT946X_REG_CHGADC, - RT946X_SHIFT_ADC_START, - &adc_start); - if (!adc_start && rv == 0) - break; - } - if (i == max_wait_times) - CPRINTS("%s: wait conversation failed, sel = %d, rv = %d", - __func__, adc_sel, rv); - - /* Read ADC data */ - rv = rt946x_read8(RT946X_REG_ADCDATAH, &adc_data_h); - rv = rt946x_read8(RT946X_REG_ADCDATAL, &adc_data_l); - if (rv) - goto out; - -#if defined(CONFIG_CHARGER_RT9466) || defined(CONFIG_CHARGER_RT9467) - if (adc_sel == RT946X_ADC_VBUS_DIV5) - adc_result = ((adc_data_h << 8) | adc_data_l) * 25; - else - CPRINTS("%s: RT946X not yet support channels", __func__); - *adc_val = adc_result; -#elif defined(CONFIG_CHARGER_MT6370) - /* Calculate ADC value */ - adc_result = (adc_data_h * 256 + adc_data_l) - * mt6370_adc_unit[adc_sel] + mt6370_adc_offset[adc_sel]; - - /* For TS_BAT/TS_BUS, the real unit is 0.25, here we use 25(unit) */ - if (adc_sel == MT6370_ADC_TS_BAT) - adc_result /= 100; -#endif - -out: -#ifdef CONFIG_CHARGER_MT6370 - if (adc_sel == MT6370_ADC_IBUS) { - if (aicr < 400) /* 400mA */ - adc_result = adc_result * 67 / 100; - } - - if (adc_sel != MT6370_ADC_TS_BAT && adc_sel != MT6370_ADC_TEMP_JC) - *adc_val = adc_result / 1000; - else - *adc_val = adc_result; - mt6370_enable_hidden_mode(0); -#endif - mutex_unlock(&adc_access_lock); - return rv; -} - -int charger_get_vbus_voltage(int port) -{ - static int vbus_mv; - - rt946x_get_adc(RT946X_ADC_VBUS_DIV5, &vbus_mv); - return vbus_mv; -} - -#ifdef CONFIG_CHARGER_MT6370 -static int mt6370_toggle_cfo(void) -{ - int rv, data; - - rv = rt946x_read8(MT6370_REG_FLEDEN, &data); - if (rv) - return rv; - - if (data & MT6370_STROBE_EN_MASK) - return rv; - - /* read data */ - rv = rt946x_read8(RT946X_REG_CHGCTRL2, &data); - if (rv) - return rv; - - /* cfo off */ - data &= ~RT946X_MASK_CFO_EN; - rv = rt946x_write8(RT946X_REG_CHGCTRL2, data); - if (rv) - return rv; - - /* cfo on */ - data |= RT946X_MASK_CFO_EN; - return rt946x_write8(RT946X_REG_CHGCTRL2, data); -} - -static int mt6370_pmu_chg_mivr_irq_handler(void) -{ - int rv, ibus = 0, mivr_stat; - - rv = mt6370_pmu_reg_test_bit(MT6370_REG_CHGSTAT1, - MT6370_SHIFT_MIVR_STAT, &mivr_stat); - if (rv) - return rv; - - if (!mivr_stat) { - CPRINTS("%s: mivr stat not act", __func__); - return rv; - } - - rv = rt946x_get_adc(MT6370_ADC_IBUS, &ibus); - if (rv) - return rv; - - if (ibus < 100) /* 100mA */ - rv = mt6370_toggle_cfo(); - - return rv; -} - -static int mt6370_irq_handler(void) -{ - int data, mask, ret, reg_val; - int stat_chg, valid_chg, stat_old, stat_new; - - ret = rt946x_write8(MT6370_REG_IRQMASK, MT6370_IRQ_MASK_ALL); - if (ret) - return ret; - - ret = rt946x_read8(MT6370_REG_IRQIND, ®_val); - if (ret) - return ret; - - /* read stat before reading irq evt */ - ret = rt946x_read8(MT6370_REG_CHGSTAT1, &stat_old); - if (ret) - return ret; - - /* workaround for irq, divided irq event into upper and lower */ - ret = rt946x_read8(MT6370_REG_CHGIRQ1, &data); - if (ret) - return ret; - - /* read stat after reading irq evt */ - ret = rt946x_read8(MT6370_REG_CHGSTAT1, &stat_new); - if (ret) - return ret; - - ret = rt946x_read8(MT6370_REG_CHGMASK1, &mask); - if (ret) - return ret; - - ret = rt946x_write8(MT6370_REG_IRQMASK, 0x00); - if (ret) - return ret; - - stat_chg = stat_old ^ stat_new; - valid_chg = (stat_new & 0xF1) | (~stat_new & 0xF1); - data |= (stat_chg & valid_chg); - data &= ~mask; - if (data) - ret = mt6370_pmu_chg_mivr_irq_handler(); - return ret; -} -#endif /* CONFIG_CHARGER_MT6370 */ - -static void rt946x_bc12_workaround(void) -{ - /* - * There is a parasitic capacitance on D+, - * which results in pulling D+ up too slow while detecting BC1.2. - * So we try to fix this in two steps: - * 1. Pull D+ up to a voltage under 0.6V - * 2. re-toggling and pull D+ up to 0.6V (again) - * and then detect the voltage of D-. - */ - rt946x_toggle_bc12_detection(); - msleep(10); - rt946x_toggle_bc12_detection(); -} -DECLARE_DEFERRED(rt946x_bc12_workaround); - -void usb_charger_task(void *u) -{ - struct charge_port_info chg; - int bc12_type = CHARGE_SUPPLIER_NONE; - int chg_type; - int reg = 0; - int bc12_cnt = 0; - const int max_bc12_cnt = 3; - - chg.voltage = USB_CHARGER_VOLTAGE_MV; - while (1) { -#ifdef CONFIG_CHARGER_MT6370 - mt6370_irq_handler(); -#endif /* CONFIG_CHARGER_MT6370 */ - - rt946x_read8(RT946X_REG_DPDMIRQ, ®); - - /* VBUS attach event */ - if (reg & RT946X_MASK_DPDMIRQ_ATTACH) { - CPRINTS("VBUS attached: %dmV", - charger_get_vbus_voltage(0)); - if (IS_ENABLED(CONFIG_CHARGER_MT6370)) { - chg_type = mt6370_get_charger_type(); - bc12_type = - mt6370_get_bc12_device_type(chg_type); - chg.current = mt6370_get_bc12_ilim(bc12_type); - } else { - bc12_type = - rt946x_get_bc12_device_type(chg_type); - chg.current = rt946x_get_bc12_ilim(bc12_type); - } - CPRINTS("BC12 type %d", bc12_type); - if (bc12_type == CHARGE_SUPPLIER_NONE) - goto bc12_none; - if (IS_ENABLED(CONFIG_WIRELESS_CHARGER_P9221_R7) && - bc12_type == CHARGE_SUPPLIER_BC12_SDP && - wpc_chip_is_online()) { - p9221_notify_vbus_change(1); - CPRINTS("WPC ON"); - } - if (bc12_type == CHARGE_SUPPLIER_BC12_SDP && - ++bc12_cnt < max_bc12_cnt) { - /* - * defer the workaround and awaiting for - * waken up by the interrupt. - */ - hook_call_deferred( - &rt946x_bc12_workaround_data, 5); - goto wait_event; - } - - charge_manager_update_charge(bc12_type, 0, &chg); -bc12_none: - rt946x_enable_bc12_detection(0); - hook_notify(HOOK_AC_CHANGE); - } - - /* VBUS detach event */ - if (reg & RT946X_MASK_DPDMIRQ_DETACH) { - CPRINTS("VBUS detached"); - bc12_cnt = 0; -#ifdef CONFIG_WIRELESS_CHARGER_P9221_R7 - p9221_notify_vbus_change(0); -#endif - charge_manager_update_charge(bc12_type, 0, NULL); - - if (!IS_ENABLED(CONFIG_CHARGER_MT6370_BC12_GPIO)) - rt946x_enable_bc12_detection(1); - - hook_notify(HOOK_AC_CHANGE); - } - -wait_event: - task_wait_event(-1); - } -} - -int usb_charger_ramp_allowed(int supplier) -{ - return supplier == CHARGE_SUPPLIER_BC12_DCP; -} - -int usb_charger_ramp_max(int supplier, int sup_curr) -{ - return rt946x_get_bc12_ilim(supplier); -} -#endif /* HAS_TASK_USB_CHG */ - -/* Non-standard interface functions */ - -int rt946x_enable_charger_boost(int en) -{ - return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL2, RT946X_MASK_CHG_EN); -} - -/* - * rt946x reports VBUS ready after VBUS is up for ~500ms. - * Check if this works for the use case before calling this function. - */ -int rt946x_is_vbus_ready(void) -{ - int val = 0; - - return rt946x_read8(RT946X_REG_CHGSTATC, &val) ? - 0 : !!(val & RT946X_MASK_PWR_RDY); -} - -int rt946x_is_charge_done(void) -{ - int val = 0; - - if (rt946x_read8(RT946X_REG_CHGSTAT, &val)) - return 0; - - val = (val & RT946X_MASK_CHG_STAT) >> RT946X_SHIFT_CHG_STAT; - - return val == RT946X_CHGSTAT_DONE; -} - -int rt946x_cutoff_battery(void) -{ - int val = RT946X_MASK_SHIP_MODE; - -#ifdef CONFIG_CHARGER_MT6370 - val |= RT946X_MASK_TE | RT946X_MASK_CFO_EN | RT946X_MASK_CHG_EN; -#endif - return rt946x_set_bit(RT946X_REG_CHGCTRL2, val); -} - -int rt946x_enable_charge_termination(int en) -{ - return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL2, RT946X_MASK_TE); -} - -int rt946x_enable_charge_eoc(int en) -{ - return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL9, RT946X_MASK_EOC); -} - -#ifdef CONFIG_CHARGER_MT6370 -/* MT6370 LDO */ - -int mt6370_set_ldo_voltage(int mv) -{ - int rv; - int vout_val; - const int vout_mask = MT6370_MASK_LDOVOUT_EN | MT6370_MASK_LDOVOUT_VOUT; - - /* LDO output-off mode to floating. */ - rv = rt946x_update_bits(MT6370_REG_LDOCFG, MT6370_MASK_LDOCFG_OMS, 0); - if (rv) - return rv; - - /* Disable LDO if voltage is zero. */ - if (mv == 0) - return rt946x_clr_bit(MT6370_REG_LDOVOUT, - MT6370_MASK_LDOVOUT_EN); - - vout_val = 1 << MT6370_SHIFT_LDOVOUT_EN; - vout_val |= rt946x_closest_reg(MT6370_LDO_MIN, MT6370_LDO_MAX, - MT6370_LDO_STEP, mv); - return rt946x_update_bits(MT6370_REG_LDOVOUT, vout_mask, vout_val); -} - -/* MT6370 Display bias */ -int mt6370_db_external_control(int en) -{ - return rt946x_update_bits(MT6370_REG_DBCTRL1, MT6370_MASK_DB_EXT_EN, - en << MT6370_SHIFT_DB_EXT_EN); -} - -int mt6370_db_set_voltages(int vbst, int vpos, int vneg) -{ - int rv; - - /* set display bias VBST */ - rv = rt946x_update_bits(MT6370_REG_DBVBST, MT6370_MASK_DB_VBST, - rt946x_closest_reg(MT6370_DB_VBST_MIN, - MT6370_DB_VBST_MAX, - MT6370_DB_VBST_STEP, vbst)); - - /* set display bias VPOS */ - rv |= rt946x_update_bits(MT6370_REG_DBVPOS, MT6370_MASK_DB_VPOS, - rt946x_closest_reg(MT6370_DB_VPOS_MIN, - MT6370_DB_VPOS_MAX, - MT6370_DB_VPOS_STEP, vpos)); - - /* set display bias VNEG */ - rv |= rt946x_update_bits(MT6370_REG_DBVNEG, MT6370_MASK_DB_VNEG, - rt946x_closest_reg(MT6370_DB_VNEG_MIN, - MT6370_DB_VNEG_MAX, - MT6370_DB_VNEG_STEP, vneg)); - - /* Enable VNEG/VPOS discharge when VNEG/VPOS rails disabled. */ - rv |= rt946x_update_bits( - MT6370_REG_DBCTRL2, - MT6370_MASK_DB_VNEG_DISC | MT6370_MASK_DB_VPOS_DISC, - MT6370_MASK_DB_VNEG_DISC | MT6370_MASK_DB_VPOS_DISC); - - return rv; -} - -/* MT6370 BACKLIGHT LED */ - -int mt6370_backlight_set_dim(uint16_t dim) -{ - int rv; - - /* datasheet suggests that update BLDIM2 first then BLDIM */ - rv = rt946x_write8(MT6370_BACKLIGHT_BLDIM2, dim & MT6370_MASK_BLDIM2); - - if (rv) - return rv; - - rv = rt946x_write8(MT6370_BACKLIGHT_BLDIM, - (dim >> MT6370_SHIFT_BLDIM_MSB) & MT6370_MASK_BLDIM); - - return rv; -} - -/* MT6370 RGB LED */ - -int mt6370_led_set_dim_mode(enum mt6370_led_index index, - enum mt6370_led_dim_mode mode) -{ - if (index <= MT6370_LED_ID_OFF || index >= MT6370_LED_ID_COUNT) - return EC_ERROR_INVAL; - - rt946x_update_bits(MT6370_REG_RGBDIM_BASE + index, - MT6370_MASK_RGB_DIMMODE, - mode << MT6370_SHIFT_RGB_DIMMODE); - return EC_SUCCESS; -} - -int mt6370_led_set_color(uint8_t mask) -{ - return rt946x_update_bits(MT6370_REG_RGBEN, MT6370_MASK_RGB_ISNK_ALL_EN, - mask); -} - -int mt6370_led_set_brightness(enum mt6370_led_index index, uint8_t brightness) -{ - if (index >= MT6370_LED_ID_COUNT || index <= MT6370_LED_ID_OFF) - return EC_ERROR_INVAL; - - rt946x_update_bits(MT6370_REG_RGBISNK_BASE + index, - MT6370_MASK_RGBISNK_CURSEL, - brightness << MT6370_SHIFT_RGBISNK_CURSEL); - return EC_SUCCESS; -} - -int mt6370_led_set_pwm_dim_duty(enum mt6370_led_index index, uint8_t dim_duty) -{ - if (index >= MT6370_LED_ID_COUNT || index <= MT6370_LED_ID_OFF) - return EC_ERROR_INVAL; - - rt946x_update_bits(MT6370_REG_RGBDIM_BASE + index, - MT6370_MASK_RGB_DIMDUTY, - dim_duty << MT6370_SHIFT_RGB_DIMDUTY); - return EC_SUCCESS; -} - -int mt6370_led_set_pwm_frequency(enum mt6370_led_index index, - enum mt6370_led_pwm_freq freq) -{ - if (index >= MT6370_LED_ID_COUNT || index <= MT6370_LED_ID_OFF) - return EC_ERROR_INVAL; - - rt946x_update_bits(MT6370_REG_RGBISNK_BASE + index, - MT6370_MASK_RGBISNK_DIMFSEL, - freq << MT6370_SHIFT_RGBISNK_DIMFSEL); - return EC_SUCCESS; -} -#endif /* CONFIG_CHARGER_MT6370 */ diff --git a/driver/charger/rt946x.h b/driver/charger/rt946x.h deleted file mode 100644 index 9797e95255..0000000000 --- a/driver/charger/rt946x.h +++ /dev/null @@ -1,809 +0,0 @@ -/* Copyright 2017 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. - * - * Richtek rt9466/rt9467, Mediatek mt6370 battery charger driver. - */ - -#ifndef __CROS_EC_RT946X_H -#define __CROS_EC_RT946X_H - -/* Charger parameters */ -#define CHARGER_NAME RT946X_CHARGER_NAME -#define CHARGE_V_MAX 4710 -#define CHARGE_V_MIN 3900 -#define CHARGE_V_STEP 10 -#define CHARGE_I_MAX 5000 -#define CHARGE_I_MIN 100 -#define CHARGE_I_OFF 0 -#define CHARGE_I_STEP 100 -#define INPUT_I_MAX 3250 -#define INPUT_I_MIN 100 -#define INPUT_I_STEP 50 - -/* Registers for rt9466, rt9467 */ -#if defined(CONFIG_CHARGER_RT9466) || defined(CONFIG_CHARGER_RT9467) -#define RT946X_REG_CORECTRL0 0x00 -#define RT946X_REG_CORECTRL_RST RT946X_REG_CORECTRL0 -#define RT946X_REG_CHGCTRL1 0x01 -#define RT946X_REG_CHGCTRL2 0x02 -#define RT946X_REG_CHGCTRL3 0x03 -#define RT946X_REG_CHGCTRL4 0x04 -#define RT946X_REG_CHGCTRL5 0x05 -#define RT946X_REG_CHGCTRL6 0x06 -#define RT946X_REG_CHGCTRL7 0x07 -#define RT946X_REG_CHGCTRL8 0x08 -#define RT946X_REG_CHGCTRL9 0x09 -#define RT946X_REG_CHGCTRL10 0x0A -#define RT946X_REG_CHGCTRL11 0x0B -#define RT946X_REG_CHGCTRL12 0x0C -#define RT946X_REG_CHGCTRL13 0x0D -#define RT946X_REG_CHGCTRL14 0x0E -#define RT946X_REG_CHGCTRL15 0x0F -#define RT946X_REG_CHGCTRL16 0x10 -#define RT946X_REG_CHGADC 0x11 - -#ifdef CONFIG_CHARGER_RT9467 -#define RT946X_REG_DPDM1 0x12 -#define RT946X_REG_DPDM2 0x13 -#define RT946X_REG_DPDM3 0x14 -#endif - -#define RT946X_REG_CHGCTRL19 0x18 -#define RT946X_REG_CHGCTRL17 0x19 -#define RT946X_REG_CHGCTRL18 0x1A -#define RT946X_REG_CHGHIDDENCTRL2 0x21 -#define RT946X_REG_CHGHIDDENCTRL4 0x23 -#define RT946X_REG_CHGHIDDENCTRL6 0x25 -#define RT946X_REG_CHGHIDDENCTRL7 0x26 -#define RT946X_REG_CHGHIDDENCTRL8 0x27 -#define RT946X_REG_CHGHIDDENCTRL9 0x28 -#define RT946X_REG_CHGHIDDENCTRL15 0x2E -#define RT946X_REG_DEVICEID 0x40 -#define RT946X_REG_CHGSTAT 0x42 -#define RT946X_REG_CHGNTC 0x43 -#define RT946X_REG_ADCDATAH 0x44 -#define RT946X_REG_ADCDATAL 0x45 -#define RT946X_REG_CHGSTATC 0x50 -#define RT946X_REG_CHGFAULT 0x51 -#define RT946X_REG_TSSTATC 0x52 -#define RT946X_REG_CHGIRQ1 0x53 -#define RT946X_REG_CHGIRQ2 0x54 -#define RT946X_REG_CHGIRQ3 0x55 - -#ifdef CONFIG_CHARGER_RT9467 -#define RT946X_REG_DPDMIRQ 0x56 -#endif - -#define RT946X_REG_CHGSTATCCTRL 0x60 -#define RT946X_REG_CHGFAULTCTRL 0x61 -#define RT946X_REG_TSSTATCCTRL 0x62 -#define RT946X_REG_CHGIRQ1CTRL 0x63 -#define RT946X_REG_CHGIRQ2CTRL 0x64 -#define RT946X_REG_CHGIRQ3CTRL 0x65 - -#ifdef CONFIG_CHARGER_RT9467 -#define RT946X_REG_DPDMIRQCTRL 0x66 -#endif - -#elif defined(CONFIG_CHARGER_MT6370) -/* Registers for mt6370 */ -#define RT946X_REG_DEVICEID 0x00 -#define RT946X_REG_CORECTRL1 0x01 -#define RT946X_REG_CORECTRL2 0x02 -#define RT946X_REG_CORECTRL_RST RT946X_REG_CORECTRL2 -#define MT6370_REG_RSTPASCODE1 0x03 -#define MT6370_REG_RSTPASCODE2 0x04 -#define MT6370_REG_HIDDENPASCODE1 0x07 -#define MT6370_REG_HIDDENPASCODE2 0x08 -#define MT6370_REG_HIDDENPASCODE3 0x09 -#define MT6370_REG_HIDDENPASCODE4 0x0A -#define MT6370_REG_IRQIND 0x0B -#define MT6370_REG_IRQMASK 0x0C -#define MT6370_REG_OSCCTRL 0x10 -#define RT946X_REG_CHGCTRL1 0x11 -#define RT946X_REG_CHGCTRL2 0x12 -#define RT946X_REG_CHGCTRL3 0x13 -#define RT946X_REG_CHGCTRL4 0x14 -#define RT946X_REG_CHGCTRL5 0x15 -#define RT946X_REG_CHGCTRL6 0x16 -#define RT946X_REG_CHGCTRL7 0x17 -#define RT946X_REG_CHGCTRL8 0x18 -#define RT946X_REG_CHGCTRL9 0x19 -#define RT946X_REG_CHGCTRL10 0x1A -#define RT946X_REG_CHGCTRL11 0x1B -#define RT946X_REG_CHGCTRL12 0x1C -#define RT946X_REG_CHGCTRL13 0x1D -#define RT946X_REG_CHGCTRL14 0x1E -#define RT946X_REG_CHGCTRL15 0x1F -#define RT946X_REG_CHGCTRL16 0x20 -#define RT946X_REG_CHGADC 0x21 -#define MT6370_REG_DEVICETYPE 0x22 -#define RT946X_REG_DPDM1 MT6370_REG_DEVICETYPE -#define MT6370_REG_USBSTATUS1 0x27 -#define MT6370_REG_QCSTATUS2 0x29 -#define RT946X_REG_CHGCTRL17 0X2B -#define RT946X_REG_CHGCTRL18 0X2C -#define MT6370_REG_CHGHIDDENCTRL15 0x3E -#define RT946X_REG_CHGSTAT 0X4A -#define RT946X_REG_CHGNTC 0X4B -#define RT946X_REG_ADCDATAH 0X4C -#define RT946X_REG_ADCDATAL 0X4D -/* FLED */ -#define MT6370_REG_FLEDEN 0x7E -/* LDO */ -#define MT6370_REG_LDOCFG 0X80 -#define MT6370_REG_LDOVOUT 0X81 -/* RGB led */ -#define MT6370_REG_RGBDIM_BASE 0x81 -#define MT6370_REG_RGB1DIM 0x82 -#define MT6370_REG_RGB2DIM 0x83 -#define MT6370_REG_RGB3DIM 0x84 -#define MT6370_REG_RGBEN 0x85 -#define MT6370_REG_RGBISNK_BASE 0x85 -#define MT6370_REG_RGB1ISNK 0x86 -#define MT6370_REG_RGB2ISNK 0x87 -#define MT6370_REG_RGB3ISNK 0x88 -#define MT6370_REG_RGBCHRINDDIM 0x92 -#define MT6370_REG_RGBCHRINDCTRL 0x93 - -/* backlight */ -#define MT6370_BACKLIGHT_BLEN 0xA0 -#define MT6370_BACKLIGHT_BLPWM 0xA2 -#define MT6370_BACKLIGHT_BLDIM2 0xA4 -#define MT6370_BACKLIGHT_BLDIM 0xA5 - -/* Display bias */ -#define MT6370_REG_DBCTRL1 0XB0 -#define MT6370_REG_DBCTRL2 0XB1 -#define MT6370_REG_DBVBST 0XB2 -#define MT6370_REG_DBVPOS 0XB3 -#define MT6370_REG_DBVNEG 0XB4 -#define MT6370_REG_CHGIRQ1 0xC0 -#define RT946X_REG_DPDMIRQ 0xC6 - -/* status event */ -#define MT6370_REG_CHGSTAT1 0xD0 -#define RT946X_REG_CHGSTATC MT6370_REG_CHGSTAT1 -#define MT6370_REG_CHGSTAT2 0xD1 -#define RT946X_REG_CHGFAULT MT6370_REG_CHGSTAT2 -#define MT6370_REG_CHGSTAT3 0xD2 -#define MT6370_REG_CHGSTAT4 0xD3 -#define MT6370_REG_CHGSTAT5 0xD4 -#define MT6370_REG_CHGSTAT6 0xD5 -#define MT6370_REG_DPDMSTAT 0xD6 -#define MT6370_REG_DICHGSTAT 0xD7 -#define MT6370_REG_OVPCTRLSTAT 0xD8 -#define MT6370_REG_FLEDSTAT1 0xD9 -#define MT6370_REG_FLEDSTAT2 0xDA -#define MT6370_REG_BASESTAT 0xDB -#define MT6370_REG_LDOSTAT 0xDC -#define MT6370_REG_RGBSTAT 0xDD -#define MT6370_REG_BLSTAT 0xDE -#define MT6370_REG_DBSTAT 0xDF -/* irq mask */ -#define MT6370_REG_CHGMASK1 0xE0 -#define RT946X_REG_CHGSTATCCTRL MT6370_REG_CHGMASK1 -#define MT6370_REG_CHGMASK2 0xE1 -#define MT6370_REG_CHGMASK3 0xE2 -#define MT6370_REG_CHGMASK4 0xE3 -#define MT6370_REG_CHGMASK5 0xE4 -#define MT6370_REG_CHGMASK6 0xE5 -#define MT6370_REG_DPDMMASK1 0xE6 -#define MT6370_REG_DICHGMASK 0xE7 -#define MT6370_REG_OVPCTRLMASK 0xE8 -#define MT6370_REG_FLEDMASK1 0xE9 -#define MT6370_REG_FLEDMASK2 0xEA -#define MT6370_REG_BASEMASK 0xEB -#define MT6370_REG_LDOMASK 0xEC -#define MT6370_REG_RGBMASK 0xED -#define MT6370_REG_BLMASK 0xEE -#define MT6370_REG_DBMASK 0xEF -#else -#error "No suitable charger option defined" -#endif - -/* EOC current */ -#define RT946X_IEOC_MIN 100 -#define RT946X_IEOC_MAX 850 -#define RT946X_IEOC_STEP 50 - -/* Minimum Input Voltage Regulator */ -#define RT946X_MIVR_MIN 3900 -#define RT946X_MIVR_MAX 13400 -#define RT946X_MIVR_STEP 100 - -/* Boost voltage */ -#define RT946X_BOOST_VOLTAGE_MIN 4425 -#define RT946X_BOOST_VOLTAGE_MAX 5825 -#define RT946X_BOOST_VOLTAGE_STEP 25 - -/* IR compensation resistor */ -#define RT946X_IRCMP_RES_MIN 0 -#define RT946X_IRCMP_RES_MAX 175 -#define RT946X_IRCMP_RES_STEP 25 - -/* IR compensation voltage clamp */ -#define RT946X_IRCMP_VCLAMP_MIN 0 -#define RT946X_IRCMP_VCLAMP_MAX 224 -#define RT946X_IRCMP_VCLAMP_STEP 32 - -/* Pre-charge mode threshold voltage */ -#define RT946X_VPREC_MIN 2000 -#define RT946X_VPREC_MAX 3500 -#define RT946X_VPREC_STEP 100 - -/* Pre-charge current */ -#define RT946X_IPREC_MIN 100 -#define RT946X_IPREC_MAX 850 -#define RT946X_IPREC_STEP 50 - -/* AICLVTH */ -#define RT946X_AICLVTH_MIN 4100 -#define RT946X_AICLVTH_MAX 4800 -#define RT946X_AICLVTH_STEP 100 - -/* NTC */ -#define RT946X_BATTEMP_NORMAL 0x00 -#define RT946X_BATTEMP_WARM 0x02 -#define RT946X_BATTEMP_COOL 0x03 -#define RT946X_BATTEMP_COLD 0x05 -#define RT946X_BATTEMP_HOT 0x06 - -/* LDO voltage */ -#define MT6370_LDO_MIN 1600 -#define MT6370_LDO_MAX 4000 -#define MT6370_LDO_STEP 200 - -/* ========== CORECTRL0 0x00 ============ */ -#define RT946X_SHIFT_RST 7 -#define RT946X_SHIFT_CHG_RST 6 -#define RT946X_SHIFT_FLED_RST 5 -#define RT946X_SHIFT_LDO_RST 4 -#define RT946X_SHIFT_RGB_RST 3 -#define RT946X_SHIFT_BL_RST 2 -#define RT946X_SHIFT_DB_RST 1 -#define RT946X_SHIFT_REG_RST 0 - -#define RT946X_MASK_RST BIT(RT946X_SHIFT_RST) -#define RT946X_MASK_CHG_RST BIT(RT946X_SHIFT_CHG_RST) -#define RT946X_MASK_FLED_RST BIT(RT946X_SHIFT_FLED_RST) -#define RT946X_MASK_LDO_RST BIT(RT946X_SHIFT_LDO_RST) -#define RT946X_MASK_RGB_RST BIT(RT946X_SHIFT_RGB_RST) -#define RT946X_MASK_BL_RST BIT(RT946X_SHIFT_BL_RST) -#define RT946X_MASK_DB_RST BIT(RT946X_SHIFT_DB_RST) -#define RT946X_MASK_REG_RST BIT(RT946X_SHIFT_REG_RST) -#define RT946X_MASK_SOFT_RST \ - (RT946X_MASK_CHG_RST | RT946X_MASK_FLED_RST | RT946X_MASK_LDO_RST | \ - RT946X_MASK_RGB_RST | RT946X_MASK_BL_RST | RT946X_MASK_DB_RST | \ - RT946X_MASK_REG_RST) - -/* ========== CHGCTRL1 0x01 ============ */ -#define RT946X_SHIFT_OPA_MODE 0 -#define RT946X_SHIFT_HZ_EN 2 - -#define RT946X_MASK_OPA_MODE BIT(RT946X_SHIFT_OPA_MODE) -#define RT946X_MASK_HZ_EN BIT(RT946X_SHIFT_HZ_EN) - -/* ========== CHGCTRL2 0x02 ============ */ -#define RT946X_SHIFT_SHIP_MODE 7 -#define RT946X_SHIFT_TE 4 -#define RT946X_SHIFT_ILMTSEL 2 -#define RT946X_SHIFT_CFO_EN 1 -#define RT946X_SHIFT_CHG_EN 0 - -#define RT946X_MASK_SHIP_MODE BIT(RT946X_SHIFT_SHIP_MODE) -#define RT946X_MASK_TE BIT(RT946X_SHIFT_TE) -#define RT946X_MASK_ILMTSEL (0x3 << RT946X_SHIFT_ILMTSEL) -#define RT946X_MASK_CFO_EN BIT(RT946X_SHIFT_CFO_EN) -#define RT946X_MASK_CHG_EN BIT(RT946X_SHIFT_CHG_EN) - -/* ========== RSTPASCODE1 0x03 (mt6370) ============ */ -#define MT6370_MASK_RSTPASCODE1 0xA9 - -/* ========== CHGCTRL3 0x03 ============ */ -#define RT946X_SHIFT_AICR 2 -#define RT946X_SHIFT_ILIMEN 0 - -#define RT946X_MASK_AICR (0x3F << RT946X_SHIFT_AICR) -#define RT946X_MASK_ILIMEN BIT(RT946X_SHIFT_ILIMEN) - -/* - * The accuracy of AICR is 7%. So if AICR = 2150, - * then Max=2150, Typ=2000, Min=1860. And plus 25 since the AICR - * is 50ma a step. - */ -#define RT946X_AICR_TYP2MAX(x) ((x) * 107 / 100 + 25) - -/* ========== RSTPASCODE2 0x04 (mt6370) ============ */ -#define MT6370_MASK_RSTPASCODE2 0x96 - -/* ========== CHGCTRL4 0x04 ============ */ -#define RT946X_SHIFT_CV 1 - -#define RT946X_MASK_CV 0xFE - -/* ========== CHGCTRL5 0x05 ============ */ -#define RT946X_SHIFT_BOOST_VOLTAGE 2 - -#define RT946X_MASK_BOOST_VOLTAGE 0xFC - -/* ========== CHGCTRL6 0x06 ============ */ -#define RT946X_SHIFT_MIVR 1 - -#define RT946X_MASK_MIVR (0x7F << RT946X_SHIFT_MIVR) - -/* ========== CHGCTRL7 0x07 ============ */ -#define RT946X_SHIFT_ICHG 2 - -#define RT946X_MASK_ICHG (0x3F << RT946X_SHIFT_ICHG) - -/* ========== CHGCTRL8 0x08 ============ */ -#define RT946X_SHIFT_VPREC 4 -#define RT946X_SHIFT_IPREC 0 - -#define RT946X_MASK_VPREC (0xF << RT946X_SHIFT_VPREC) -#define RT946X_MASK_IPREC (0xF << RT946X_SHIFT_IPREC) - -/* ========== CHGCTRL9 0x09 ============ */ -#define RT946X_SHIFT_EOC 3 -#define RT946X_SHIFT_IEOC 4 - -#define RT946X_MASK_EOC BIT(RT946X_SHIFT_EOC) -#define RT946X_MASK_IEOC (0xF << RT946X_SHIFT_IEOC) - -/* ========== CHGCTRL10 0x0A ============ */ -#define RT946X_SHIFT_BOOST_CURRENT 0 - -#define RT946X_MASK_BOOST_CURRENT 0x07 - -/* ========== CHGCTRL12 0x0C ============ */ -#define RT946X_SHIFT_TMR_EN 1 -#define MT6370_IRQ_MASK_ALL 0xFE - -#define RT946X_MASK_TMR_EN BIT(RT946X_SHIFT_TMR_EN) - -/* ========== CHGCTRL13 0x0D ============ */ -#define RT946X_SHIFT_WDT_EN 7 - -#define RT946X_MASK_WDT_EN BIT(RT946X_SHIFT_WDT_EN) - -/* ========== CHGCTRL14 0x0E ============ */ -#define RT946X_SHIFT_AICLMEAS 7 -#define RT946X_SHIFT_AICLVTH 0 - -#define RT946X_MASK_AICLMEAS BIT(RT946X_SHIFT_AICLMEAS) -#define RT946X_MASK_AICLVTH 0x07 - -/* ========== CHGCTRL16 0x10 ============ */ -#define RT946X_SHIFT_JEITA_EN 4 - -#define RT946X_MASK_JEITA_EN BIT(RT946X_SHIFT_JEITA_EN) - -/* ========== CHGADC 0x11 ============ */ -#define RT946X_SHIFT_ADC_IN_SEL 4 -#define RT946X_SHIFT_ADC_START 0 - -#define RT946X_MASK_ADC_IN_SEL (0xF << RT946X_SHIFT_ADC_IN_SEL) -#define RT946X_MASK_ADC_START BIT(RT946X_SHIFT_ADC_START) - -/* ========== CHGDPDM1 0x12 (rt946x) DEVICETYPE 0x22 (mt6370) ============ */ -#define RT946X_SHIFT_USBCHGEN 7 -#define RT946X_SHIFT_DCDTIMEOUT 6 -#define RT946X_SHIFT_DCP 2 -#define RT946X_SHIFT_CDP 1 -#define RT946X_SHIFT_SDP 0 - -#define RT946X_MASK_USBCHGEN BIT(RT946X_SHIFT_USBCHGEN) -#define RT946X_MASK_DCDTIMEOUT BIT(RT946X_SHIFT_DCDTIMEOUT) -#define RT946X_MASK_DCP BIT(RT946X_SHIFT_DCP) -#define RT946X_MASK_CDP BIT(RT946X_SHIFT_CDP) -#define RT946X_MASK_SDP BIT(RT946X_SHIFT_SDP) - -#define RT946X_MASK_BC12_TYPE (RT946X_MASK_DCP | \ - RT946X_MASK_CDP | \ - RT946X_MASK_SDP) - -/* ========== USBSTATUS1 0x27 (mt6370) ============ */ -#define MT6370_SHIFT_DCD_TIMEOUT 2 -#define MT6370_SHIFT_USB_STATUS 4 - -#define MT6370_MASK_USB_STATUS 0x70 - -#define MT6370_CHG_TYPE_NOVBUS 0 -#define MT6370_CHG_TYPE_BUSY 1 -#define MT6370_CHG_TYPE_SDP 2 -#define MT6370_CHG_TYPE_SDPNSTD 3 -#define MT6370_CHG_TYPE_DCP 4 -#define MT6370_CHG_TYPE_CDP 5 -#define MT6370_CHG_TYPE_SAMSUNG_CHARGER 6 -#define MT6370_CHG_TYPE_APPLE_0_5A_CHARGER 7 -#define MT6370_CHG_TYPE_APPLE_1_0A_CHARGER 8 -#define MT6370_CHG_TYPE_APPLE_2_1A_CHARGER 9 -#define MT6370_CHG_TYPE_APPLE_2_4A_CHARGER 10 - -#define MT6370_MASK_DCD_TIMEOUT BIT(MT6370_SHIFT_DCD_TIMEOUT) - -/* ========== QCSTATUS2 0x29 (mt6370) ============ */ -#define MT6370_SHIFT_APP_OUT 5 -#define MT6370_SHIFT_SS_OUT 4 -#define MT6370_SHIFT_APP_REF 3 -#define MT6370_SHIFT_APP_DPDM_IN 2 -#define MT6370_SHIFT_APP_SS_PL 1 -#define MT6370_SHIFT_APP_SS_EN 0 - -#define MT6370_MASK_APP_OUT BIT(MT6370_SHIFT_APP_OUT) -#define MT6370_MASK_SS_OUT BIT(MT6370_SHIFT_SS_OUT) -#define MT6370_MASK_APP_REF BIT(MT6370_SHIFT_APP_REF) -#define MT6370_MASK_APP_DPDM_IN BIT(MT6370_SHIFT_APP_DPDM_IN) -#define MT6370_MASK_APP_SS_PL BIT(MT6370_SHIFT_APP_SS_PL) -#define MT6370_MASK_APP_SS_EN BIT(MT6370_SHIFT_APP_SS_EN) - -#define MT6360_MASK_CHECK_DPDM (MT6370_MASK_APP_SS_EN | \ - MT6370_MASK_APP_SS_PL | \ - MT6370_MASK_APP_DPDM_IN | \ - MT6370_MASK_APP_REF) - -/* ========== CHGCTRL18 0x1A ============ */ -#define RT946X_SHIFT_IRCMP_RES 3 -#define RT946X_SHIFT_IRCMP_VCLAMP 0 - -#define RT946X_MASK_IRCMP_RES (0x7 << RT946X_SHIFT_IRCMP_RES) -#define RT946X_MASK_IRCMP_VCLAMP (0x7 << RT946X_SHIFT_IRCMP_VCLAMP) - -/* ========== DEVICE_ID 0x40 ============ */ -#define RT946X_MASK_VENDOR_ID 0xF0 -#define RT946X_MASK_CHIP_REV 0x0F - -/* ========== CHGSTAT 0x42 ============ */ -#define RT946X_SHIFT_CHG_STAT 6 -#define RT946X_SHIFT_ADC_STAT 0 - -#define RT946X_MASK_CHG_STAT (0x3 << RT946X_SHIFT_CHG_STAT) -#define RT946X_MASK_ADC_STAT BIT(RT946X_SHIFT_ADC_STAT) - -/* ========== CHGNTC 0x43 ============ */ -#define RT946X_SHIFT_BATNTC_FAULT 4 - -#define RT946X_MASK_BATNTC_FAULT 0x70 - -/* ========== CHGSTATC 0x50 (rt946x) ============ */ -#define RT946X_SHIFT_PWR_RDY 7 - -#define RT946X_MASK_PWR_RDY BIT(RT946X_SHIFT_PWR_RDY) - -/* ========== CHGFAULT 0x51 (rt946x) ============ */ -#if defined(CONFIG_CHARGER_RT9466) || defined(CONFIG_CHARGER_RT9467) -#define RT946X_SHIFT_CHG_VSYSUV 4 -#define RT946X_SHIFT_CHG_VSYSOV 5 -#define RT946X_SHIFT_CHG_VBATOV 6 -#define RT946X_SHIFT_CHG_VBUSOV 7 - -#define RT946X_MASK_CHG_VSYSUV BIT(RT946X_SHIFT_CHG_VSYSUV) -#define RT946X_MASK_CHG_VSYSOV BIT(RT946X_SHIFT_CHG_VSYSOV) -#define RT946X_MASK_CHG_VBATOV BIT(RT946X_SHIFT_CHG_VBATOV) -#define RT946X_MASK_CHG_VBUSOV BIT(RT946X_SHIFT_CHG_VBUSOV) -#endif - -/* ========== DPDMIRQ 0x56 ============ */ -#if defined(CONFIG_CHARGER_RT9467) || defined(CONFIG_CHARGER_MT6370) -#define RT946X_SHIFT_DPDMIRQ_DETACH 1 -#define RT946X_SHIFT_DPDMIRQ_ATTACH 0 - -#define RT946X_MASK_DPDMIRQ_DETACH BIT(RT946X_SHIFT_DPDMIRQ_DETACH) -#define RT946X_MASK_DPDMIRQ_ATTACH BIT(RT946X_SHIFT_DPDMIRQ_ATTACH) -#endif - -/* ========== FLED EN 0x7E (mt6370) ============ */ -#define MT6370_STROBE_EN_MASK 0x04 - -/* ========== LDOCFG 0x80 (mt6370) ============ */ -#define MT6370_SHIFT_LDOCFG_OMS 6 - -#define MT6370_MASK_LDOCFG_OMS BIT(MT6370_SHIFT_LDOCFG_OMS) - -/* ========== LDOVOUT 0x81 (mt6370) ============ */ -#define MT6370_SHIFT_LDOVOUT_EN 7 -#define MT6370_SHIFT_LDOVOUT_VOUT 0 - -#define MT6370_MASK_LDOVOUT_EN BIT(MT6370_SHIFT_LDOVOUT_EN) -#define MT6370_MASK_LDOVOUT_VOUT (0xf << MT6370_SHIFT_LDOVOUT_VOUT) - -/* ========== RGBDIM 0x82/0x83/0x84 (mt6370) ============ */ -#define MT6370_LED_PWM_DIMDUTY_MIN 0x00 -#define MT6370_LED_PWM_DIMDUTY_MAX 0x1f - -#define MT6370_SHIFT_RGB_DIMMODE 5 -#define MT6370_SHIFT_RGB_DIMDUTY 0 - -#define MT6370_MASK_RGB_DIMMODE (3 << MT6370_SHIFT_RGB_DIMMODE) -#define MT6370_MASK_RGB_DIMDUTY (0x1f << MT6370_SHIFT_RGB_DIMDUTY) - -/* ========== RGBEN 0x85 (mt6370) ============ */ -#define MT6370_SHIFT_RGB_ISNK1DIM 7 -#define MT6370_SHIFT_RGB_ISNK2DIM 6 -#define MT6370_SHIFT_RGB_ISNK3DIM 5 -#define MT6370_SHIFT_RGB_ISNKDIM_BASE 8 - -#define MT6370_MASK_RGB_ISNK1DIM_EN BIT(MT6370_SHIFT_RGB_ISNK1DIM) -#define MT6370_MASK_RGB_ISNK2DIM_EN BIT(MT6370_SHIFT_RGB_ISNK2DIM) -#define MT6370_MASK_RGB_ISNK3DIM_EN BIT(MT6370_SHIFT_RGB_ISNK3DIM) -#define MT6370_MASK_RGB_ISNK_ALL_EN (MT6370_MASK_RGB_ISNK1DIM_EN | \ - MT6370_MASK_RGB_ISNK2DIM_EN | \ - MT6370_MASK_RGB_ISNK3DIM_EN) - -/* ========== RGB_ISNK 0x86/0x87/0x88 (mt6370) ============ */ -#define MT6370_LED_BRIGHTNESS_MIN 0 -#define MT6370_LED_BRIGHTNESS_MAX 7 - -#define MT6370_SHIFT_RGBISNK_CURSEL 0 -#define MT6370_SHIFT_RGBISNK_DIMFSEL 3 -#define MT6370_MASK_RGBISNK_CURSEL (0x7 << MT6370_SHIFT_RGBISNK_CURSEL) -#define MT6370_MASK_RGBISNK_DIMFSEL (0x7 << MT6370_SHIFT_RGBISNK_DIMFSEL) - -/* ========== DBCTRL1 (mt6370) ============ */ -#define MT6370_SHIFT_DB_EXT_EN 0 -#define MT6370_SHIFT_DB_PERIODIC_FIX 4 -#define MT6370_SHIFT_DB_SINGLE_PIN 5 -#define MT6370_SHIFT_DB_FREQ_PM 6 -#define MT6370_SHIFT_DB_PERIODIC_MODE 7 - -#define MT6370_MASK_DB_EXT_EN 1 -#define MT6370_MASK_DB_PERIODIC_FIX 1 -#define MT6370_MASK_DB_SINGLE_PIN 1 -#define MT6370_MASK_DB_FREQ_PM 1 -#define MT6370_MASK_DB_PERIODIC_MODE 1 - -/* ========== DBCTRL1 (mt6370) ============ */ -#define MT6370_MASK_DB_VNEG_DISC BIT(2) -#define MT6370_MASK_DB_VPOS_DISC BIT(5) - -/* ========== DBVBST (mt6370) ============ */ -#define MT6370_SHIFT_DB_VBST 0 - -#define MT6370_MASK_DB_VBST 0x3f - -#define MT6370_DB_VBST_MAX 6200 -#define MT6370_DB_VBST_MIN 4000 -#define MT6370_DB_VBST_STEP 50 - -/* ========== DBVPOS (mt6370) ============ */ -#define MT6370_SHIFT_DB_VPOS 0 - -#define MT6370_MASK_DB_VPOS 0x3f - -#define MT6370_DB_VPOS_MAX 6000 -#define MT6370_DB_VPOS_MIN 4000 -#define MT6370_DB_VPOS_STEP 50 - -/* ========== DBVNEG (mt6370) ============ */ -#define MT6370_SHIFT_DB_VNEG 0 - -#define MT6370_MASK_DB_VNEG 0x3f - -#define MT6370_DB_VNEG_MAX 6000 -#define MT6370_DB_VNEG_MIN 4000 -#define MT6370_DB_VNEG_STEP 50 - -/* ========== BLEN 0xA0 (mt6370) ============ */ -#define MT6370_SHIFT_BLED_EXT_EN 7 -#define MT6370_SHIFT_BLED_EN 6 -#define MT6370_SHIFT_BLED_1CH_EN 5 -#define MT6370_SHIFT_BLED_2CH_EN 4 -#define MT6370_SHIFT_BLED_3CH_EN 3 -#define MT6370_SHIFT_BLED_4CH_EN 2 -#define MT6370_SHIFT_BLED_CODE 1 -#define MT6370_SHIFT_BLED_CONFIG 0 - -#define MT6370_MASK_BLED_EXT_EN BIT(MT6370_SHIFT_BLED_EXT_EN) -#define MT6370_MASK_BLED_EN BIT(MT6370_SHIFT_BLED_EN) -#define MT6370_MASK_BLED_1CH_EN BIT(MT6370_SHIFT_BLED_1CH_EN) -#define MT6370_MASK_BLED_2CH_EN BIT(MT6370_SHIFT_BLED_2CH_EN) -#define MT6370_MASK_BLED_3CH_EN BIT(MT6370_SHIFT_BLED_3CH_EN) -#define MT6370_MASK_BLED_4CH_EN BIT(MT6370_SHIFT_BLED_4CH_EN) - -#define MT6370_BLED_CODE_LINEAR BIT(MT6370_SHIFT_BLED_CODE) -#define MT6370_BLED_CODE_EXP 0 - -#define MT6370_BLED_CONFIG_ACTIVE_HIGH BIT(MT6370_SHIFT_BLED_CONFIG) -#define MT6370_BLED_CONFIG_ACTIVE_LOW 0 - -/* ========== BLPWM 0xA2 (mt6370) ============ */ -#define MT6370_SHIFT_BLPWM_BLED_PWM 7 - -#define MT6370_MASK_BLPWM_BLED_PWM BIT(MT6370_SHIFT_BLPWM_BLED_PWM) - -/* ========== BLDIM2 0xA4 (mt6370) ============ */ -#define MT6370_MASK_BLDIM2 0x7 - -/* ========== BLDIM 0xA5 (mt6370) ============ */ -#define MT6370_SHIFT_BLDIM_MSB 3 -#define MT6370_MASK_BLDIM 0xff - -#define MT6370_BLDIM_DEFAULT 0x7ff - -/* ========== CHG_IRQ1 0xC0 (mt6370) ============ */ -#define MT6370_SHIFT_MIVR_EVT 6 -#define MT6370_MASK_MIVR_EVT BIT(MT6370_SHIFT_MIVR_EVT) - -/* ========== CHGSTAT2 0xD0 (mt6370) ============ */ -#define MT6370_SHIFT_MIVR_STAT 6 - -/* ========== CHGSTAT2 0xD1 (mt6370) ============ */ -#ifdef CONFIG_CHARGER_MT6370 -#define MT6370_SHIFT_CHG_VBUSOV_STAT 7 -#define MT6370_SHIFT_CHG_VBATOV_STAT 6 - -#define RT946X_MASK_CHG_VBATOV MT6370_SHIFT_CHG_VBATOV_STAT - -#define MT6370_MASK_CHG_VBUSOV_STAT BIT(MT6370_SHIFT_CHG_VBUSOV_STAT) -#define MT6370_MASK_CHG_VBATOV_STAT BIT(MT6370_SHIFT_CHG_VBATOV_STAT) -#endif - -/* ADC unit/offset */ -#define MT6370_ADC_UNIT_VBUS_DIV5 25000 /* uV */ -#define MT6370_ADC_UNIT_VBUS_DIV2 10000 /* uV */ -#define MT6370_ADC_UNIT_VSYS 5000 /* uV */ -#define MT6370_ADC_UNIT_VBAT 5000 /* uV */ -#define MT6370_ADC_UNIT_TS_BAT 25 /* 0.01% */ -#define MT6370_ADC_UNIT_IBUS 50000 /* uA */ -#define MT6370_ADC_UNIT_IBAT 50000 /* uA */ -#define MT6370_ADC_UNIT_CHG_VDDP 5000 /* uV */ -#define MT6370_ADC_UNIT_TEMP_JC 2 /* degree */ - -#define MT6370_ADC_OFFSET_VBUS_DIV5 0 /* mV */ -#define MT6370_ADC_OFFSET_VBUS_DIV2 0 /* mV */ -#define MT6370_ADC_OFFSET_VSYS 0 /* mV */ -#define MT6370_ADC_OFFSET_VBAT 0 /* mV */ -#define MT6370_ADC_OFFSET_TS_BAT 0 /* % */ -#define MT6370_ADC_OFFSET_IBUS 0 /* mA */ -#define MT6370_ADC_OFFSET_IBAT 0 /* mA */ -#define MT6370_ADC_OFFSET_CHG_VDDP 0 /* mV */ -#define MT6370_ADC_OFFSET_TEMP_JC (-40) /* degree */ - -/* ========== Variant-specific configuration ============ */ -#if defined(CONFIG_CHARGER_RT9466) - #define RT946X_CHARGER_NAME "rt9466" - #define RT946X_VENDOR_ID 0x80 - #define RT946X_ADDR_FLAGS 0x53 -#elif defined(CONFIG_CHARGER_RT9467) - #define RT946X_CHARGER_NAME "rt9467" - #define RT946X_VENDOR_ID 0x90 - #define RT946X_ADDR_FLAGS 0x5B -#elif defined(CONFIG_CHARGER_MT6370) - #define RT946X_CHARGER_NAME "mt6370" - #define RT946X_VENDOR_ID 0xE0 - #define RT946X_ADDR_FLAGS 0x34 -#else - #error "No suitable charger option defined" -#endif - -/* RT946x specific interface functions */ - -/* Power on reset */ -int rt946x_por_reset(void); - -/* Interrupt handler for rt946x */ -void rt946x_interrupt(enum gpio_signal signal); - -/* Enable/Disable rt946x (in charger or boost mode) */ -int rt946x_enable_charger_boost(int en); - -/* - * Return 1 if VBUS is ready, which means - * UVLO < VBUS < VOVP && VBUS > BATS + VSLP - */ -int rt946x_is_vbus_ready(void); - -/* Return 1 if rt946x triggers charge termination due to full charge. */ -int rt946x_is_charge_done(void); - -/* - * Cut off the battery (force BATFET to turn off). - * Return 0 if it succeeds. - */ -int rt946x_cutoff_battery(void); - -/* Enable/Disable charge temination */ -int rt946x_enable_charge_termination(int en); - -/* Enable/Disable charge EOC */ -int rt946x_enable_charge_eoc(int en); - -/** - * Toggle BC12 detection - * - * @return EC_SUCCESS or EC_ERROR_* - */ -int rt946x_toggle_bc12_detection(void); - -struct rt946x_init_setting { - uint16_t eoc_current; - uint16_t mivr; - uint16_t ircmp_vclamp; - uint16_t ircmp_res; - uint16_t boost_voltage; - uint16_t boost_current; -}; - -#ifdef CONFIG_CHARGER_MT6370 - -/* - * Set LDO voltage. - * Disable LDO if voltage is zero. - */ -int mt6370_set_ldo_voltage(int mv); - -enum mt6370_led_index { - MT6370_LED_ID_OFF = 0, - MT6370_LED_ID1 = 1, - MT6370_LED_ID2 = 2, - MT6370_LED_ID3 = 3, - MT6370_LED_ID_COUNT, /* The bound of the ID indexes. */ -}; - -enum mt6370_led_dim_mode { - MT6370_LED_DIM_MODE_PWM = 0, - MT6370_LED_DIM_MODE_BREATH = 1, - MT6370_LED_DIM_MODE_REGISTER = 3 -}; - -enum mt6370_led_pwm_freq { - MT6370_LED_PWM_FREQ01 = 0, /* 0.1 Hz */ - MT6370_LED_PWM_FREQ02 = 1, /* 0.2 Hz */ - MT6370_LED_PWM_FREQ05 = 2, /* 0.5 Hz */ - MT6370_LED_PWM_FREQ1 = 3, /* 1 Hz */ - MT6370_LED_PWM_FREQ2 = 4, /* 2 Hz */ - MT6370_LED_PWM_FREQ5 = 5, /* 5 Hz */ - MT6370_LED_PWM_FREQ200 = 6, /* 200 Hz */ - MT6370_LED_PWM_FREQ1000 = 7 /* 1000 Hz */ -}; - -/* Enable display bias external pin control. */ -int mt6370_db_external_control(int en); - -/** - * Set backlight LED dim. - * - * dim: A value from 0 to 2047. - * return: EC_SUCCESS on success, and EC_ERROR_* otherwise. - */ -int mt6370_backlight_set_dim(uint16_t dim); - -/** - * MT6370 display bias voltage settings. - * - * Set disaply bias voltages for the panel. - * - * vbst: VBST config in mv. - * vpos: VPOS config in mv. - * vneg: VNEG config in mv. - * return: EC_SUCCESS on succes, and EC_ERROR_* otherwise. - */ -int mt6370_db_set_voltages(int vbst, int vpos, int vneg); - -/* Set LED brightness */ -int mt6370_led_set_brightness(enum mt6370_led_index index, uint8_t brightness); - -/** - * Set LED Color - * - * mask: Bitmap indicating 1=on 0=off for each LED. 000 = all off. - * Combination of MT6370_MASK_RGB_ISNK1/2/3DIM_EN. - * return: EC_SUCCESS or EC_ERROR_* on error. - */ -int mt6370_led_set_color(uint8_t mask); - -/* Set LED dim mode, available modes: REGISTER, PWM, BREATH. */ -int mt6370_led_set_dim_mode(enum mt6370_led_index index, - enum mt6370_led_dim_mode mode); - -/* Set LED PWM mode duty */ -int mt6370_led_set_pwm_dim_duty(enum mt6370_led_index index, uint8_t dim_duty); - -/* Set LED PWM mode frequency */ -int mt6370_led_set_pwm_frequency(enum mt6370_led_index index, - enum mt6370_led_pwm_freq freq); -#endif - -#endif /* __CROS_EC_RT946X_H */ diff --git a/driver/charger/sy21612.c b/driver/charger/sy21612.c deleted file mode 100644 index 0a1b122d28..0000000000 --- a/driver/charger/sy21612.c +++ /dev/null @@ -1,214 +0,0 @@ -/* Copyright 2017 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. - * - * SILERGY SY21612 buck-boost converter driver. - */ - - -#include "console.h" -#include "hooks.h" -#include "i2c.h" -#include "sy21612.h" -#include "task.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHARGER, outstr) -#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) -#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) - -static int sy21612_clear_set_reg(int reg, int clear, int set) -{ - int val, old_val, rv; - - rv = i2c_read8(I2C_PORT_SY21612, SY21612_ADDR_FLAGS, reg, &old_val); - if (rv) - return rv; - - val = old_val; - val &= ~clear; - val |= set; - - if (val != old_val || clear || set) - rv = i2c_write8(I2C_PORT_SY21612, SY21612_ADDR_FLAGS, - reg, val); - - return rv; -} - -static int sy21612_read(int reg, int *val) -{ - return i2c_read8(I2C_PORT_SY21612, SY21612_ADDR_FLAGS, reg, val); -} - -int sy21612_enable_regulator(int enable) -{ - return enable ? - sy21612_clear_set_reg(SY21612_CTRL1, 0, SY21612_CTRL1_REG_EN) : - sy21612_clear_set_reg(SY21612_CTRL1, SY21612_CTRL1_REG_EN, 0); -} - -int sy21612_enable_adc(int enable) -{ - return enable ? - sy21612_clear_set_reg(SY21612_CTRL1, 0, SY21612_CTRL1_ADC_EN) : - sy21612_clear_set_reg(SY21612_CTRL1, SY21612_CTRL1_ADC_EN, 0); -} - -int sy21612_set_adc_mode(int auto_mode) -{ - return auto_mode ? - sy21612_clear_set_reg(SY21612_CTRL1, - 0, SY21612_CTRL1_ADC_AUTO_MODE) : - sy21612_clear_set_reg(SY21612_CTRL1, - SY21612_CTRL1_ADC_AUTO_MODE, 0); -} - -int sy21612_set_vbus_discharge(int auto_discharge) -{ - return auto_discharge ? - sy21612_clear_set_reg(SY21612_CTRL1, - SY21612_CTRL1_VBUS_NDISCHG, 0) : - sy21612_clear_set_reg(SY21612_CTRL1, - 0, SY21612_CTRL1_VBUS_NDISCHG); -} - -int sy21612_set_switching_freq(enum sy21612_switching_freq freq) -{ - return sy21612_clear_set_reg(SY21612_CTRL2, - SY21612_CTRL2_FREQ_MASK, - freq << SY21612_CTRL2_FREQ_SHIFT); -} - -int sy21612_set_vbus_volt(enum sy21612_vbus_volt volt) -{ - return sy21612_clear_set_reg(SY21612_CTRL2, - SY21612_CTRL2_VBUS_MASK, - volt << SY21612_CTRL2_VBUS_SHIFT); -} - -int sy21612_set_vbus_adj(enum sy21612_vbus_adj adj) -{ - return sy21612_clear_set_reg(SY21612_CTRL2, - SY21612_CTRL2_VBUS_ADJ_MASK, - adj << SY21612_CTRL2_VBUS_ADJ_SHIFT); -} - -int sy21612_set_sink_mode(int sink_mode) -{ - return sink_mode ? - sy21612_clear_set_reg(SY21612_PROT2, - 0, SY21612_PROT2_SINK_MODE) : - sy21612_clear_set_reg(SY21612_PROT2, - SY21612_PROT2_SINK_MODE, 0); -} - -int sy21612_is_power_good(void) -{ - int reg; - - if (sy21612_read(SY21612_STATE, ®)) - return 0; - - return reg & SY21612_STATE_POWER_GOOD; -} - -int sy21612_read_clear_int(void) -{ - int reg; - - if (sy21612_read(SY21612_INT, ®)) - return 0; - - return reg; -} - -int sy21612_get_vbat_voltage(void) -{ - int reg; - - if (sy21612_read(SY21612_VBAT_VOLT, ®)) - return 0; - - return reg * 25000 / 255; -} - -int sy21612_get_vbus_voltage(void) -{ - int reg; - - if (sy21612_read(SY21612_VBUS_VOLT, ®)) - return 0; - - return reg * 25000 / 255; -} - -int sy21612_get_vbus_current(void) -{ - int reg; - - if (sy21612_read(SY21612_VBUS_CURRENT, ®)) - return 0; - - /* - * delta V in range 0 ~ 67mV - * sense resistor 10 mOhm - */ - return reg * 6700 / 255; -} - -void sy21612_int(enum gpio_signal signal) -{ -#ifdef HAS_TASK_SY21612 - task_wake(TASK_ID_SY21612); -#endif -} - -#ifdef HAS_TASK_SY21612 -void sy21612_task(void) -{ - int flags; - - while (1) { - task_wait_event(-1); - if (sy21612_read(SY21612_INT, &flags)) - continue; - /* TODO: notify the error condition and enable regulator */ - if (flags & SY21612_INT_VBUS_OCP) - CPUTS("buck-boost VBUS OCP\n"); - if (flags & SY21612_INT_INDUCTOR_OCP) - CPUTS("buck-boost inductor OCP\n"); - if (flags & SY21612_INT_UVP) - CPUTS("buck-boost UVP\n"); - if (flags & SY21612_INT_OTP) - CPUTS("buck-boost OTP\n"); - } -} -#endif - -#ifdef CONFIG_CMD_CHARGER -static int command_sy21612(int argc, char **argv) -{ - int i, val, rv; - - ccputs("sy21612 regs:\n"); - for (i = 0; i < 9; i++) { - ccprintf("[%02x] ", i); - rv = sy21612_read(i, &val); - if (rv) - ccprintf(" x (%d)\n", rv); - else - ccprintf("%02x - %pb\n", val, BINARY_VALUE(val, 8)); - } - - ccprintf("vbat voltage: %d mV\n", sy21612_get_vbat_voltage()); - ccprintf("vbus voltage: %d mV\n", sy21612_get_vbus_voltage()); - ccprintf("vbus current: %d mA\n", sy21612_get_vbus_current()); - - return 0; -} -DECLARE_CONSOLE_COMMAND(sy21612, command_sy21612, - NULL, NULL); -#endif - diff --git a/driver/charger/sy21612.h b/driver/charger/sy21612.h deleted file mode 100644 index befb8e6a35..0000000000 --- a/driver/charger/sy21612.h +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2017 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. - * - * SILERGY SY21612 buck-boost converter driver. - */ - -#ifndef __CROS_EC_SY21612_H -#define __CROS_EC_SY21612_H - -#include "gpio.h" - -#ifndef SY21612_ADDR_FLAGS -#define SY21612_ADDR_FLAGS 0x71 -#endif - -enum sy21612_switching_freq { - SY21612_FREQ_250KHZ = 0, - SY21612_FREQ_500KHZ, - SY21612_FREQ_750KHZ, - SY21612_FREQ_1MHZ -}; - -enum sy21612_vbus_volt { - SY21612_VBUS_5V = 2, - SY21612_VBUS_7V, - SY21612_VBUS_9V, - SY21612_VBUS_12V, - SY21612_VBUS_15V, - SY21612_VBUS_20V, -}; - -enum sy21612_vbus_adj { - SY21612_VBUS_M2_5 = 0, - SY21612_VBUS_M1_25, - SY21612_VBUS_0, - SY21612_VBUS_1_25, - SY21612_VBUS_2_5, - SY21612_VBUS_3_75, - SY21612_VBUS_5, -}; - -#define SY21612_CTRL1 0x00 -#define SY21612_CTRL1_REG_EN BIT(7) -#define SY21612_CTRL1_LOW_BAT_MASK (7 << 4) -#define SY21612_CTRL1_LOW_BAT_10_2V (0 << 4) -#define SY21612_CTRL1_LOW_BAT_10_7V BIT(4) -#define SY21612_CTRL1_LOW_BAT_11_2V (2 << 4) -#define SY21612_CTRL1_LOW_BAT_11_7V (3 << 4) -#define SY21612_CTRL1_LOW_BAT_22_0V (4 << 4) -#define SY21612_CTRL1_LOW_BAT_22_5V (5 << 4) -#define SY21612_CTRL1_LOW_BAT_23_0V (6 << 4) -#define SY21612_CTRL1_LOW_BAT_23_5V (7 << 4) -#define SY21612_CTRL1_ADC_EN BIT(3) -#define SY21612_CTRL1_ADC_AUTO_MODE BIT(2) -#define SY21612_CTRL1_VBUS_NDISCHG BIT(1) - -#define SY21612_CTRL2 0x01 -#define SY21612_CTRL2_FREQ_MASK (3 << 6) -#define SY21612_CTRL2_FREQ_SHIFT 6 -#define SY21612_CTRL2_FREQ_250K (0 << 6) -#define SY21612_CTRL2_FREQ_500K BIT(6) -#define SY21612_CTRL2_FREQ_750K (2 << 6) -#define SY21612_CTRL2_FREQ_1M (3 << 6) -#define SY21612_CTRL2_VBUS_MASK (7 << 3) -#define SY21612_CTRL2_VBUS_SHIFT 3 -#define SY21612_CTRL2_VBUS_5V (2 << 3) -#define SY21612_CTRL2_VBUS_7V (3 << 3) -#define SY21612_CTRL2_VBUS_9V (4 << 3) -#define SY21612_CTRL2_VBUS_12V (5 << 3) -#define SY21612_CTRL2_VBUS_15V (6 << 3) -#define SY21612_CTRL2_VBUS_20V (7 << 3) -#define SY21612_CTRL2_VBUS_ADJ_MASK 7 -#define SY21612_CTRL2_VBUS_ADJ_SHIFT 0 -#define SY21612_CTRL2_VBUS_ADJ_M2_5 0 -#define SY21612_CTRL2_VBUS_ADJ_M1_25 1 -#define SY21612_CTRL2_VBUS_ADJ_0 2 -#define SY21612_CTRL2_VBUS_ADJ_1_25 3 -#define SY21612_CTRL2_VBUS_ADJ_2_5 4 -#define SY21612_CTRL2_VBUS_ADJ_3_75 5 -#define SY21612_CTRL2_VBUS_ADJ_5 6 - -#define SY21612_PROT1 0x02 -#define SY21612_PROT1_I_THRESH_MASK (7 << 5) -#define SY21612_PROT1_I_THRESH_18MV (0 << 5) -#define SY21612_PROT1_I_THRESH_22MV BIT(5) -#define SY21612_PROT1_I_THRESH_27MV (2 << 5) -#define SY21612_PROT1_I_THRESH_31MV (3 << 5) -#define SY21612_PROT1_I_THRESH_36MV (4 << 5) -#define SY21612_PROT1_I_THRESH_45MV (5 << 5) -#define SY21612_PROT1_I_THRESH_54MV (6 << 5) -#define SY21612_PROT1_I_THRESH_64MV (7 << 5) -#define SY21612_PROT1_OVP_THRESH_MASK (3 << 3) -#define SY21612_PROT1_OVP_THRESH_110 (0 << 3) -#define SY21612_PROT1_OVP_THRESH_115 BIT(3) -#define SY21612_PROT1_OVP_THRESH_120 (2 << 3) -#define SY21612_PROT1_OVP_THRESH_125 (3 << 3) -#define SY21612_PROT1_UVP_THRESH_MASK (3 << 1) -#define SY21612_PROT1_UVP_THRESH_50 (0 << 1) -#define SY21612_PROT1_UVP_THRESH_60 BIT(1) -#define SY21612_PROT1_UVP_THRESH_70 (2 << 1) -#define SY21612_PROT1_UVP_THRESH_80 (3 << 1) - -#define SY21612_PROT2 0x03 -#define SY21612_PROT2_I_LIMIT_MASK (3 << 6) -#define SY21612_PROT2_I_LIMIT_6A (0 << 6) -#define SY21612_PROT2_I_LIMIT_8A (2 << 6) -#define SY21612_PROT2_I_LIMIT_10A (3 << 6) -#define SY21612_PROT2_OCP_AUTORECOVER BIT(5) -#define SY21612_PROT2_UVP_AUTORECOVER BIT(4) -#define SY21612_PROT2_OTP_AUTORECOVER BIT(3) -#define SY21612_PROT2_SINK_MODE BIT(2) - -#define SY21612_STATE 0x04 -#define SY21612_STATE_POWER_GOOD BIT(7) -#define SY21612_STATE_VBAT_LT_VBUS BIT(6) -#define SY21612_STATE_VBAT_LOW BIT(5) - -#define SY21612_INT 0x05 -#define SY21612_INT_ADC_READY BIT(7) -#define SY21612_INT_VBUS_OCP BIT(6) -#define SY21612_INT_INDUCTOR_OCP BIT(5) -#define SY21612_INT_UVP BIT(4) -#define SY21612_INT_OTP BIT(3) - -/* Battery voltage range: 0 ~ 25V */ -#define SY21612_VBAT_VOLT 0x06 - -/* VBUS voltage range: 0 ~ 25V */ -#define SY21612_VBUS_VOLT 0x07 - -/* Output current sense voltage range 0 ~ 67mV */ -#define SY21612_VBUS_CURRENT 0x08 - -/* Enable or disable the regulator */ -int sy21612_enable_regulator(int enable); -/* Enable internal adc */ -int sy21612_enable_adc(int enable); -/* Set ADC mode to single or auto */ -int sy21612_set_adc_mode(int auto_mode); -/* Enable VBUS auto discharge when regulator is disabled */ -int sy21612_set_vbus_discharge(int auto_discharge); -/* Set buck-boost switching frequency */ -int sy21612_set_switching_freq(enum sy21612_switching_freq freq); -/* Set VBUS output voltage */ -int sy21612_set_vbus_volt(enum sy21612_vbus_volt volt); -/* Adjust VBUS output voltage */ -int sy21612_set_vbus_adj(enum sy21612_vbus_adj adj); -/* Set bidirection mode */ -int sy21612_set_sink_mode(int sink_mode); -/* Get power good status */ -int sy21612_is_power_good(void); -/* Read and clear interrupt flags */ -int sy21612_read_clear_int(void); -/* Get VBUS voltage in mV */ -int sy21612_get_vbat_voltage(void); -/* Get VBUS voltage in mV */ -int sy21612_get_vbus_voltage(void); -/* Get VBUS current in mA */ -int sy21612_get_vbus_current(void); -/* Interrupt handler */ -void sy21612_int(enum gpio_signal signal); - -#endif /* __CROS_EC_SY21612_H */ |