diff options
Diffstat (limited to 'driver/charger/bq25703.c')
-rw-r--r-- | driver/charger/bq25703.c | 388 |
1 files changed, 0 insertions, 388 deletions
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 */ |