diff options
-rw-r--r-- | board/damu/board.c | 17 | ||||
-rw-r--r-- | board/damu/board.h | 2 | ||||
-rw-r--r-- | board/host/charger.c | 57 | ||||
-rw-r--r-- | board/jacuzzi/board.c | 17 | ||||
-rw-r--r-- | board/jacuzzi/board.h | 2 | ||||
-rw-r--r-- | common/charger.c | 443 | ||||
-rw-r--r-- | driver/charger/bd9995x.c | 396 | ||||
-rw-r--r-- | driver/charger/bd9995x.h | 3 | ||||
-rw-r--r-- | driver/charger/bq24715.c | 101 | ||||
-rw-r--r-- | driver/charger/bq24715.h | 2 | ||||
-rw-r--r-- | driver/charger/bq24773.c | 136 | ||||
-rw-r--r-- | driver/charger/bq24773.h | 26 | ||||
-rw-r--r-- | driver/charger/bq25710.c | 200 | ||||
-rw-r--r-- | driver/charger/bq25710.h | 2 | ||||
-rw-r--r-- | driver/charger/isl923x.c | 272 | ||||
-rw-r--r-- | driver/charger/isl923x.h | 3 | ||||
-rw-r--r-- | driver/charger/isl9241.c | 189 | ||||
-rw-r--r-- | driver/charger/isl9241.h | 3 | ||||
-rw-r--r-- | driver/charger/rt946x.c | 531 | ||||
-rw-r--r-- | driver/charger/rt946x.h | 2 | ||||
-rw-r--r-- | include/charger.h | 158 | ||||
-rw-r--r-- | include/config.h | 9 |
22 files changed, 1738 insertions, 833 deletions
diff --git a/board/damu/board.c b/board/damu/board.c index 546fbda4bf..946f925081 100644 --- a/board/damu/board.c +++ b/board/damu/board.c @@ -123,6 +123,23 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, }; +/* Charger config. Start i2c address at 1, update during runtime */ +struct charger_config_t chg_chips[] = { + { + .i2c_port = 1, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); + +/* Board version depends on ADCs, so init i2c port after ADC */ +static void charger_config_complete(void) +{ + chg_chips[0].i2c_port = board_get_charger_i2c(); +} +DECLARE_HOOK(HOOK_INIT, charger_config_complete, HOOK_PRIO_INIT_ADC + 1); + uint16_t tcpc_get_alert_status(void) { uint16_t status = 0; diff --git a/board/damu/board.h b/board/damu/board.h index fed9012e43..8399a19b81 100644 --- a/board/damu/board.h +++ b/board/damu/board.h @@ -27,6 +27,8 @@ #define CONFIG_CHARGER_PSYS +#define CONFIG_CHARGER_RUNTIME_CONFIG + #define CONFIG_BC12_DETECT_PI3USB9201 #define CONFIG_EXTPOWER_GPIO diff --git a/board/host/charger.c b/board/host/charger.c index 1dd972a82e..d71f1e8994 100644 --- a/board/host/charger.c +++ b/board/host/charger.c @@ -32,13 +32,13 @@ static uint32_t mock_current; static uint32_t mock_voltage; static uint32_t mock_input_current; -const struct charger_info *charger_get_info(void) +static const struct charger_info *mock_get_info(int chgnum) { return &mock_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list mock_get_status(int chgnum, int *status) { *status = CHARGER_LEVEL_2; if (mock_mode & CHARGE_FLAG_INHIBIT_CHARGE) @@ -48,7 +48,7 @@ int charger_get_status(int *status) } -int charger_set_mode(int mode) +static enum ec_error_list mock_set_mode(int chgnum, int mode) { if (mode & CHARGE_FLAG_INHIBIT_CHARGE) mock_mode |= OPTION_CHARGE_INHIBIT; @@ -58,16 +58,16 @@ int charger_set_mode(int mode) } -int charger_get_current(int *current) +static enum ec_error_list mock_get_current(int chgnum, int *current) { *current = mock_current; return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list mock_set_current(int chgnum, int current) { - const struct charger_info *info = charger_get_info(); + const struct charger_info *info = mock_get_info(chgnum); if (current > 0 && current < info->current_min) current = info->current_min; @@ -80,14 +80,14 @@ int charger_set_current(int current) return EC_SUCCESS; } -int charger_get_voltage(int *voltage) +static enum ec_error_list mock_get_voltage(int chgnum, int *voltage) { *voltage = mock_voltage; return EC_SUCCESS; } -int charger_set_voltage(int voltage) +static enum ec_error_list mock_set_voltage(int chgnum, int voltage) { mock_voltage = voltage; ccprintf("Charger set voltage: %d\n", voltage); @@ -95,42 +95,42 @@ int charger_set_voltage(int voltage) } -int charger_get_option(int *option) +static enum ec_error_list mock_get_option(int chgnum, int *option) { *option = mock_option; return EC_SUCCESS; } -int charger_set_option(int option) +static enum ec_error_list mock_set_option(int chgnum, int option) { mock_option = option; return EC_SUCCESS; } -int charger_manufacturer_id(int *id) +static enum ec_error_list mock_manufacturer_id(int chgnum, int *id) { return EC_SUCCESS; } -int charger_device_id(int *id) +static enum ec_error_list mock_device_id(int chgnum, int *id) { return EC_SUCCESS; } -int charger_get_input_current(int *input_current) +static enum ec_error_list mock_get_input_current(int chgnum, int *input_current) { *input_current = mock_input_current; return EC_SUCCESS; } -int charger_set_input_current(int current) +static enum ec_error_list mock_set_input_current(int chgnum, int current) { - const struct charger_info *info = charger_get_info(); + const struct charger_info *info = mock_get_info(chgnum); if (current < info->input_current_min) current = info->input_current_min; @@ -145,8 +145,33 @@ int charger_set_input_current(int current) } -int charger_post_init(void) +static enum ec_error_list mock_post_init(int chgnum) { mock_current = mock_input_current = CONFIG_CHARGER_INPUT_CURRENT; return EC_SUCCESS; } + +const struct charger_drv mock_drv = { + .post_init = &mock_post_init, + .get_info = &mock_get_info, + .get_status = &mock_get_status, + .set_mode = &mock_set_mode, + .get_current = &mock_get_current, + .set_current = &mock_set_current, + .get_voltage = &mock_get_voltage, + .set_voltage = &mock_set_voltage, + .set_input_current = &mock_set_input_current, + .get_input_current = &mock_get_input_current, + .manufacturer_id = &mock_manufacturer_id, + .device_id = &mock_device_id, + .get_option = &mock_get_option, + .set_option = &mock_set_option, +}; + +const struct charger_config_t chg_chips[] = { + { + .drv = &mock_drv, + }, +}; + +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); diff --git a/board/jacuzzi/board.c b/board/jacuzzi/board.c index 799d36ba9c..123a378f6f 100644 --- a/board/jacuzzi/board.c +++ b/board/jacuzzi/board.c @@ -159,6 +159,23 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, }; +/* Charger config. Start i2c address at 1, update during runtime */ +struct charger_config_t chg_chips[] = { + { + .i2c_port = 1, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); + +/* Board version depends on ADCs, so init i2c port after ADC */ +static void charger_config_complete(void) +{ + chg_chips[0].i2c_port = board_get_charger_i2c(); +} +DECLARE_HOOK(HOOK_INIT, charger_config_complete, HOOK_PRIO_INIT_ADC + 1); + uint16_t tcpc_get_alert_status(void) { uint16_t status = 0; diff --git a/board/jacuzzi/board.h b/board/jacuzzi/board.h index 777fd581b9..1f3d9fdfe6 100644 --- a/board/jacuzzi/board.h +++ b/board/jacuzzi/board.h @@ -26,6 +26,8 @@ #define CONFIG_CHARGER_PSYS +#define CONFIG_CHARGER_RUNTIME_CONFIG + #define CONFIG_BC12_DETECT_PI3USB9201 #define CONFIG_EXTPOWER_GPIO diff --git a/common/charger.c b/common/charger.c index 7ee80a9c23..e2f6112ed7 100644 --- a/common/charger.c +++ b/common/charger.c @@ -143,23 +143,20 @@ void print_charger_debug(void) /* charge voltage limit */ print_item_name("V_batt:"); if (check_print_error(charger_get_voltage(&d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, - info->voltage_min, info->voltage_max, - info->voltage_step); + ccprintf("%5d (%4d - %5d, %3d)\n", d, info->voltage_min, + info->voltage_max, info->voltage_step); /* charge current limit */ print_item_name("I_batt:"); if (check_print_error(charger_get_current(&d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, - info->current_min, info->current_max, - info->current_step); + ccprintf("%5d (%4d - %5d, %3d)\n", d, info->current_min, + info->current_max, info->current_step); /* input current limit */ print_item_name("I_in:"); if (check_print_error(charger_get_input_current(&d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, - info->input_current_min, info->input_current_max, - info->input_current_step); + ccprintf("%5d (%4d - %5d, %3d)\n", d, info->input_current_min, + info->input_current_max, info->input_current_step); /* dptf current limit */ print_item_name("I_dptf:"); @@ -209,3 +206,431 @@ static int command_charger(int argc, char **argv) DECLARE_CONSOLE_COMMAND(charger, command_charger, "[input | current | voltage | dptf] [newval]", "Get or set charger param(s)"); + +/* Driver wrapper functions */ + +/* + * TODO(b/147672225): boards should define their own charger structures + * Drivers cannot be included together, as they define some of the same items. + * This will need to be addressed if we want to support different types of + * charger chips on a board + */ +#if defined(CONFIG_CHARGER_BD9995X) +#include "driver/charger/bd9995x.h" +#elif defined(CONFIG_CHARGER_BQ24715) +#include "driver/charger/bq24715.h" +#elif defined(CONFIG_CHARGER_BQ24770) || defined(CONFIG_CHARGER_BQ24773) +#include "driver/charger/bq24773.h" +#elif defined(CONFIG_CHARGER_BQ25710) +#include "driver/charger/bq25710.h" +#elif defined(CONFIG_CHARGER_ISL9237) || defined(CONFIG_CHARGER_ISL9238) +#include "driver/charger/isl923x.h" +#elif defined(CONFIG_CHARGER_ISL9241) +#include "driver/charger/isl9241.h" +#elif defined(CONFIG_CHARGER_MT6370) || defined(CONFIG_CHARGER_RT9466) \ + || defined(CONFIG_CHARGER_RT9467) +#include "driver/charger/rt946x.h" +#endif + +#if !defined(CONFIG_CHARGER_RUNTIME_CONFIG) && !defined(TEST_BUILD) +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, +#if defined(CONFIG_CHARGER_BD9995X) + .i2c_addr_flags = BD9995X_ADDR_FLAGS, + .drv = &bd9995x_drv, +#elif defined(CONFIG_CHARGER_BQ24715) + .i2c_addr_flags = CHARGER_ADDR_FLAGS, + .drv = &bq24715_drv, +#elif defined(CONFIG_CHARGER_BQ24770) || defined(CONFIG_CHARGER_BQ24773) + .i2c_addr_flags = I2C_ADDR_CHARGER_FLAGS, + .drv = &bq2477x_drv, +#elif defined(CONFIG_CHARGER_BQ25710) + .i2c_addr_flags = BQ25710_SMBUS_ADDR1_FLAGS, + .drv = &bq25710_drv, +#elif defined(CONFIG_CHARGER_ISL9237) || defined(CONFIG_CHARGER_ISL9238) + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, +#elif defined(CONFIG_CHARGER_ISL9241) + .i2c_addr_flags = ISL9241_ADDR_FLAGS, + .drv = &isl9241_drv, +#elif defined(CONFIG_CHARGER_MT6370) || defined(CONFIG_CHARGER_RT9466) \ + || defined(CONFIG_CHARGER_RT9467) + .i2c_addr_flags = RT946X_ADDR_FLAGS, + .drv = &rt946x_drv, +#endif + }, +}; + +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); +#endif /* CONFIG_CHARGER_RUNTIME_CONFIG */ + + +static void charger_chips_init(void) +{ + int chip; + + for (chip = 0; chip < chg_cnt; chip++) { + if (chg_chips[chip].drv->init) + chg_chips[chip].drv->init(chip); + } +} +DECLARE_HOOK(HOOK_INIT, charger_chips_init, HOOK_PRIO_INIT_I2C + 1); + +enum ec_error_list charger_post_init(void) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->post_init) + rv = chg_chips[chgnum].drv->post_init(chgnum); + + return rv; +} + +const struct charger_info *charger_get_info(void) +{ + int chgnum = 0; + const struct charger_info *ret = NULL; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return NULL; + } + + if (chg_chips[chgnum].drv->get_info) + ret = chg_chips[chgnum].drv->get_info(chgnum); + + return ret; +} + +enum ec_error_list charger_get_status(int *status) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->get_status) + rv = chg_chips[chgnum].drv->get_status(chgnum, status); + + return rv; +} + +enum ec_error_list charger_set_mode(int mode) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_mode) + rv = chg_chips[chgnum].drv->set_mode(chgnum, mode); + + return rv; +} + +enum ec_error_list charger_enable_otg_power(int enabled) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->enable_otg_power) + rv = chg_chips[chgnum].drv->enable_otg_power(chgnum, enabled); + + return rv; +} + +enum ec_error_list charger_set_otg_current_voltage(int output_current, + int output_voltage) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_otg_current_voltage) + rv = chg_chips[chgnum].drv->set_otg_current_voltage(chgnum, + output_current, output_voltage); + + return rv; +} + +enum ec_error_list charger_get_current(int *current) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->get_current) + rv = chg_chips[chgnum].drv->get_current(chgnum, current); + + return rv; +} + +enum ec_error_list charger_set_current(int current) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_current) + rv = chg_chips[chgnum].drv->set_current(chgnum, current); + + return rv; +} + +enum ec_error_list charger_get_voltage(int *voltage) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->get_voltage) + rv = chg_chips[chgnum].drv->get_voltage(chgnum, voltage); + + return rv; +} + +enum ec_error_list charger_set_voltage(int voltage) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_voltage) + rv = chg_chips[chgnum].drv->set_voltage(chgnum, voltage); + + return rv; +} + +enum ec_error_list charger_discharge_on_ac(int enable) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->discharge_on_ac) + rv = chg_chips[chgnum].drv->discharge_on_ac(chgnum, enable); + + return rv; +} + +int charger_get_vbus_voltage(int port) +{ + int chgnum = 0; + int rv = 0; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return 0; + } + + if (chg_chips[chgnum].drv->get_vbus_voltage) + rv = chg_chips[chgnum].drv->get_vbus_voltage(chgnum, port); + + return rv; +} + +enum ec_error_list charger_set_input_current(int input_current) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_input_current) + rv = chg_chips[chgnum].drv->set_input_current(chgnum, + input_current); + + return rv; +} + +enum ec_error_list charger_get_input_current(int *input_current) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->get_input_current) + rv = chg_chips[chgnum].drv->get_input_current(chgnum, + input_current); + + return rv; +} + +enum ec_error_list charger_manufacturer_id(int *id) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->manufacturer_id) + rv = chg_chips[chgnum].drv->manufacturer_id(chgnum, id); + + return rv; +} + +enum ec_error_list charger_device_id(int *id) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->device_id) + rv = chg_chips[chgnum].drv->device_id(chgnum, id); + + return rv; +} + +enum ec_error_list charger_get_option(int *option) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->get_option) + rv = chg_chips[chgnum].drv->get_option(chgnum, option); + + return rv; +} + +enum ec_error_list charger_set_option(int option) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_option) + rv = chg_chips[chgnum].drv->set_option(chgnum, option); + + return rv; +} + +enum ec_error_list charger_set_hw_ramp(int enable) +{ + int chgnum = 0; + int rv = EC_ERROR_UNIMPLEMENTED; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return EC_ERROR_INVAL; + } + + if (chg_chips[chgnum].drv->set_hw_ramp) + rv = chg_chips[chgnum].drv->set_hw_ramp(chgnum, enable); + + return rv; +} + +#ifdef CONFIG_CHARGE_RAMP_HW +int chg_ramp_is_stable(void) +{ + int chgnum = 0; + int rv = 0; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return 0; + } + + if (chg_chips[chgnum].drv->ramp_is_stable) + rv = chg_chips[chgnum].drv->ramp_is_stable(chgnum); + + return rv; +} + +int chg_ramp_is_detected(void) +{ + int chgnum = 0; + int rv = 0; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return 0; + } + + if (chg_chips[chgnum].drv->ramp_is_detected) + rv = chg_chips[chgnum].drv->ramp_is_detected(chgnum); + + return rv; +} + +int chg_ramp_get_current_limit(void) +{ + int chgnum = 0; + int rv = 0; + + if ((chgnum < 0) || (chgnum >= chg_cnt)) { + CPRINTS("%s(%d) Invalid charger!", __func__, chgnum); + return 0; + } + + if (chg_chips[chgnum].drv->ramp_get_current_limit) + rv = chg_chips[chgnum].drv->ramp_get_current_limit(chgnum); + + return rv; +} +#endif diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c index 23303589b6..9c78ba7709 100644 --- a/driver/charger/bd9995x.c +++ b/driver/charger/bd9995x.c @@ -98,6 +98,9 @@ static enum usb_switch usb_switch_state[BD9995X_CHARGE_PORT_COUNT] = { USB_SWITCH_DISCONNECT, }; +static enum ec_error_list bd9995x_set_current(int chgnum, int current); +static enum ec_error_list bd9995x_set_voltage(int chgnum, int voltage); + static int bd9995x_get_bc12_ilim(int charge_supplier) { switch (charge_supplier) { @@ -123,15 +126,16 @@ static int bd9995x_get_bc12_ilim(int charge_supplier) } #endif /* HAS_TASK_USB_CHG */ -static inline int ch_raw_read16(int cmd, int *param, - enum bd9995x_command map_cmd) +static inline enum ec_error_list ch_raw_read16(int chgnum, 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, + rv = i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, BD9995X_CMD_MAP_SET, map_cmd); if (rv) { charger_map_cmd = BD9995X_INVALID_COMMAND; @@ -141,7 +145,8 @@ static inline int ch_raw_read16(int cmd, int *param, charger_map_cmd = map_cmd; } - rv = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + rv = i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, cmd, param); bd9995x_read_cleanup: @@ -150,15 +155,16 @@ bd9995x_read_cleanup: return rv; } -static inline int ch_raw_write16(int cmd, int param, - enum bd9995x_command map_cmd) +static inline enum ec_error_list ch_raw_write16(int chgnum, 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, + rv = i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, BD9995X_CMD_MAP_SET, map_cmd); if (rv) { charger_map_cmd = BD9995X_INVALID_COMMAND; @@ -168,7 +174,8 @@ static inline int ch_raw_write16(int cmd, int param, charger_map_cmd = map_cmd; } - rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + rv = i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, cmd, param); bd9995x_write_cleanup: @@ -179,13 +186,13 @@ bd9995x_write_cleanup: /* BD9995X local interfaces */ -static int bd9995x_set_vfastchg(int voltage) +static int bd9995x_set_vfastchg(int chgnum, int voltage) { int rv; /* Fast Charge Voltage Regulation Settings for fast charging. */ - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET1, + rv = ch_raw_write16(chgnum, BD9995X_CMD_VFASTCHG_REG_SET1, voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -195,39 +202,39 @@ static int bd9995x_set_vfastchg(int voltage) * If TSENSE is not connected set all the VFASTCHG_REG_SETx * to same voltage. */ - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET2, + rv = ch_raw_write16(chgnum, BD9995X_CMD_VFASTCHG_REG_SET2, voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); if (rv) return rv; - rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET3, + rv = ch_raw_write16(chgnum, BD9995X_CMD_VFASTCHG_REG_SET3, voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); #endif return rv; } -static int bd9995x_set_vsysreg(int voltage) +static int bd9995x_set_vsysreg(int chgnum, int voltage) { /* VSYS Regulation voltage is in 64mV steps. */ voltage &= ~0x3F; - return ch_raw_write16(BD9995X_CMD_VSYSREG_SET, voltage, + return ch_raw_write16(chgnum, BD9995X_CMD_VSYSREG_SET, voltage, BD9995X_EXTENDED_COMMAND); } -static int bd9995x_is_discharging_on_ac(void) +static int bd9995x_is_discharging_on_ac(int chgnum) { int reg; - if (ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + if (ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND)) return 0; return !!(reg & BD9995X_CMD_CHGOP_SET2_BATT_LEARN); } -static int bd9995x_charger_enable(int enable) +static int bd9995x_charger_enable(int chgnum, int enable) { int rv, reg; static int prev_chg_enable = -1; @@ -261,13 +268,13 @@ static int bd9995x_charger_enable(int enable) * Set VSYSREG_SET <= VBAT so that the charger is in Fast-Charge * state when charging. */ - rv = bd9995x_set_vsysreg(bi->voltage_min); + rv = bd9995x_set_vsysreg(chgnum, 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 + + rv = bd9995x_set_vsysreg(chgnum, bi->voltage_max + BD9995X_VSYS_PRECHARGE_OFFSET_MV); /* @@ -280,7 +287,7 @@ static int bd9995x_charger_enable(int enable) if (rv) return rv; - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -290,17 +297,17 @@ static int bd9995x_charger_enable(int enable) else reg &= ~BD9995X_CMD_CHGOP_SET2_CHG_EN; - return ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, + return ch_raw_write16(chgnum, BD9995X_CMD_CHGOP_SET2, reg, BD9995X_EXTENDED_COMMAND); } -static int bd9995x_por_reset(void) +static int bd9995x_por_reset(int chgnum) { int rv; int reg; int i; - rv = ch_raw_write16(BD9995X_CMD_SYSTEM_CTRL_SET, + rv = ch_raw_write16(chgnum, BD9995X_CMD_SYSTEM_CTRL_SET, BD9995X_CMD_SYSTEM_CTRL_SET_OTPLD | BD9995X_CMD_SYSTEM_CTRL_SET_ALLRST, BD9995X_EXTENDED_COMMAND); @@ -310,7 +317,7 @@ static int bd9995x_por_reset(void) /* 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, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_SYSTEM_STATUS, ®, BD9995X_EXTENDED_COMMAND); if (!rv && (reg & BD9995X_CMD_SYSTEM_STATUS_OTPLD_STATE) && @@ -323,38 +330,38 @@ static int bd9995x_por_reset(void) if (i == OTPROM_LOAD_WAIT_RETRY) return EC_ERROR_TIMEOUT; - return ch_raw_write16(BD9995X_CMD_SYSTEM_CTRL_SET, 0, + return ch_raw_write16(chgnum, BD9995X_CMD_SYSTEM_CTRL_SET, 0, BD9995X_EXTENDED_COMMAND); } -static int bd9995x_reset_to_zero(void) +static int bd9995x_reset_to_zero(int chgnum) { int rv; - rv = charger_set_current(0); + rv = bd9995x_set_current(chgnum, 0); if (rv) return rv; - return charger_set_voltage(0); + return bd9995x_set_voltage(chgnum, 0); } -static int bd9995x_get_charger_op_status(int *status) +static int bd9995x_get_charger_op_status(int chgnum, int *status) { - return ch_raw_read16(BD9995X_CMD_CHGOP_STATUS, status, + return ch_raw_read16(chgnum, 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. */ +/* Mutex for UCD_SET registers, lock before read / mask / write. */ static struct mutex ucd_set_mutex[BD9995X_CHARGE_PORT_COUNT]; -static int bd9995x_get_bc12_device_type(int port) +static int bd9995x_get_bc12_device_type(int chgnum, int port) { int rv; int reg; - rv = ch_raw_read16((port == BD9995X_CHARGE_PORT_VBUS) ? + rv = ch_raw_read16(chgnum, (port == BD9995X_CHARGE_PORT_VBUS) ? BD9995X_CMD_VBUS_UCD_STATUS : BD9995X_CMD_VCC_UCD_STATUS, ®, BD9995X_EXTENDED_COMMAND); @@ -384,7 +391,8 @@ static int bd9995x_get_bc12_device_type(int port) * (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) +static int bd9995x_update_ucd_set_reg(int chgnum, int port, uint16_t mask, + int set) { int rv; int reg; @@ -392,21 +400,22 @@ static int bd9995x_update_ucd_set_reg(int port, uint16_t mask, int set) 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); + rv = ch_raw_read16(chgnum, port_reg, ®, BD9995X_EXTENDED_COMMAND); if (!rv) { if (set) reg |= mask; else reg &= ~mask; - rv = ch_raw_write16(port_reg, reg, BD9995X_EXTENDED_COMMAND); + rv = ch_raw_write16(chgnum, port_reg, reg, + BD9995X_EXTENDED_COMMAND); } mutex_unlock(&ucd_set_mutex[port]); return rv; } -static int bd9995x_bc12_check_type(int port) +static int bd9995x_bc12_check_type(int chgnum, int port) { int bc12_type; struct charge_port_info charge; @@ -421,7 +430,7 @@ static int bd9995x_bc12_check_type(int port) return 0; /* get device type */ - bc12_type = bd9995x_get_bc12_device_type(port); + bc12_type = bd9995x_get_bc12_device_type(chgnum, port); if (bc12_type == CHARGE_SUPPLIER_NONE) /* * Device type is not available, return non-zero so new wait @@ -438,7 +447,7 @@ static int bd9995x_bc12_check_type(int port) return 0; } -static void bd9995x_bc12_detach(int port, int type) +static void bd9995x_bc12_detach(int chgnum, int port, int type) { /* Update charge manager */ charge_manager_update_charge(type, port, NULL); @@ -447,7 +456,8 @@ static void bd9995x_bc12_detach(int port, int type) bd9995x_bc12_enable_charging(port, 0); } -static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) +static int bd9995x_enable_vbus_detect_interrupts(int chgnum, int port, + int enable) { int reg; int rv; @@ -455,7 +465,7 @@ static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) int mask_val; /* 1st Level Interrupt Setting */ - rv = ch_raw_read16(BD9995X_CMD_INT0_SET, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_INT0_SET, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -469,7 +479,7 @@ static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) else reg &= ~mask_val; - rv = ch_raw_write16(BD9995X_CMD_INT0_SET, reg, + rv = ch_raw_write16(chgnum, BD9995X_CMD_INT0_SET, reg, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -477,7 +487,7 @@ static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) /* 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); + rv = ch_raw_read16(chgnum, port_reg, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -492,11 +502,11 @@ static int bd9995x_enable_vbus_detect_interrupts(int port, int enable) else reg &= ~mask_val; - return ch_raw_write16(port_reg, reg, BD9995X_EXTENDED_COMMAND); + return ch_raw_write16(chgnum, port_reg, reg, BD9995X_EXTENDED_COMMAND); } /* Read + clear active interrupt bits for a given port */ -static int bd9995x_get_interrupts(int port) +static int bd9995x_get_interrupts(int chgnum, int port) { int rv; int reg; @@ -505,13 +515,13 @@ static int bd9995x_get_interrupts(int port) port_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? BD9995X_CMD_INT1_STATUS : BD9995X_CMD_INT2_STATUS; - rv = ch_raw_read16(port_reg, ®, BD9995X_EXTENDED_COMMAND); + rv = ch_raw_read16(chgnum, 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); + ch_raw_write16(chgnum, port_reg, reg, BD9995X_EXTENDED_COMMAND); return reg; } @@ -521,16 +531,16 @@ static int bd9995x_get_interrupts(int port) * 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) +static int bd9995x_bc12_detect(int chgnum, int port, int enable) { - return bd9995x_update_ucd_set_reg(port, + return bd9995x_update_ucd_set_reg(chgnum, 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) +static int usb_charger_process(int chgnum, int port) { int vbus_provided = bd9995x_is_vbus_provided(port) && !usb_charger_port_is_sourcing_vbus(port); @@ -543,7 +553,7 @@ static int usb_charger_process(int port) * to speak PD. */ if (vbus_provided && !pd_capable(port)) { - bd9995x_bc12_detect(port, 1); + bd9995x_bc12_detect(chgnum, port, 1); /* * Need to give the charger time (~312 mSec) before the * bc12_type is available. The main task loop will schedule a @@ -553,7 +563,7 @@ static int usb_charger_process(int port) } /* Reset BC1.2 regs so we don't do auto-detection. */ - bd9995x_bc12_detect(port, 0); + bd9995x_bc12_detect(chgnum, port, 0); /* * VBUS is no longer being provided, if the bc12_type had been @@ -561,7 +571,7 @@ static int usb_charger_process(int port) */ if (bc12_detected_type[port] != CHARGE_SUPPLIER_NONE) { /* Charger/sink detached */ - bd9995x_bc12_detach(port, bc12_detected_type[port]); + bd9995x_bc12_detach(chgnum, port, bc12_detected_type[port]); bc12_detected_type[port] = CHARGE_SUPPLIER_NONE; } /* No need for the task to schedule a wait event */ @@ -586,7 +596,8 @@ int usb_charger_ramp_max(int supplier, int sup_curr) /* chip specific interfaces */ -int charger_set_input_current(int input_current) +static enum ec_error_list bd9995x_set_input_current(int chgnum, + int input_current) { int rv; @@ -596,42 +607,44 @@ int charger_set_input_current(int input_current) 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, + rv = ch_raw_write16(chgnum, 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, + return ch_raw_write16(chgnum, BD9995X_CMD_ICC_LIM_SET, input_current, BD9995X_BAT_CHG_COMMAND); } -int charger_get_input_current(int *input_current) +static enum ec_error_list bd9995x_get_input_current(int chgnum, + int *input_current) { - return ch_raw_read16(BD9995X_CMD_CUR_ILIM_VAL, input_current, + return ch_raw_read16(chgnum, BD9995X_CMD_CUR_ILIM_VAL, input_current, BD9995X_EXTENDED_COMMAND); } -int charger_manufacturer_id(int *id) +static enum ec_error_list bd9995x_manufacturer_id(int chgnum, int *id) { return EC_ERROR_UNIMPLEMENTED; } -int charger_device_id(int *id) +static enum ec_error_list bd9995x_device_id(int chgnum, int *id) { - return ch_raw_read16(BD9995X_CMD_CHIP_ID, id, BD9995X_EXTENDED_COMMAND); + return ch_raw_read16(chgnum, BD9995X_CMD_CHIP_ID, id, + BD9995X_EXTENDED_COMMAND); } -int charger_get_option(int *option) +static enum ec_error_list bd9995x_get_option(int chgnum, int *option) { int rv; int reg; - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET1, option, + rv = ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET1, option, BD9995X_EXTENDED_COMMAND); if (rv) return rv; - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -641,27 +654,28 @@ int charger_get_option(int *option) return EC_SUCCESS; } -int charger_set_option(int option) +static enum ec_error_list bd9995x_set_option(int chgnum, int option) { int rv; - rv = ch_raw_write16(BD9995X_CMD_CHGOP_SET1, option & 0xFFFF, + rv = ch_raw_write16(chgnum, 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); + return ch_raw_write16(chgnum, BD9995X_CMD_CHGOP_SET2, + (option >> 16) & 0xFFFF, + BD9995X_EXTENDED_COMMAND); } /* Charger interfaces */ -const struct charger_info *charger_get_info(void) +static const struct charger_info *bd9995x_get_info(int chgnum) { return &bd9995x_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list bd9995x_get_status(int chgnum, int *status) { int rv; int reg; @@ -671,7 +685,7 @@ int charger_get_status(int *status) *status = CHARGER_LEVEL_2; /* charger enable/inhibit */ - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -680,7 +694,7 @@ int charger_get_status(int *status) *status |= CHARGER_CHARGE_INHIBITED; /* charger alarm enable/inhibit */ - rv = ch_raw_read16(BD9995X_CMD_PROCHOT_CTRL_SET, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_PROCHOT_CTRL_SET, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -692,7 +706,7 @@ int charger_get_status(int *status) BD9995X_CMD_PROCHOT_CTRL_SET_PROCHOT_EN0))) *status |= CHARGER_ALARM_INHIBITED; - rv = bd9995x_get_charger_op_status(®); + rv = bd9995x_get_charger_op_status(chgnum, ®); if (rv) return rv; @@ -734,18 +748,18 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list bd9995x_set_mode(int chgnum, int mode) { int rv; if (mode & CHARGE_FLAG_POR_RESET) { - rv = bd9995x_por_reset(); + rv = bd9995x_por_reset(chgnum); if (rv) return rv; } if (mode & CHARGE_FLAG_RESET_TO_ZERO) { - rv = bd9995x_reset_to_zero(); + rv = bd9995x_reset_to_zero(chgnum); if (rv) return rv; } @@ -753,13 +767,13 @@ int charger_set_mode(int mode) return EC_SUCCESS; } -int charger_get_current(int *current) +static enum ec_error_list bd9995x_get_current(int chgnum, int *current) { - return ch_raw_read16(BD9995X_CMD_CHG_CURRENT, current, + return ch_raw_read16(chgnum, BD9995X_CMD_CHG_CURRENT, current, BD9995X_BAT_CHG_COMMAND); } -int charger_set_current(int current) +static enum ec_error_list bd9995x_set_current(int chgnum, int current) { int rv; int chg_enable = 1; @@ -778,20 +792,20 @@ int charger_set_current(int current) * 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()) { + if (!current || bd9995x_is_discharging_on_ac(chgnum)) { chg_enable = 0; - rv = bd9995x_charger_enable(0); + rv = bd9995x_charger_enable(chgnum, 0); if (rv) return rv; } - rv = ch_raw_write16(BD9995X_CMD_IPRECH_SET, + rv = ch_raw_write16(chgnum, 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, + rv = ch_raw_write16(chgnum, BD9995X_CMD_CHG_CURRENT, current, BD9995X_BAT_CHG_COMMAND); if (rv) return rv; @@ -800,10 +814,10 @@ int charger_set_current(int current) * Enable charger if charge current is non-zero or not discharging * on AC. */ - return chg_enable ? bd9995x_charger_enable(1) : EC_SUCCESS; + return chg_enable ? bd9995x_charger_enable(chgnum, 1) : EC_SUCCESS; } -int charger_get_voltage(int *voltage) +static enum ec_error_list bd9995x_get_voltage(int chgnum, int *voltage) { if (vsys_priority) { int batt_volt_measured; @@ -820,10 +834,11 @@ int charger_get_voltage(int *voltage) * is always active. */ mutex_lock(&bd9995x_vin_mutex); - if (!ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, ®, - BD9995X_EXTENDED_COMMAND)) { + if (!ch_raw_read16(chgnum, 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, + rv = ch_raw_write16(chgnum, + BD9995X_CMD_VIN_CTRL_SET, reg, BD9995X_EXTENDED_COMMAND); @@ -835,11 +850,11 @@ int charger_get_voltage(int *voltage) } } - return ch_raw_read16(BD9995X_CMD_CHG_VOLTAGE, voltage, + return ch_raw_read16(chgnum, BD9995X_CMD_CHG_VOLTAGE, voltage, BD9995X_BAT_CHG_COMMAND); } -int charger_set_voltage(int voltage) +static enum ec_error_list bd9995x_set_voltage(int chgnum, int voltage) { const int battery_voltage_max = battery_get_info()->voltage_max; @@ -848,7 +863,7 @@ int charger_set_voltage(int voltage) * is not present or the battery is discharging on AC. */ if (voltage == 0 || - bd9995x_is_discharging_on_ac() || + bd9995x_is_discharging_on_ac(chgnum) || battery_is_present() != BP_YES || battery_is_cut_off() || voltage > battery_voltage_max) @@ -861,52 +876,57 @@ int charger_set_voltage(int voltage) if (voltage < bd9995x_charger_info.voltage_min) voltage = bd9995x_charger_info.voltage_min; - return bd9995x_set_vfastchg(voltage); + return bd9995x_set_vfastchg(chgnum, voltage); } -static void bd9995x_battery_charging_profile_settings(void) +static void bd9995x_battery_charging_profile_settings(int chgnum) { const struct battery_info *bi = battery_get_info(); /* Input Current Limit Setting */ - charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); + bd9995x_set_input_current(chgnum, CONFIG_CHARGER_INPUT_CURRENT); /* Charge Termination Current Setting */ - ch_raw_write16(BD9995X_CMD_ITERM_SET, 0, BD9995X_EXTENDED_COMMAND); + ch_raw_write16(chgnum, BD9995X_CMD_ITERM_SET, 0, + BD9995X_EXTENDED_COMMAND); /* Trickle-charge Current Setting */ - ch_raw_write16(BD9995X_CMD_ITRICH_SET, + ch_raw_write16(chgnum, BD9995X_CMD_ITRICH_SET, bi->precharge_current & 0x07C0, BD9995X_EXTENDED_COMMAND); - bd9995x_set_vfastchg(bi->voltage_max); + bd9995x_set_vfastchg(chgnum, bi->voltage_max); /* Set Pre-charge Voltage Threshold for trickle charging. */ - ch_raw_write16(BD9995X_CMD_VPRECHG_TH_SET, + ch_raw_write16(chgnum, 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, + ch_raw_write16(chgnum, 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, + ch_raw_write16(chgnum, 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, + ch_raw_write16(chgnum, BD9995X_CMD_VRBOOST_SET, 0, BD9995X_EXTENDED_COMMAND); /* Disable fast/pre-charging watchdog */ - ch_raw_write16(BD9995X_CMD_CHGWDT_SET, 0, + ch_raw_write16(chgnum, BD9995X_CMD_CHGWDT_SET, 0, BD9995X_EXTENDED_COMMAND); /* TODO(crosbug.com/p/55626): Set VSYSVAL_THH/THL appropriately */ } +/* + * Note: opting not to use charger driver init here due to the different + * priority (other drivers use HOOK_PRIO_INIT_I2C + 1) + */ static void bd9995x_init(void) { int reg; @@ -915,7 +935,7 @@ static void bd9995x_init(void) * Disable charging trigger by BC1.2 on VCC & VBUS and * automatic limitation of the input current. */ - if (ch_raw_read16(BD9995X_CMD_CHGOP_SET1, ®, + if (ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_CHGOP_SET1, ®, BD9995X_EXTENDED_COMMAND)) return; reg |= (BD9995X_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN | @@ -925,7 +945,7 @@ static void bd9995x_init(void) 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, + ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_CHGOP_SET1, reg, BD9995X_EXTENDED_COMMAND); /* @@ -934,11 +954,11 @@ static void bd9995x_init(void) * 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_set_vsysreg(CHARGER_SOLO, 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, ®, + if (ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND)) return; reg &= ~(BD9995X_CMD_CHGOP_SET2_USB_SUS | @@ -947,18 +967,19 @@ static void bd9995x_init(void) #ifdef CONFIG_CHARGER_BD9995X_CHGEN reg |= BD9995X_CMD_CHGOP_SET2_CHG_EN; #endif - ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, + ch_raw_write16(CHARGER_SOLO, 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, ®, + if (ch_raw_read16(CHARGER_SOLO, 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); + ch_raw_write16(CHARGER_SOLO, 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 @@ -968,17 +989,17 @@ static void bd9995x_init(void) * 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, ®, + if (ch_raw_read16(CHARGER_SOLO, 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, + ch_raw_write16(CHARGER_SOLO, 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(); + bd9995x_battery_charging_profile_settings(CHARGER_SOLO); /* Power save mode when VBUS/VCC is removed. */ #ifdef CONFIG_BD9995X_POWER_SAVE_MODE @@ -989,36 +1010,38 @@ static void bd9995x_init(void) #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); + ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_VBUS_TH_SET, + BD9995X_VBUS_DISCHARGE_TH, BD9995X_EXTENDED_COMMAND); + ch_raw_write16(CHARGER_SOLO, 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); + ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_PROTECT_SET, 0x3c, + BD9995X_EXTENDED_COMMAND); /* Undocumented - reverse current threshold = -50mV */ - ch_raw_write16(0x14, 0x0202, BD9995X_DEBUG_COMMAND); + ch_raw_write16(CHARGER_SOLO, 0x14, 0x0202, BD9995X_DEBUG_COMMAND); /* Undocumented - internal gain = 2x */ - ch_raw_write16(0x1a, 0x80, BD9995X_DEBUG_COMMAND); + ch_raw_write16(CHARGER_SOLO, 0x1a, 0x80, BD9995X_DEBUG_COMMAND); /* Re-lock debug regs */ - ch_raw_write16(BD9995X_CMD_PROTECT_SET, 0x0, BD9995X_EXTENDED_COMMAND); + ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_PROTECT_SET, 0x0, + BD9995X_EXTENDED_COMMAND); } DECLARE_HOOK(HOOK_INIT, bd9995x_init, HOOK_PRIO_INIT_EXTPOWER); -int charger_post_init(void) +static enum ec_error_list bd9995x_post_init(int chgnum) { return EC_SUCCESS; } -int charger_discharge_on_ac(int enable) +static enum ec_error_list bd9995x_discharge_on_ac(int chgnum, int enable) { int rv; int reg; - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -1036,11 +1059,11 @@ int charger_discharge_on_ac(int enable) reg &= ~(BD9995X_CMD_CHGOP_SET2_BATT_LEARN | BD9995X_CMD_CHGOP_SET2_USB_SUS); - return ch_raw_write16(BD9995X_CMD_CHGOP_SET2, reg, + return ch_raw_write16(chgnum, BD9995X_CMD_CHGOP_SET2, reg, BD9995X_EXTENDED_COMMAND); } -int charger_get_vbus_voltage(int port) +static int bd9995x_get_vbus_voltage(int chgnum, int port) { uint8_t read_reg; int voltage; @@ -1048,8 +1071,8 @@ int charger_get_vbus_voltage(int port) 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; + return ch_raw_read16(chgnum, read_reg, &voltage, + BD9995X_EXTENDED_COMMAND) ? 0 : voltage; } /*** Non-standard interface functions ***/ @@ -1058,7 +1081,7 @@ int bd9995x_is_vbus_provided(enum bd9995x_charge_port port) { int reg; - if (ch_raw_read16(BD9995X_CMD_VBUS_VCC_STATUS, ®, + if (ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_VBUS_VCC_STATUS, ®, BD9995X_EXTENDED_COMMAND)) return 0; @@ -1078,7 +1101,7 @@ int bd9995x_is_vbus_provided(enum bd9995x_charge_port port) #ifdef CONFIG_BD9995X_DELAY_INPUT_PORT_SELECT static int bd9995x_select_input_port_private(enum bd9995x_charge_port port, - int select) + int select) #else int bd9995x_select_input_port(enum bd9995x_charge_port port, int select) #endif @@ -1087,7 +1110,7 @@ int bd9995x_select_input_port(enum bd9995x_charge_port port, int select) int reg; mutex_lock(&bd9995x_vin_mutex); - rv = ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, ®, + rv = ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_VIN_CTRL_SET, ®, BD9995X_EXTENDED_COMMAND); if (rv) goto select_input_port_exit; @@ -1119,7 +1142,7 @@ int bd9995x_select_input_port(enum bd9995x_charge_port port, int select) panic("Invalid charge port"); } - rv = ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg, + rv = ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_VIN_CTRL_SET, reg, BD9995X_EXTENDED_COMMAND); select_input_port_exit: mutex_unlock(&bd9995x_vin_mutex); @@ -1146,14 +1169,14 @@ static inline int bd9995x_vbus_test(int value, int limit) return ((value > lo_value) && (value < hi_value)); } -static int bd9995x_vbus_debounce(enum bd9995x_charge_port port) +static int bd9995x_vbus_debounce(int chgnum, 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)) + if (ch_raw_read16(chgnum, vbus_reg, &voltage, BD9995X_EXTENDED_COMMAND)) voltage = 0; if (!bd9995x_vbus_test(voltage, vbus_voltage)) { @@ -1174,7 +1197,7 @@ int bd9995x_get_battery_temp(int *temp_ptr) { int rv; - rv = ch_raw_read16(BD9995X_CMD_THERM_VAL, temp_ptr, + rv = ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_THERM_VAL, temp_ptr, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -1187,14 +1210,15 @@ int bd9995x_get_battery_temp(int *temp_ptr) void bd9995x_set_power_save_mode(int mode) { - ch_raw_write16(BD9995X_CMD_SMBREG, mode, BD9995X_EXTENDED_COMMAND); + ch_raw_write16(CHARGER_SOLO, 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, + rv = ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_VBAT_VAL, &vbat_val, BD9995X_EXTENDED_COMMAND); return rv ? 0 : vbat_val; @@ -1212,7 +1236,7 @@ int bd9995x_bc12_enable_charging(int port, int enable) * detection and disable SDP_CHG_TRIG, SDP_CHG_TRIG_EN. Vice versa * for USB-C. */ - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET1, ®, + rv = ch_raw_read16(CHARGER_SOLO, BD9995X_CMD_CHGOP_SET1, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -1228,7 +1252,7 @@ int bd9995x_bc12_enable_charging(int port, int enable) else reg |= mask_val; - return ch_raw_write16(BD9995X_CMD_CHGOP_SET1, reg, + return ch_raw_write16(CHARGER_SOLO, BD9995X_CMD_CHGOP_SET1, reg, BD9995X_EXTENDED_COMMAND); } @@ -1249,8 +1273,9 @@ void usb_charger_set_switches(int port, enum usb_switch setting) ? 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); + bd9995x_update_ucd_set_reg(CHARGER_SOLO, port, + BD9995X_CMD_UCD_SET_USB_SW, + usb_switch_state[port] == USB_SWITCH_CONNECT); } void bd9995x_vbus_interrupt(enum gpio_signal signal) @@ -1275,7 +1300,7 @@ void usb_charger_task(void *u) 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); + bd9995x_enable_vbus_detect_interrupts(CHARGER_SOLO, port, 1); bc12_det_mark[port] = 0; } @@ -1284,7 +1309,7 @@ void usb_charger_task(void *u) changed = 0; for (port = 0; port < board_get_usb_pd_port_count(); port++) { /* Get port interrupts */ - interrupts = bd9995x_get_interrupts(port); + interrupts = bd9995x_get_interrupts(CHARGER_SOLO, port); if (interrupts & BD9995X_CMD_INT_VBUS_DET || !initialized) { /* @@ -1293,7 +1318,8 @@ void usb_charger_task(void *u) * bc12_type to be available. If VBUS is not * provided, then disable wait for this port. */ - bc12_det_mark[port] = usb_charger_process(port) + bc12_det_mark[port] = + usb_charger_process(CHARGER_SOLO, port) ? get_time().val + BC12_DETECT_US : 0; changed = 1; } @@ -1304,7 +1330,7 @@ void usb_charger_task(void *u) vbus_reg = (port == BD9995X_CHARGE_PORT_VBUS) ? BD9995X_CMD_VBUS_VAL : BD9995X_CMD_VCC_VAL; - if (ch_raw_read16(vbus_reg, + if (ch_raw_read16(CHARGER_SOLO, vbus_reg, &voltage, BD9995X_EXTENDED_COMMAND)) voltage = 0; @@ -1322,13 +1348,14 @@ void usb_charger_task(void *u) * 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. + * happens the function will return 0. */ bc12_det_mark[port] = - bd9995x_bc12_check_type(port) ? + bd9995x_bc12_check_type(CHARGER_SOLO, + port) ? get_time().val + 100 * MSEC : 0; /* Reset BC1.2 regs to skip auto-detection. */ - bd9995x_bc12_detect(port, 0); + bd9995x_bc12_detect(CHARGER_SOLO, port, 0); } /* @@ -1376,7 +1403,7 @@ void usb_charger_task(void *u) } break; case DEBOUNCE: - if (bd9995x_vbus_debounce(port_update) || + if (bd9995x_vbus_debounce(CHARGER_SOLO, port_update) || get_time().val > vbus_timeout) { select_input_port_update = 0; bd9995x_select_input_port_private( @@ -1403,19 +1430,19 @@ void usb_charger_task(void *u) /*** Console commands ***/ #ifdef CONFIG_CMD_CHARGER_DUMP -static int read_bat(uint8_t cmd) +static int read_bat(int chgnum, uint8_t cmd) { int read = 0; - ch_raw_read16(cmd, &read, BD9995X_BAT_CHG_COMMAND); + ch_raw_read16(chgnum, cmd, &read, BD9995X_BAT_CHG_COMMAND); return read; } -static int read_ext(uint8_t cmd) +static int read_ext(int chgnum, uint8_t cmd) { int read = 0; - ch_raw_read16(cmd, &read, BD9995X_EXTENDED_COMMAND); + ch_raw_read16(chgnum, cmd, &read, BD9995X_EXTENDED_COMMAND); return read; } @@ -1427,11 +1454,12 @@ static int console_bd9995x_dump_regs(int argc, char **argv) /* Battery group registers */ for (i = 0; i < ARRAY_SIZE(regs); ++i) - ccprintf("BAT REG %4x: %4x\n", regs[i], read_bat(regs[i])); + ccprintf("BAT REG %4x: %4x\n", regs[i], read_bat(CHARGER_SOLO, + regs[i])); /* Extended group registers */ for (i = 0; i < 0x7f; ++i) { - ccprintf("EXT REG %4x: %4x\n", i, read_ext(i)); + ccprintf("EXT REG %4x: %4x\n", i, read_ext(CHARGER_SOLO, i)); cflush(); } @@ -1467,15 +1495,15 @@ static int console_command_bd9995x(int argc, char **argv) return EC_ERROR_PARAM3; if (rw == 'r') - rv = ch_raw_read16(reg, &data, cmd); + rv = ch_raw_read16(CHARGER_SOLO, 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); + rv = ch_raw_write16(CHARGER_SOLO, reg, val, cmd); if (rv == EC_SUCCESS) - rv = ch_raw_read16(reg, &data, cmd); + rv = ch_raw_read16(CHARGER_SOLO, reg, &data, cmd); } if (rv == EC_SUCCESS) @@ -1489,14 +1517,14 @@ DECLARE_CONSOLE_COMMAND(bd9995x, console_command_bd9995x, #endif /* CONFIG_CMD_CHARGER */ #ifdef CONFIG_CHARGER_PSYS_READ -static int bd9995x_psys_charger_adc(void) +static int bd9995x_psys_charger_adc(int chgnum) { 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, ®, + if (ch_raw_read16(chgnum, BD9995X_CMD_PMON_DACIN_VAL, ®, BD9995X_EXTENDED_COMMAND)) return 0; @@ -1513,12 +1541,12 @@ static int bd9995x_psys_charger_adc(void) BD9995X_PMON_IOUT_ADC_READ_COUNT)); } -static int bd9995x_enable_psys(void) +static int bd9995x_enable_psys(int chgnum) { int rv; int reg; - rv = ch_raw_read16(BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -1529,7 +1557,7 @@ static int bd9995x_enable_psys(void) BD9995X_CMD_PMON_IOUT_CTRL_SET_PMON_OUT_EN | BD9995X_PSYS_GAIN_SELECT); - return ch_raw_write16(BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, + return ch_raw_write16(chgnum, BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, BD9995X_EXTENDED_COMMAND); } @@ -1545,12 +1573,12 @@ static int console_command_psys(int argc, char **argv) { int rv; - rv = bd9995x_enable_psys(); + rv = bd9995x_enable_psys(CHARGER_SOLO); if (rv) return rv; CPRINTS("PSYS from chg_adc: %d mW", - bd9995x_psys_charger_adc()); + bd9995x_psys_charger_adc(CHARGER_SOLO)); return EC_SUCCESS; } @@ -1560,14 +1588,14 @@ DECLARE_CONSOLE_COMMAND(psys, console_command_psys, #endif /* CONFIG_CHARGER_PSYS_READ */ #ifdef CONFIG_CMD_CHARGER_ADC_AMON_BMON -static int bd9995x_amon_bmon_chg_adc(void) +static int bd9995x_amon_bmon_chg_adc(int chgnum) { 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, ®, + ch_raw_read16(chgnum, BD9995X_CMD_IOUT_DACIN_VAL, ®, BD9995X_EXTENDED_COMMAND); iout += reg; @@ -1587,14 +1615,14 @@ static int bd9995x_amon_bmon_chg_adc(void) (10 * BD9995X_PMON_IOUT_ADC_READ_COUNT); } -static int bd9995x_amon_bmon(int amon_bmon) +static int bd9995x_amon_bmon(int chgnum, int amon_bmon) { int rv; int reg; int imon; int sns_res; - rv = ch_raw_read16(BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, + rv = ch_raw_read16(chgnum, BD9995X_CMD_PMON_IOUT_CTRL_SET, ®, BD9995X_EXTENDED_COMMAND); if (rv) return rv; @@ -1613,12 +1641,12 @@ static int bd9995x_amon_bmon(int amon_bmon) sns_res = CONFIG_CHARGER_SENSE_RESISTOR; } - rv = ch_raw_write16(BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, + rv = ch_raw_write16(chgnum, BD9995X_CMD_PMON_IOUT_CTRL_SET, reg, BD9995X_EXTENDED_COMMAND); if (rv) return rv; - imon = bd9995x_amon_bmon_chg_adc(); + imon = bd9995x_amon_bmon_chg_adc(chgnum); CPRINTS("%cMON from chg_adc: %d uV, %d mA]", amon_bmon ? 'A' : 'B', @@ -1637,11 +1665,11 @@ static int console_command_amon_bmon(int argc, char **argv) /* Switch to AMON */ if (argc == 1 || (argc >= 2 && argv[1][0] == 'a')) - rv = bd9995x_amon_bmon(1); + rv = bd9995x_amon_bmon(CHARGER_SOLO, 1); /* Switch to BMON */ if (argc == 1 || (argc >= 2 && argv[1][0] == 'b')) - rv = bd9995x_amon_bmon(0); + rv = bd9995x_amon_bmon(CHARGER_SOLO, 0); return rv; } @@ -1653,12 +1681,13 @@ DECLARE_CONSOLE_COMMAND(amonbmon, console_command_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); + return ch_raw_read16(CHARGER_SOLO, reg, data, BD9995X_EXTENDED_COMMAND); } static int bd9995x_i2c_write(const int reg, int data) { - return ch_raw_write16(reg, data, BD9995X_EXTENDED_COMMAND); + return ch_raw_write16(CHARGER_SOLO, reg, data, + BD9995X_EXTENDED_COMMAND); } /* BD9995X_CMD_CHIP_ID register value may vary by chip. */ @@ -1672,3 +1701,22 @@ struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev = { .i2c_write_dev = &bd9995x_i2c_write, }; #endif /* CONFIG_CMD_I2C_STRESS_TEST_CHARGER */ + +const struct charger_drv bd9995x_drv = { + .post_init = &bd9995x_post_init, + .get_info = &bd9995x_get_info, + .get_status = &bd9995x_get_status, + .set_mode = &bd9995x_set_mode, + .get_current = &bd9995x_get_current, + .set_current = &bd9995x_set_current, + .get_voltage = &bd9995x_get_voltage, + .set_voltage = &bd9995x_set_voltage, + .discharge_on_ac = &bd9995x_discharge_on_ac, + .get_vbus_voltage = &bd9995x_get_vbus_voltage, + .set_input_current = &bd9995x_set_input_current, + .get_input_current = &bd9995x_get_input_current, + .manufacturer_id = &bd9995x_manufacturer_id, + .device_id = &bd9995x_device_id, + .get_option = &bd9995x_get_option, + .set_option = &bd9995x_set_option, +}; diff --git a/driver/charger/bd9995x.h b/driver/charger/bd9995x.h index 491f4bdeac..5d346eb969 100644 --- a/driver/charger/bd9995x.h +++ b/driver/charger/bd9995x.h @@ -9,7 +9,6 @@ #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 @@ -361,4 +360,6 @@ int bd9995x_get_battery_voltage(void); extern struct i2c_stress_test_dev bd9995x_i2c_stress_test_dev; #endif +extern const struct charger_drv bd9995x_drv; + #endif /* __CROS_EC_BD9995X_H */ diff --git a/driver/charger/bq24715.c b/driver/charger/bq24715.c index 8a8d9b894f..691d5f94fb 100644 --- a/driver/charger/bq24715.c +++ b/driver/charger/bq24715.c @@ -22,7 +22,7 @@ /* Note: it is assumed that the sense resistors are 10mOhm. */ -static const struct charger_info bq24725_charger_info = { +static const struct charger_info bq24715_charger_info = { .name = "bq24715", .voltage_max = CHARGE_V_MAX, .voltage_min = CHARGE_V_MIN, @@ -35,30 +35,34 @@ static const struct charger_info bq24725_charger_info = { .input_current_step = REG_TO_CURRENT(INPUT_I_STEP, R_AC), }; -static inline int sbc_read(int cmd, int *param) +static inline enum ec_error_list sbc_read(int chgnum, int cmd, int *param) { - return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR_FLAGS, + return i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, cmd, param); } -static inline int sbc_write(int cmd, int param) +static inline enum ec_error_list sbc_write(int chgnum, int cmd, int param) { - return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR_FLAGS, + return i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, cmd, param); } -int charger_set_input_current(int input_current) +static enum ec_error_list bq24715_set_input_current(int chgnum, + int input_current) { - return sbc_write(BQ24715_INPUT_CURRENT, + return sbc_write(chgnum, BQ24715_INPUT_CURRENT, CURRENT_TO_REG(input_current, R_AC)); } -int charger_get_input_current(int *input_current) +static enum ec_error_list bq24715_get_input_current(int chgnum, + int *input_current) { int rv; int reg; - rv = sbc_read(BQ24715_INPUT_CURRENT, ®); + rv = sbc_read(chgnum, BQ24715_INPUT_CURRENT, ®); if (rv) return rv; @@ -67,39 +71,39 @@ int charger_get_input_current(int *input_current) return EC_SUCCESS; } -int charger_manufacturer_id(int *id) +static enum ec_error_list bq24715_manufacturer_id(int chgnum, int *id) { - return sbc_read(BQ24715_MANUFACTURER_ID, id); + return sbc_read(chgnum, BQ24715_MANUFACTURER_ID, id); } -int charger_device_id(int *id) +static enum ec_error_list bq24715_device_id(int chgnum, int *id) { - return sbc_read(BQ24715_DEVICE_ID, id); + return sbc_read(chgnum, BQ24715_DEVICE_ID, id); } -int charger_get_option(int *option) +static enum ec_error_list bq24715_get_option(int chgnum, int *option) { - return sbc_read(BQ24715_CHARGE_OPTION, option); + return sbc_read(chgnum, BQ24715_CHARGE_OPTION, option); } -int charger_set_option(int option) +static enum ec_error_list bq24715_set_option(int chgnum, int option) { - return sbc_write(BQ24715_CHARGE_OPTION, option); + return sbc_write(chgnum, BQ24715_CHARGE_OPTION, option); } /* Charger interfaces */ -const struct charger_info *charger_get_info(void) +static const struct charger_info *bq24715_get_info(int chgnum) { - return &bq24725_charger_info; + return &bq24715_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list bq24715_get_status(int chgnum, int *status) { int rv; int option; - rv = charger_get_option(&option); + rv = bq24715_get_option(chgnum, &option); if (rv) return rv; @@ -112,12 +116,12 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list bq24715_set_mode(int chgnum, int mode) { int rv; int option; - rv = charger_get_option(&option); + rv = bq24715_get_option(chgnum, &option); if (rv) return rv; @@ -126,15 +130,15 @@ int charger_set_mode(int mode) option |= OPT_CHARGE_DISABLE; else option |= OPT_CHARGE_ENABLE; - return charger_set_option(option); + return bq24715_set_option(chgnum, option); } -int charger_get_current(int *current) +static enum ec_error_list bq24715_get_current(int chgnum, int *current) { int rv; int reg; - rv = sbc_read(SB_CHARGING_CURRENT, ®); + rv = sbc_read(chgnum, SB_CHARGING_CURRENT, ®); if (rv) return rv; @@ -142,11 +146,12 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list bq24715_set_current(int chgnum, int current) { current = charger_closest_current(current); - return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); + return sbc_write(chgnum, SB_CHARGING_CURRENT, + CURRENT_TO_REG(current, R_SNS)); } /* The voltage setting needs to be cached to work with the current @@ -156,7 +161,7 @@ int charger_set_current(int current) * 0V is handled specially to appease the state machine. */ static int cached_voltage; -int charger_get_voltage(int *voltage) +static enum ec_error_list bq24715_get_voltage(int chgnum, int *voltage) { int ret; @@ -165,7 +170,7 @@ int charger_get_voltage(int *voltage) return EC_SUCCESS; } - ret = sbc_read(SB_CHARGING_VOLTAGE, &cached_voltage); + ret = sbc_read(chgnum, SB_CHARGING_VOLTAGE, &cached_voltage); if (ret == EC_SUCCESS) *voltage = cached_voltage; @@ -173,19 +178,19 @@ int charger_get_voltage(int *voltage) return ret; } -int charger_set_voltage(int voltage) +static enum ec_error_list bq24715_set_voltage(int chgnum, int voltage) { cached_voltage = voltage; - return sbc_write(SB_CHARGING_VOLTAGE, voltage); + return sbc_write(chgnum, SB_CHARGING_VOLTAGE, voltage); } /* Charging power state initialization */ -int charger_post_init(void) +static enum ec_error_list bq24715_post_init(int chgnum) { int rv; int option; - rv = charger_get_option(&option); + rv = bq24715_get_option(chgnum, &option); if (rv) return rv; @@ -200,20 +205,20 @@ int charger_post_init(void) /* Enable dynamic power management */ option |= OPT_IDPM_ENABLE; - rv = charger_set_option(option); + rv = bq24715_set_option(chgnum, option); if (rv) return rv; - rv = charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); + rv = bq24715_set_input_current(chgnum, CONFIG_CHARGER_INPUT_CURRENT); return rv; } -int charger_discharge_on_ac(int enable) +static enum ec_error_list bq24715_discharge_on_ac(int chgnum, int enable) { int rv; int option; - rv = charger_get_option(&option); + rv = bq24715_get_option(chgnum, &option); if (rv) return rv; @@ -222,7 +227,25 @@ int charger_discharge_on_ac(int enable) option |= OPT_LEARN_ENABLE; else option |= OPT_LEARN_DISABLE; - rv = charger_set_option(option); + rv = bq24715_set_option(chgnum, option); return rv; } + +const struct charger_drv bq24715_drv = { + .post_init = &bq24715_post_init, + .get_info = &bq24715_get_info, + .get_status = &bq24715_get_status, + .set_mode = &bq24715_set_mode, + .get_current = &bq24715_get_current, + .set_current = &bq24715_set_current, + .get_voltage = &bq24715_get_voltage, + .set_voltage = &bq24715_set_voltage, + .discharge_on_ac = &bq24715_discharge_on_ac, + .set_input_current = &bq24715_set_input_current, + .get_input_current = &bq24715_get_input_current, + .manufacturer_id = &bq24715_manufacturer_id, + .device_id = &bq24715_device_id, + .get_option = &bq24715_get_option, + .set_option = &bq24715_set_option, +}; diff --git a/driver/charger/bq24715.h b/driver/charger/bq24715.h index ca07da053f..644f995f2e 100644 --- a/driver/charger/bq24715.h +++ b/driver/charger/bq24715.h @@ -127,4 +127,6 @@ #define INPUT_I_MAX (8064) #define INPUT_I_STEP (64) +extern const struct charger_drv bq24715_drv; + #endif /* __CROS_EC_BQ24715_H */ diff --git a/driver/charger/bq24773.c b/driver/charger/bq24773.c index 4cd85b5ff1..87ef187357 100644 --- a/driver/charger/bq24773.c +++ b/driver/charger/bq24773.c @@ -42,28 +42,61 @@ static const struct charger_info bq2477x_charger_info = { .input_current_step = REG_TO_CURRENT(INPUT_I_STEP, R_AC), }; +#ifdef CONFIG_CHARGER_BQ24773 +static inline enum ec_error_list raw_read8(int chgnum, int offset, int *value) +{ + return i2c_read8(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, + offset, value); +} + +static inline enum ec_error_list raw_write8(int chgnum, int offset, int value) +{ + return i2c_write8(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, + offset, value); +} +#endif + +static inline enum ec_error_list raw_read16(int chgnum, int offset, int *value) +{ + return i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, + offset, value); +} + +static inline enum ec_error_list raw_write16(int chgnum, int offset, int value) +{ + return i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, + offset, value); +} + + /* chip specific interfaces */ -int charger_set_input_current(int input_current) +static enum ec_error_list bq2477x_set_input_current(int chgnum, + int input_current) { #ifdef CONFIG_CHARGER_BQ24770 - return raw_write16(REG_INPUT_CURRENT, + return raw_write16(chgnum, REG_INPUT_CURRENT, CURRENT_TO_REG(input_current, R_AC)); #elif defined(CONFIG_CHARGER_BQ24773) - return raw_write8(REG_INPUT_CURRENT, + return raw_write8(chgnum, REG_INPUT_CURRENT, CURRENT_TO_REG8(input_current, R_AC)); #endif } -int charger_get_input_current(int *input_current) +static enum ec_error_list bq2477x_get_input_current(int chgnum, + int *input_current) { int rv; int reg; #ifdef CONFIG_CHARGER_BQ24770 - rv = raw_read16(REG_INPUT_CURRENT, ®); + rv = raw_read16(chgnum, REG_INPUT_CURRENT, ®); #elif defined(CONFIG_CHARGER_BQ24773) - rv = raw_read8(REG_INPUT_CURRENT, ®); + rv = raw_read8(chgnum, REG_INPUT_CURRENT, ®); #endif if (rv) return rv; @@ -76,48 +109,48 @@ int charger_get_input_current(int *input_current) return EC_SUCCESS; } -int charger_manufacturer_id(int *id) +static enum ec_error_list bq2477x_manufacturer_id(int chgnum, int *id) { #ifdef CONFIG_CHARGER_BQ24770 - return raw_read16(REG_MANUFACTURE_ID, id); + return raw_read16(chgnum, REG_MANUFACTURE_ID, id); #elif defined(CONFIG_CHARGER_BQ24773) *id = 0x40; /* TI */ return EC_SUCCESS; #endif } -int charger_device_id(int *id) +static enum ec_error_list bq2477x_device_id(int chgnum, int *id) { #ifdef CONFIG_CHARGER_BQ24770 - return raw_read16(REG_DEVICE_ADDRESS, id); + return raw_read16(chgnum, REG_DEVICE_ADDRESS, id); #elif defined(CONFIG_CHARGER_BQ24773) - return raw_read8(REG_DEVICE_ADDRESS, id); + return raw_read8(chgnum, REG_DEVICE_ADDRESS, id); #endif } -int charger_get_option(int *option) +static enum ec_error_list bq2477x_get_option(int chgnum, int *option) { - return raw_read16(REG_CHARGE_OPTION0, option); + return raw_read16(chgnum, REG_CHARGE_OPTION0, option); } -int charger_set_option(int option) +static enum ec_error_list bq2477x_set_option(int chgnum, int option) { - return raw_write16(REG_CHARGE_OPTION0, option); + return raw_write16(chgnum, REG_CHARGE_OPTION0, option); } /* Charger interfaces */ -const struct charger_info *charger_get_info(void) +static const struct charger_info *bq2477x_get_info(int chgnum) { return &bq2477x_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list bq2477x_get_status(int chgnum, int *status) { int rv; int option; - rv = charger_get_option(&option); + rv = bq2477x_get_option(chgnum, &option); if (rv) return rv; @@ -130,12 +163,12 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list bq2477x_set_mode(int chgnum, int mode) { int rv; int option; - rv = charger_get_option(&option); + rv = bq2477x_get_option(chgnum, &option); if (rv) return rv; @@ -143,15 +176,15 @@ int charger_set_mode(int mode) option |= OPTION0_CHARGE_INHIBIT; else option &= ~OPTION0_CHARGE_INHIBIT; - return charger_set_option(option); + return bq2477x_set_option(chgnum, option); } -int charger_get_current(int *current) +static enum ec_error_list bq2477x_get_current(int chgnum, int *current) { int rv; int reg; - rv = raw_read16(REG_CHARGE_CURRENT, ®); + rv = raw_read16(chgnum, REG_CHARGE_CURRENT, ®); if (rv) return rv; @@ -160,55 +193,56 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list bq2477x_set_current(int chgnum, int current) { current = charger_closest_current(current); - return raw_write16(REG_CHARGE_CURRENT, CURRENT_TO_REG(current, R_SNS)); + return raw_write16(chgnum, REG_CHARGE_CURRENT, + CURRENT_TO_REG(current, R_SNS)); } -int charger_get_voltage(int *voltage) +static enum ec_error_list bq2477x_get_voltage(int chgnum, int *voltage) { - return raw_read16(REG_MAX_CHARGE_VOLTAGE, voltage); + return raw_read16(chgnum, REG_MAX_CHARGE_VOLTAGE, voltage); } -int charger_set_voltage(int voltage) +static enum ec_error_list bq2477x_set_voltage(int chgnum, int voltage) { voltage = charger_closest_voltage(voltage); - return raw_write16(REG_MAX_CHARGE_VOLTAGE, voltage); + return raw_write16(chgnum, REG_MAX_CHARGE_VOLTAGE, voltage); } /* Charging power state initialization */ -int charger_post_init(void) +static enum ec_error_list bq2477x_post_init(int chgnum) { int rv, option; #ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED int option2; #endif - rv = charger_get_option(&option); + rv = bq2477x_get_option(chgnum, &option); if (rv) return rv; option &= ~OPTION0_LEARN_ENABLE; - rv = charger_set_option(option); + rv = bq2477x_set_option(chgnum, option); if (rv) return rv; #ifndef BOARD_SAMUS /* Turn off PROCHOT warning */ - rv = raw_read16(REG_PROCHOT_OPTION1, &option); + rv = raw_read16(chgnum, REG_PROCHOT_OPTION1, &option); if (rv) return rv; option &= ~PROCHOT_OPTION1_SELECTOR_MASK; - rv = raw_write16(REG_PROCHOT_OPTION1, option); + rv = raw_write16(chgnum, 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); + rv = raw_write16(chgnum, REG_PROCHOT_OPTION1, 0x8120); /* Set PROCHOT ICRIT warning when IADP is >120% of IDPM */ - rv |= raw_write16(REG_PROCHOT_OPTION0, 0x1b54); + rv |= raw_write16(chgnum, REG_PROCHOT_OPTION0, 0x1b54); #endif if (rv) @@ -216,14 +250,14 @@ int charger_post_init(void) #ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED /* Read the external ILIM pin enabled flag. */ - rv = raw_read16(REG_CHARGE_OPTION2, &option2); + rv = raw_read16(chgnum, 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); + rv = raw_write16(chgnum, REG_CHARGE_OPTION2, option2); } return rv; #else @@ -231,19 +265,37 @@ int charger_post_init(void) #endif } -int charger_discharge_on_ac(int enable) +static enum ec_error_list bq2477x_discharge_on_ac(int chgnum, int enable) { int rv; int option; - rv = charger_get_option(&option); + rv = bq2477x_get_option(chgnum, &option); if (rv) return rv; if (enable) - rv = charger_set_option(option | OPTION0_LEARN_ENABLE); + rv = bq2477x_set_option(chgnum, option | OPTION0_LEARN_ENABLE); else - rv = charger_set_option(option & ~OPTION0_LEARN_ENABLE); + rv = bq2477x_set_option(chgnum, option & ~OPTION0_LEARN_ENABLE); return rv; } + +const struct charger_drv bq2477x_drv = { + .post_init = &bq2477x_post_init, + .get_info = &bq2477x_get_info, + .get_status = &bq2477x_get_status, + .set_mode = &bq2477x_set_mode, + .get_current = &bq2477x_get_current, + .set_current = &bq2477x_set_current, + .get_voltage = &bq2477x_get_voltage, + .set_voltage = &bq2477x_set_voltage, + .discharge_on_ac = &bq2477x_discharge_on_ac, + .set_input_current = &bq2477x_set_input_current, + .get_input_current = &bq2477x_get_input_current, + .manufacturer_id = &bq2477x_manufacturer_id, + .device_id = &bq2477x_device_id, + .get_option = &bq2477x_get_option, + .set_option = &bq2477x_set_option, +}; diff --git a/driver/charger/bq24773.h b/driver/charger/bq24773.h index 910ad8da25..c22bfa528a 100644 --- a/driver/charger/bq24773.h +++ b/driver/charger/bq24773.h @@ -102,30 +102,6 @@ #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); -} +extern const struct charger_drv bq2477x_drv; #endif /* __CROS_EC_BQ24773_H */ diff --git a/driver/charger/bq25710.c b/driver/charger/bq25710.c index 9df085d78f..d355db8c7e 100644 --- a/driver/charger/bq25710.c +++ b/driver/charger/bq25710.c @@ -16,6 +16,7 @@ #include "i2c.h" #include "task.h" #include "timer.h" +#include "util.h" #ifndef CONFIG_CHARGER_NARROW_VDC #error "BQ25710 is a NVDC charger, please enable CONFIG_CHARGER_NARROW_VDC." @@ -69,26 +70,31 @@ static const struct charger_info bq25710_charger_info = { .input_current_step = 50 / INPUT_RESISTOR_RATIO, }; -static inline int raw_read16(int offset, int *value) +static enum ec_error_list bq25710_get_option(int chgnum, int *option); +static enum ec_error_list bq25710_set_option(int chgnum, int option); + +static inline enum ec_error_list raw_read16(int chgnum, int offset, int *value) { - return i2c_read16(I2C_PORT_CHARGER, BQ25710_SMBUS_ADDR1_FLAGS, + return i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static inline int raw_write16(int offset, int value) +static inline enum ec_error_list raw_write16(int chgnum, int offset, int value) { - return i2c_write16(I2C_PORT_CHARGER, BQ25710_SMBUS_ADDR1_FLAGS, + return i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_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) +static int bq25710_get_low_power_mode(int chgnum, int *mode) { int rv; int reg; - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_0, ®); + rv = raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_0, ®); if (rv) return rv; @@ -97,12 +103,12 @@ static int bq25710_get_low_power_mode(int *mode) return EC_SUCCESS; } -static int bq25710_set_low_power_mode(int enable) +static int bq25710_set_low_power_mode(int chgnum, int enable) { int rv; int reg; - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_0, ®); + rv = raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_0, ®); if (rv) return rv; @@ -126,7 +132,7 @@ static int bq25710_set_low_power_mode(int enable) else reg &= ~BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE; - rv = raw_write16(BQ25710_REG_CHARGE_OPTION_0, reg); + rv = raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_0, reg); #ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA mutex_unlock(&bq25710_perf_mode_mutex); #endif @@ -136,18 +142,18 @@ static int bq25710_set_low_power_mode(int enable) return EC_SUCCESS; } -static int bq25710_adc_start(int adc_en_mask) +static int bq25710_adc_start(int chgnum, 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)) + if (bq25710_get_low_power_mode(chgnum, &mode)) return EC_ERROR_UNKNOWN; /* Exit low power mode so ADC conversion takes typical time */ - if (bq25710_set_low_power_mode(0)) + if (bq25710_set_low_power_mode(chgnum, 0)) return EC_ERROR_UNKNOWN; /* @@ -156,7 +162,7 @@ static int bq25710_adc_start(int adc_en_mask) */ reg = (adc_en_mask & BQ25710_ADC_OPTION_EN_ADC_ALL) | BQ25710_ADC_OPTION_ADC_START; - if (raw_write16(BQ25710_REG_ADC_OPTION, reg)) + if (raw_write16(chgnum, BQ25710_REG_ADC_OPTION, reg)) return EC_ERROR_UNKNOWN; /* @@ -166,11 +172,11 @@ static int bq25710_adc_start(int adc_en_mask) */ do { msleep(2); - raw_read16(BQ25710_REG_ADC_OPTION, ®); + raw_read16(chgnum, 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)) + if (bq25710_set_low_power_mode(chgnum, mode)) return EC_ERROR_UNKNOWN; /* Could not complete read */ @@ -181,7 +187,7 @@ static int bq25710_adc_start(int adc_en_mask) } #endif -static void bq25710_init(void) +static void bq25710_init(int chgnum) { int reg; int vsys; @@ -196,23 +202,23 @@ static void bq25710_init(void) * the bq25710 must not be in low power mode, otherwise the VDDA rail * may not be powered if AC is not connected. */ - rv = bq25710_set_low_power_mode(0); + rv = bq25710_set_low_power_mode(chgnum, 0); /* Allow enough time for VDDA to be powered */ msleep(BQ25710_VDDA_STARTUP_DELAY_MSEC); - rv |= raw_read16(BQ25710_REG_MIN_SYSTEM_VOLTAGE, &vsys); - rv |= raw_read16(BQ25710_REG_CHARGE_OPTION_3, ®); + rv |= raw_read16(chgnum, BQ25710_REG_MIN_SYSTEM_VOLTAGE, &vsys); + rv |= raw_read16(chgnum, 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); + raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_3, reg); /* Restore VSYS_MIN voltage to POR reset value */ - raw_write16(BQ25710_REG_MIN_SYSTEM_VOLTAGE, vsys); + raw_write16(chgnum, BQ25710_REG_MIN_SYSTEM_VOLTAGE, vsys); } /* Reenable low power mode */ - bq25710_set_low_power_mode(1); + bq25710_set_low_power_mode(chgnum, 1); - if (!raw_read16(BQ25710_REG_PROCHOT_OPTION_1, ®)) { - /* Disbale VDPM prochot profile at initialization */ + if (!raw_read16(chgnum, BQ25710_REG_PROCHOT_OPTION_1, ®)) { + /* Disable VDPM prochot profile at initialization */ reg &= ~BQ25710_PROCHOT_PROFILE_VDPM; /* * Enable PROCHOT to be asserted with VSYS min detection. Note @@ -236,33 +242,32 @@ static void bq25710_init(void) BQ25710_PROCHOT_IDCHG_VTH_MASK); reg |= BQ25710_PROCHOT_PROFILE_IDCHG; #endif - raw_write16(BQ25710_REG_PROCHOT_OPTION_1, reg); + raw_write16(chgnum, BQ25710_REG_PROCHOT_OPTION_1, reg); } /* Reduce ILIM from default of 150% to 105% */ - if (!raw_read16(BQ25710_REG_PROCHOT_OPTION_0, ®)) { + if (!raw_read16(chgnum, BQ25710_REG_PROCHOT_OPTION_0, ®)) { reg &= ~BQ25710_PROCHOT0_ILIM_VTH_MASK; - raw_write16(BQ25710_REG_PROCHOT_OPTION_0, reg); + raw_write16(chgnum, 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, ®)) { + if (!raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_2, ®)) { reg &= ~BQ25710_CHARGE_OPTION_2_TMAX_MASK; - raw_write16(BQ25710_REG_CHARGE_OPTION_2, reg); + raw_write16(chgnum, 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) +static const struct charger_info *bq25710_get_info(int chgnum) { return &bq25710_charger_info; } -int charger_post_init(void) +static enum ec_error_list bq25710_post_init(int chgnum) { /* * Note: bq25710 power on reset state is: @@ -276,12 +281,12 @@ int charger_post_init(void) return EC_SUCCESS; } -int charger_get_status(int *status) +static enum ec_error_list bq25710_get_status(int chgnum, int *status) { int rv; int option; - rv = charger_get_option(&option); + rv = bq25710_get_option(chgnum, &option); if (rv) return rv; @@ -294,12 +299,12 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list bq25710_set_mode(int chgnum, int mode) { int rv; int option; - rv = charger_get_option(&option); + rv = bq25710_get_option(chgnum, &option); if (rv) return rv; @@ -308,16 +313,18 @@ int charger_set_mode(int mode) else option &= ~BQ25710_CHARGE_OPTION_0_CHRG_INHIBIT; - return charger_set_option(option); + return bq25710_set_option(chgnum, option); } -int charger_enable_otg_power(int enabled) +static enum ec_error_list bq25710_enable_otg_power(int chgnum, 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) +static enum ec_error_list bq25710_set_otg_current_voltage(int chgum, + int output_current, + int output_voltage) { /* Add when needed. */ return EC_ERROR_UNIMPLEMENTED; @@ -329,40 +336,40 @@ int charger_is_sourcing_otg_power(int port) return EC_ERROR_UNIMPLEMENTED; } -int charger_get_current(int *current) +static enum ec_error_list bq25710_get_current(int chgnum, int *current) { int rv, reg; - rv = raw_read16(BQ25710_REG_CHARGE_CURRENT, ®); + rv = raw_read16(chgnum, BQ25710_REG_CHARGE_CURRENT, ®); if (!rv) *current = REG_TO_CHARGING_CURRENT(reg); return rv; } -int charger_set_current(int current) +static enum ec_error_list bq25710_set_current(int chgnum, int current) { - return raw_write16(BQ25710_REG_CHARGE_CURRENT, + return raw_write16(chgnum, BQ25710_REG_CHARGE_CURRENT, CHARGING_CURRENT_TO_REG(current)); } /* Get/set charge voltage limit in mV */ -int charger_get_voltage(int *voltage) +static enum ec_error_list bq25710_get_voltage(int chgnum, int *voltage) { - return raw_read16(BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); + return raw_read16(chgnum, BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); } -int charger_set_voltage(int voltage) +static enum ec_error_list bq25710_set_voltage(int chgnum, int voltage) { - return raw_write16(BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); + return raw_write16(chgnum, BQ25710_REG_MAX_CHARGE_VOLTAGE, voltage); } /* Discharge battery when on AC power. */ -int charger_discharge_on_ac(int enable) +static enum ec_error_list bq25710_discharge_on_ac(int chgnum, int enable) { int rv, option; - rv = charger_get_option(&option); + rv = bq25710_get_option(chgnum, &option); if (rv) return rv; @@ -371,18 +378,20 @@ int charger_discharge_on_ac(int enable) else option &= ~BQ25710_CHARGE_OPTION_0_EN_LEARN; - return charger_set_option(option); + return bq25710_set_option(chgnum, option); } -int charger_set_input_current(int input_current) +static enum ec_error_list bq25710_set_input_current(int chgnum, + int input_current) { int num_steps = INPUT_CURRENT_TO_REG(input_current); - return raw_write16(BQ25710_REG_IIN_HOST, num_steps << + return raw_write16(chgnum, BQ25710_REG_IIN_HOST, num_steps << BQ25710_CHARGE_IIN_BIT_0FFSET); } -int charger_get_input_current(int *input_current) +static enum ec_error_list bq25710_get_input_current(int chgnum, + int *input_current) { int rv, reg; @@ -392,7 +401,7 @@ int charger_get_input_current(int *input_current) * current limit used by DPM regulation may differ from the IIN_HOST * register settings. */ - rv = raw_read16(BQ25710_REG_IIN_DPM, ®); + rv = raw_read16(chgnum, BQ25710_REG_IIN_DPM, ®); if (!rv) *input_current = REG_TO_INPUT_CURRENT((reg >> @@ -401,27 +410,27 @@ int charger_get_input_current(int *input_current) return rv; } -int charger_manufacturer_id(int *id) +static enum ec_error_list bq25710_manufacturer_id(int chgnum, int *id) { - return raw_read16(BQ25710_REG_MANUFACTURER_ID, id); + return raw_read16(chgnum, BQ25710_REG_MANUFACTURER_ID, id); } -int charger_device_id(int *id) +static enum ec_error_list bq25710_device_id(int chgnum, int *id) { - return raw_read16(BQ25710_REG_DEVICE_ADDRESS, id); + return raw_read16(chgnum, BQ25710_REG_DEVICE_ADDRESS, id); } #ifdef CONFIG_USB_PD_VBUS_MEASURE_CHARGER -int charger_get_vbus_voltage(int port) +static int bq25710_get_vbus_voltage(int chgnum, int port) { int reg, rv; - rv = bq25710_adc_start(BQ25710_ADC_OPTION_EN_ADC_VBUS); + rv = bq25710_adc_start(chgnum, BQ25710_ADC_OPTION_EN_ADC_VBUS); if (rv) goto error; /* Read ADC value */ - rv = raw_read16(BQ25710_REG_ADC_VBUS_PSYS, ®); + rv = raw_read16(chgnum, BQ25710_REG_ADC_VBUS_PSYS, ®); if (rv) goto error; @@ -439,16 +448,16 @@ error: } #endif -int charger_get_option(int *option) +static enum ec_error_list bq25710_get_option(int chgnum, int *option) { /* There are 4 option registers, but we only need the first for now. */ - return raw_read16(BQ25710_REG_CHARGE_OPTION_0, option); + return raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_0, option); } -int charger_set_option(int option) +static enum ec_error_list bq25710_set_option(int chgnum, int option) { /* There are 4 option registers, but we only need the first for now. */ - return raw_write16(BQ25710_REG_CHARGE_OPTION_0, option); + return raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_0, option); } #ifdef CONFIG_CHARGE_RAMP_HW @@ -476,14 +485,14 @@ static void bq25710_chg_ramp_handle(void) } DECLARE_DEFERRED(bq25710_chg_ramp_handle); -int charger_set_hw_ramp(int enable) +static enum ec_error_list bq25710_set_hw_ramp(int chgnum, int enable) { int option3_reg, option2_reg, rv; - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_3, &option3_reg); + rv = raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_3, &option3_reg); if (rv) return rv; - rv = raw_read16(BQ25710_REG_CHARGE_OPTION_2, &option2_reg); + rv = raw_read16(chgnum, BQ25710_REG_CHARGE_OPTION_2, &option2_reg); if (rv) return rv; @@ -501,7 +510,7 @@ int charger_set_hw_ramp(int enable) } /* Set InputVoltage register to BC1.2 minimum ramp voltage */ - rv = raw_write16(BQ25710_REG_INPUT_VOLTAGE, + rv = raw_write16(chgnum, BQ25710_REG_INPUT_VOLTAGE, BQ25710_BC12_MIN_VOLTAGE_MV); if (rv) return rv; @@ -525,27 +534,27 @@ int charger_set_hw_ramp(int enable) option2_reg |= BQ25710_CHARGE_OPTION_2_EN_EXTILIM; } - rv = raw_write16(BQ25710_REG_CHARGE_OPTION_2, option2_reg); + rv = raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_2, option2_reg); if (rv) return rv; - return raw_write16(BQ25710_REG_CHARGE_OPTION_3, option3_reg); + return raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_3, option3_reg); } -int chg_ramp_is_stable(void) +static int bq25710_ramp_is_stable(int chgnum) { int reg; - if (raw_read16(BQ25710_REG_CHARGER_STATUS, ®)) + if (raw_read16(chgnum, BQ25710_REG_CHARGER_STATUS, ®)) return 0; return reg & BQ25710_CHARGE_STATUS_ICO_DONE; } -int chg_ramp_get_current_limit(void) +static int bq25710_ramp_get_current_limit(int chgnum) { int reg, rv; - rv = raw_read16(BQ25710_REG_IIN_DPM, ®); + rv = raw_read16(chgnum, BQ25710_REG_IIN_DPM, ®); if (rv) { CPRINTF("Could not read iin_dpm current limit! Error: %d\n", rv); @@ -561,7 +570,7 @@ int chg_ramp_get_current_limit(void) /* Called on AP S5 -> S3 and S3/S0iX -> S0 transition */ static void bq25710_chipset_startup(void) { - bq25710_set_low_power_mode(0); + bq25710_set_low_power_mode(CHARGER_SOLO, 0); } DECLARE_HOOK(HOOK_CHIPSET_STARTUP, bq25710_chipset_startup, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_CHIPSET_RESUME, bq25710_chipset_startup, HOOK_PRIO_DEFAULT); @@ -570,7 +579,7 @@ 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); + bq25710_set_low_power_mode(CHARGER_SOLO, 1); } DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT); @@ -581,6 +590,8 @@ static int console_bq25710_dump_regs(int argc, char **argv) { int i; int val; + int chgnum = 0; + char *e; /* Dump all readable registers on bq25710. */ static const uint8_t regs[] = { @@ -609,17 +620,48 @@ static int console_bq25710_dump_regs(int argc, char **argv) BQ25710_REG_MANUFACTURER_ID, BQ25710_REG_DEVICE_ADDRESS, }; + if (argc >= 2) { + chgnum = strtoi(argv[1], &e, 10); + if (*e) + return EC_ERROR_PARAM1; + } for (i = 0; i < ARRAY_SIZE(regs); ++i) { - if (raw_read16(regs[i], &val)) + if (raw_read16(chgnum, 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, - "", + "charger_dump <chgnum>", "Dump all charger registers"); #endif /* CONFIG_CMD_CHARGER_DUMP */ + +const struct charger_drv bq25710_drv = { + .init = &bq25710_init, + .post_init = &bq25710_post_init, + .get_info = &bq25710_get_info, + .get_status = &bq25710_get_status, + .set_mode = &bq25710_set_mode, + .enable_otg_power = &bq25710_enable_otg_power, + .set_otg_current_voltage = &bq25710_set_otg_current_voltage, + .get_current = &bq25710_get_current, + .set_current = &bq25710_set_current, + .get_voltage = &bq25710_get_voltage, + .set_voltage = &bq25710_set_voltage, + .discharge_on_ac = &bq25710_discharge_on_ac, + .get_vbus_voltage = &bq25710_get_vbus_voltage, + .set_input_current = &bq25710_set_input_current, + .get_input_current = &bq25710_get_input_current, + .manufacturer_id = &bq25710_manufacturer_id, + .device_id = &bq25710_device_id, + .get_option = &bq25710_get_option, + .set_option = &bq25710_set_option, + .set_hw_ramp = &bq25710_set_hw_ramp, + .ramp_is_stable = &bq25710_ramp_is_stable, + .ramp_get_current_limit = &bq25710_ramp_get_current_limit, +}; diff --git a/driver/charger/bq25710.h b/driver/charger/bq25710.h index 014799a832..37facb7831 100644 --- a/driver/charger/bq25710.h +++ b/driver/charger/bq25710.h @@ -93,4 +93,6 @@ #define BQ25710_IIN_DPM_BIT_SHIFT 8 #define BQ25710_IIN_DPM_STEP_MA 50 +extern const struct charger_drv bq25710_drv; + #endif /* __CROS_EC_BQ25710_H */ diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index 716dad71ac..594ce698a1 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -43,6 +43,8 @@ static int learn_mode; /* Mutex for CONTROL1 register, that can be updated from multiple tasks. */ static struct mutex control1_mutex; +static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable); + /* Charger parameters */ static const struct charger_info isl9237_charger_info = { .name = CHARGER_NAME, @@ -57,54 +59,60 @@ static const struct charger_info isl9237_charger_info = { .input_current_step = AC_REG_TO_CURRENT(INPUT_I_STEP), }; -static inline int raw_read8(int offset, int *value) +static inline enum ec_error_list raw_read8(int chgnum, int offset, int *value) { - return i2c_read8(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_read8(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static inline int raw_read16(int offset, int *value) +static inline enum ec_error_list raw_read16(int chgnum, int offset, int *value) { - return i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static inline int raw_write16(int offset, int value) +static inline enum ec_error_list raw_write16(int chgnum, int offset, int value) { - return i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static int isl9237_set_current(uint16_t current) +static enum ec_error_list isl9237_set_current(int chgnum, uint16_t current) { - return raw_write16(ISL923X_REG_CHG_CURRENT, CURRENT_TO_REG(current)); + return raw_write16(chgnum, ISL923X_REG_CHG_CURRENT, + CURRENT_TO_REG(current)); } -static int isl9237_set_voltage(uint16_t voltage) +static enum ec_error_list isl9237_set_voltage(int chgnum, uint16_t voltage) { - return raw_write16(ISL923X_REG_SYS_VOLTAGE_MAX, voltage); + return raw_write16(chgnum, ISL923X_REG_SYS_VOLTAGE_MAX, voltage); } /* chip specific interfaces */ -int charger_set_input_current(int input_current) +static enum ec_error_list isl923x_set_input_current(int chgnum, + int input_current) { int rv; uint16_t reg = AC_CURRENT_TO_REG(input_current); - rv = raw_write16(ISL923X_REG_ADAPTER_CURRENT1, reg); + rv = raw_write16(chgnum, ISL923X_REG_ADAPTER_CURRENT1, reg); if (rv) return rv; - return raw_write16(ISL923X_REG_ADAPTER_CURRENT2, reg); + return raw_write16(chgnum, ISL923X_REG_ADAPTER_CURRENT2, reg); } -int charger_get_input_current(int *input_current) +static enum ec_error_list isl923x_get_input_current(int chgnum, + int *input_current) { int rv; int reg; - rv = raw_read16(ISL923X_REG_ADAPTER_CURRENT1, ®); + rv = raw_read16(chgnum, ISL923X_REG_ADAPTER_CURRENT1, ®); if (rv) return rv; @@ -113,13 +121,13 @@ int charger_get_input_current(int *input_current) } #if defined(CONFIG_CHARGER_OTG) && defined(CONFIG_CHARGER_ISL9238) -int charger_enable_otg_power(int enabled) +static enum ec_error_list isl923x_enable_otg_power(int chgnum, int enabled) { int rv, control1; mutex_lock(&control1_mutex); - rv = raw_read16(ISL923X_REG_CONTROL1, &control1); + rv = raw_read16(chgnum, ISL923X_REG_CONTROL1, &control1); if (rv) goto out; @@ -128,7 +136,7 @@ int charger_enable_otg_power(int enabled) else control1 &= ~ISL923X_C1_OTG; - rv = raw_write16(ISL923X_REG_CONTROL1, control1); + rv = raw_write16(chgnum, ISL923X_REG_CONTROL1, control1); out: mutex_unlock(&control1_mutex); @@ -140,7 +148,9 @@ out: * 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) +static enum ec_error_list isl923x_set_otg_current_voltage(int chgnum, + int output_current, + int output_voltage) { int rv; uint16_t volt_reg = (output_voltage / ISL9238_OTG_VOLTAGE_STEP) @@ -154,21 +164,21 @@ int charger_set_otg_current_voltage(int output_current, int output_voltage) return EC_ERROR_INVAL; /* Set voltage. */ - rv = raw_write16(ISL923X_REG_OTG_VOLTAGE, volt_reg); + rv = raw_write16(chgnum, ISL923X_REG_OTG_VOLTAGE, volt_reg); if (rv) return rv; /* Set current. */ - return raw_write16(ISL923X_REG_OTG_CURRENT, current_reg); + return raw_write16(chgnum, ISL923X_REG_OTG_CURRENT, current_reg); } #endif /* CONFIG_CHARGER_OTG && CONFIG_CHARGER_ISL9238 */ -int charger_manufacturer_id(int *id) +static enum ec_error_list isl923x_manufacturer_id(int chgnum, int *id) { int rv; int reg; - rv = raw_read16(ISL923X_REG_MANUFACTURER_ID, ®); + rv = raw_read16(chgnum, ISL923X_REG_MANUFACTURER_ID, ®); if (rv) return rv; @@ -176,12 +186,12 @@ int charger_manufacturer_id(int *id) return EC_SUCCESS; } -int charger_device_id(int *id) +static enum ec_error_list isl923x_device_id(int chgnum, int *id) { int rv; int reg; - rv = raw_read16(ISL923X_REG_DEVICE_ID, ®); + rv = raw_read16(chgnum, ISL923X_REG_DEVICE_ID, ®); if (rv) return rv; @@ -189,18 +199,18 @@ int charger_device_id(int *id) return EC_SUCCESS; } -int charger_get_option(int *option) +static enum ec_error_list isl923x_get_option(int chgnum, int *option) { int rv; uint32_t controls; int reg; - rv = raw_read16(ISL923X_REG_CONTROL0, ®); + rv = raw_read16(chgnum, ISL923X_REG_CONTROL0, ®); if (rv) return rv; controls = reg; - rv = raw_read16(ISL923X_REG_CONTROL1, ®); + rv = raw_read16(chgnum, ISL923X_REG_CONTROL1, ®); if (rv) return rv; @@ -209,36 +219,36 @@ int charger_get_option(int *option) return EC_SUCCESS; } -int charger_set_option(int option) +static enum ec_error_list isl923x_set_option(int chgnum, int option) { int rv; uint16_t reg; reg = option & 0xffff; - rv = raw_write16(ISL923X_REG_CONTROL0, reg); + rv = raw_write16(chgnum, ISL923X_REG_CONTROL0, reg); if (rv) return rv; reg = (option >> 16) & 0xffff; - return raw_write16(ISL923X_REG_CONTROL1, reg); + return raw_write16(chgnum, ISL923X_REG_CONTROL1, reg); } /* Charger interfaces */ -const struct charger_info *charger_get_info(void) +static const struct charger_info *isl923x_get_info(int chgnum) { return &isl9237_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list isl923x_get_status(int chgnum, int *status) { *status = CHARGER_LEVEL_2; return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list isl923x_set_mode(int chgnum, int mode) { int rv = EC_SUCCESS; @@ -247,18 +257,18 @@ int charger_set_mode(int mode) * explicitly. */ if (!learn_mode) - rv = charger_discharge_on_ac(0); + rv = isl923x_discharge_on_ac(chgnum, 0); /* ISL923X does not support inhibit mode setting. */ return rv; } -int charger_get_current(int *current) +static enum ec_error_list isl923x_get_current(int chgnum, int *current) { int rv; int reg; - rv = raw_read16(ISL923X_REG_CHG_CURRENT, ®); + rv = raw_read16(chgnum, ISL923X_REG_CHG_CURRENT, ®); if (rv) return rv; @@ -266,17 +276,17 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list isl923x_set_current(int chgnum, int current) { - return isl9237_set_current(current); + return isl9237_set_current(chgnum, current); } -int charger_get_voltage(int *voltage) +static enum ec_error_list isl923x_get_voltage(int chgnum, int *voltage) { - return raw_read16(ISL923X_REG_SYS_VOLTAGE_MAX, voltage); + return raw_read16(chgnum, ISL923X_REG_SYS_VOLTAGE_MAX, voltage); } -int charger_set_voltage(int voltage) +static enum ec_error_list isl923x_set_voltage(int chgnum, 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 @@ -288,10 +298,10 @@ int charger_set_voltage(int voltage) voltage = bi->voltage_min; } - return isl9237_set_voltage(voltage); + return isl9237_set_voltage(chgnum, voltage); } -int charger_post_init(void) +static enum ec_error_list isl923x_post_init(int chgnum) { /* * charger_post_init() is called every time AC becomes present in the @@ -314,7 +324,7 @@ int isl923x_set_ac_prochot(uint16_t ma) return EC_ERROR_INVAL; } - rv = raw_write16(ISL923X_REG_PROCHOT_AC, ma); + rv = raw_write16(CHARGER_SOLO, ISL923X_REG_PROCHOT_AC, ma); if (rv) CPRINTS("%s set_ac_prochot failed (%d)", CHARGER_NAME, rv); return rv; @@ -329,13 +339,13 @@ int isl923x_set_dc_prochot(uint16_t ma) return EC_ERROR_INVAL; } - rv = raw_write16(ISL923X_REG_PROCHOT_DC, ma); + rv = raw_write16(CHARGER_SOLO, ISL923X_REG_PROCHOT_DC, ma); if (rv) CPRINTS("%s set_dc_prochot failed (%d)", CHARGER_NAME, rv); return rv; } -static void isl923x_init(void) +static void isl923x_init(int chgnum) { int reg; const struct battery_info *bi = battery_get_info(); @@ -349,10 +359,10 @@ static void isl923x_init(void) * A 1:1 ratio for Rs1:Rs2 is allowed, but Control4 * register Bit<11> must be set. */ - if (raw_read16(ISL9238_REG_CONTROL4, ®)) + if (raw_read16(chgnum, ISL9238_REG_CONTROL4, ®)) goto init_fail; - if (raw_write16(ISL9238_REG_CONTROL4, + if (raw_write16(chgnum, ISL9238_REG_CONTROL4, reg | RAA489000_C4_PSYS_RSNS_RATIO_1_TO_1)) goto init_fail; @@ -360,19 +370,20 @@ static void isl923x_init(void) } if (IS_ENABLED(CONFIG_TRICKLE_CHARGING)) - if (raw_write16(ISL923X_REG_SYS_VOLTAGE_MIN, precharge_voltage)) + if (raw_write16(chgnum, ISL923X_REG_SYS_VOLTAGE_MIN, + precharge_voltage)) goto init_fail; /* * [10:9]: Prochot# Debounce time * 11b: 1ms */ - if (raw_read16(ISL923X_REG_CONTROL2, ®)) + if (raw_read16(chgnum, ISL923X_REG_CONTROL2, ®)) goto init_fail; if (!IS_ENABLED(CONFIG_CHARGER_RAA489000)) reg |= ISL923X_C2_OTG_DEBOUNCE_150; - if (raw_write16(ISL923X_REG_CONTROL2, + if (raw_write16(chgnum, ISL923X_REG_CONTROL2, reg | ISL923X_C2_PROCHOT_DEBOUNCE_1000 | ISL923X_C2_ADAPTER_DEBOUNCE_150)) @@ -380,7 +391,7 @@ static void isl923x_init(void) if (IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) { if (IS_ENABLED(CONFIG_CHARGER_ISL9237)) { - if (raw_read16(ISL923X_REG_CONTROL0, ®)) + if (raw_read16(chgnum, ISL923X_REG_CONTROL0, ®)) goto init_fail; /* @@ -390,7 +401,7 @@ static void isl923x_init(void) reg &= ~ISL9237_C0_VREG_REF_MASK; reg |= ISL9237_C0_VREG_REF_4200; - if (raw_write16(ISL923X_REG_CONTROL0, reg)) + if (raw_write16(chgnum, ISL923X_REG_CONTROL0, reg)) goto init_fail; } else { /* @@ -408,17 +419,17 @@ static void isl923x_init(void) reg = (4439 / ISL9238_INPUT_VOLTAGE_REF_STEP) << ISL9238_INPUT_VOLTAGE_REF_SHIFT; - if (raw_write16(ISL9238_REG_INPUT_VOLTAGE, reg)) + if (raw_write16(chgnum, ISL9238_REG_INPUT_VOLTAGE, reg)) goto init_fail; } } else { - if (raw_read16(ISL923X_REG_CONTROL0, ®)) + if (raw_read16(chgnum, 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)) + if (raw_write16(chgnum, ISL923X_REG_CONTROL0, reg)) goto init_fail; } @@ -428,7 +439,7 @@ static void isl923x_init(void) * Don't reread the prog pin and don't reload the ILIM on ACIN. * For the RAA489000, just don't reload ACLIM. */ - if (raw_read16(ISL9238_REG_CONTROL3, ®)) + if (raw_read16(chgnum, ISL9238_REG_CONTROL3, ®)) goto init_fail; reg |= ISL9238_C3_NO_RELOAD_ACLIM_ON_ACIN; if (!IS_ENABLED(CONFIG_CHARGER_RAA489000)) @@ -441,7 +452,7 @@ static void isl923x_init(void) * anyway. */ reg |= ISL9238_C3_DISABLE_AUTO_CHARING; - if (raw_write16(ISL9238_REG_CONTROL3, reg)) + if (raw_write16(chgnum, ISL9238_REG_CONTROL3, reg)) goto init_fail; /* @@ -454,7 +465,8 @@ static void isl923x_init(void) /* * Initialize the input current limit to the board's default. */ - if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) + if (isl923x_set_input_current(chgnum, + CONFIG_CHARGER_INPUT_CURRENT)) goto init_fail; } @@ -462,16 +474,15 @@ static void isl923x_init(void) init_fail: CPRINTS("%s init failed!", CHARGER_NAME); } -DECLARE_HOOK(HOOK_INIT, isl923x_init, HOOK_PRIO_INIT_I2C + 1); -int charger_discharge_on_ac(int enable) +static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable) { int rv; int control1; mutex_lock(&control1_mutex); - rv = raw_read16(ISL923X_REG_CONTROL1, &control1); + rv = raw_read16(chgnum, ISL923X_REG_CONTROL1, &control1); if (rv) goto out; @@ -481,7 +492,7 @@ int charger_discharge_on_ac(int enable) else control1 &= ~ISL923X_C1_LEARN_MODE_ENABLE; - rv = raw_write16(ISL923X_REG_CONTROL1, control1); + rv = raw_write16(chgnum, ISL923X_REG_CONTROL1, control1); learn_mode = !rv && enable; @@ -494,11 +505,11 @@ out: /* Hardware current ramping */ #ifdef CONFIG_CHARGE_RAMP_HW -int charger_set_hw_ramp(int enable) +static enum ec_error_list isl923x_set_hw_ramp(int chgnum, int enable) { int rv, reg; - rv = raw_read16(ISL923X_REG_CONTROL0, ®); + rv = raw_read16(chgnum, ISL923X_REG_CONTROL0, ®); if (rv) return rv; @@ -508,10 +519,10 @@ int charger_set_hw_ramp(int enable) else reg |= ISL923X_C0_DISABLE_VREG; - return raw_write16(ISL923X_REG_CONTROL0, reg); + return raw_write16(chgnum, ISL923X_REG_CONTROL0, reg); } -int chg_ramp_is_stable(void) +static int isl923x_ramp_is_stable(int chgnum) { /* * Since ISL cannot read the current limit that the ramp has settled @@ -521,12 +532,12 @@ int chg_ramp_is_stable(void) return 0; } -int chg_ramp_is_detected(void) +static int isl923x_ramp_is_detected(int chgnum) { return 1; } -int chg_ramp_get_current_limit(void) +static int isl923x_ramp_get_current_limit(int chgnum) { /* * ISL doesn't have a way to get this info, so return the nominal @@ -534,7 +545,7 @@ int chg_ramp_get_current_limit(void) */ int input_current; - if (charger_get_input_current(&input_current) != EC_SUCCESS) + if (isl923x_get_input_current(chgnum, &input_current) != EC_SUCCESS) return 0; return input_current; } @@ -543,7 +554,10 @@ int chg_ramp_get_current_limit(void) #ifdef CONFIG_CHARGER_PSYS static int psys_enabled; - +/* + * TODO(b/147440290): Set to appropriate charger with multiple charger support, + * hardcode to 0 for now + */ static void charger_enable_psys(void) { int val; @@ -553,12 +567,12 @@ static void charger_enable_psys(void) /* * enable system power monitor PSYS function */ - if (raw_read16(ISL923X_REG_CONTROL1, &val)) + if (raw_read16(CHARGER_SOLO, ISL923X_REG_CONTROL1, &val)) goto out; val |= ISL923X_C1_ENABLE_PSYS; - if (raw_write16(ISL923X_REG_CONTROL1, val)) + if (raw_write16(CHARGER_SOLO, ISL923X_REG_CONTROL1, val)) goto out; psys_enabled = 1; @@ -577,12 +591,12 @@ static void charger_disable_psys(void) /* * disable system power monitor PSYS function */ - if (raw_read16(ISL923X_REG_CONTROL1, &val)) + if (raw_read16(CHARGER_SOLO, ISL923X_REG_CONTROL1, &val)) goto out; val &= ~ISL923X_C1_ENABLE_PSYS; - if (raw_write16(ISL923X_REG_CONTROL1, val)) + if (raw_write16(CHARGER_SOLO, ISL923X_REG_CONTROL1, val)) goto out; psys_enabled = 0; @@ -628,14 +642,13 @@ DECLARE_CONSOLE_COMMAND(psys, console_command_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) +static int print_amon_bmon(int chgnum, 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, ®); + ret = raw_read16(chgnum, ISL9238_REG_CONTROL3, ®); if (ret) return ret; @@ -644,16 +657,14 @@ static int print_amon_bmon(enum amon_bmon amon, int 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); + ret = raw_write16(chgnum, 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, ®); + ret = raw_read16(chgnum, ISL923X_REG_CONTROL1, ®); if (!ret) { /* Switch between AMON/BMON */ if (amon == AMON) @@ -663,8 +674,7 @@ static int print_amon_bmon(enum amon_bmon amon, int direction, /* Enable monitor */ reg &= ~ISL923X_C1_DISABLE_MON; - ret = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, - ISL923X_REG_CONTROL1, reg); + ret = raw_write16(chgnum, ISL923X_REG_CONTROL1, reg); } mutex_unlock(&control1_mutex); @@ -690,6 +700,8 @@ static int console_command_amon_bmon(int argc, char **argv) int print_battery = 1; int print_charge = 1; int print_discharge = 1; + int chgnum = 0; + char *e; if (argc >= 2) { print_ac = (argv[1][0] == 'a'); @@ -700,15 +712,20 @@ static int console_command_amon_bmon(int argc, char **argv) print_discharge = (argv[1][1] == 'd'); } #endif + if (argc >= 3) { + chgnum = strtoi(argv[2], &e, 10); + if (*e) + return EC_ERROR_PARAM2; + } } if (print_ac) { if (print_charge) - ret |= print_amon_bmon(AMON, 0, + ret |= print_amon_bmon(chgnum, AMON, 0, CONFIG_CHARGER_SENSE_RESISTOR_AC); #ifdef CONFIG_CHARGER_ISL9238 if (print_discharge) - ret |= print_amon_bmon(AMON, 1, + ret |= print_amon_bmon(chgnum, AMON, 1, CONFIG_CHARGER_SENSE_RESISTOR_AC); #endif } @@ -716,7 +733,7 @@ static int console_command_amon_bmon(int argc, char **argv) if (print_battery) { #ifdef CONFIG_CHARGER_ISL9238 if (print_charge) - ret |= print_amon_bmon(BMON, 0, + ret |= print_amon_bmon(chgnum, BMON, 0, /* * charging current monitor has * 2x amplification factor @@ -724,7 +741,7 @@ static int console_command_amon_bmon(int argc, char **argv) 2*CONFIG_CHARGER_SENSE_RESISTOR); #endif if (print_discharge) - ret |= print_amon_bmon(BMON, 1, + ret |= print_amon_bmon(chgnum, BMON, 1, CONFIG_CHARGER_SENSE_RESISTOR); } @@ -732,15 +749,15 @@ static int console_command_amon_bmon(int argc, char **argv) } DECLARE_CONSOLE_COMMAND(amonbmon, console_command_amon_bmon, #ifdef CONFIG_CHARGER_ISL9237 - "amonbmon [a|b]", + "amonbmon [a|b] <chgnum>", #else - "amonbmon [a[c|d]|b[c|d]]", + "amonbmon [a[c|d]|b[c|d]] <chgnum>", #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) +static void dump_reg_range(int chgnum, int low, int high) { int reg; int regval; @@ -748,7 +765,8 @@ static void dump_reg_range(int low, int high) for (reg = low; reg <= high; reg++) { CPRINTF("[%Xh] = ", reg); - rv = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + rv = i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, reg, ®val); if (!rv) CPRINTF("0x%04x\n", regval); @@ -760,35 +778,35 @@ static void dump_reg_range(int low, int high) static int command_isl923x_dump(int argc, char **argv) { - dump_reg_range(0x14, 0x15); - dump_reg_range(0x38, 0x3F); - dump_reg_range(0x47, 0x4A); + int chgnum = 0; + char *e; + + if (argc >= 2) { + chgnum = strtoi(argv[1], &e, 10); + if (*e) + return EC_ERROR_PARAM1; + } + + dump_reg_range(chgnum, 0x14, 0x15); + dump_reg_range(chgnum, 0x38, 0x3F); + dump_reg_range(chgnum, 0x47, 0x4A); #if defined(CONFIG_CHARGER_ISL9238) || defined(CONFIG_CHARGER_RAA489000) - dump_reg_range(0x4B, 0x4E); + dump_reg_range(chgnum, 0x4B, 0x4E); #endif /* CONFIG_CHARGER_ISL9238 || CONFIG_CHARGER_RAA489000 */ - dump_reg_range(0xFE, 0xFF); + dump_reg_range(chgnum, 0xFE, 0xFF); return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(charger_dump, command_isl923x_dump, "", - "Dumps ISL923x registers"); +DECLARE_CONSOLE_COMMAND(charger_dump, command_isl923x_dump, + "charger_dump <chgnum>", "Dumps ISL923x registers"); #endif /* CONFIG_CMD_CHARGER_DUMP */ -int charger_get_vbus_voltage(int port) +static int isl923x_get_vbus_voltage(int chgnum, int port) { int val; int rv; - int i2c_port; - /* - * TODO(b:147440290): We should have a structure for charger ICs and - * consult that instead. This hack happens to work because the charger - * IC is also the TCPC. - */ - i2c_port = tcpc_config[port].i2c_info.port; - rv = i2c_read16(i2c_port, I2C_ADDR_CHARGER_FLAGS, - RAA489000_REG_ADC_VBUS, - &val); + rv = raw_read16(chgnum, RAA489000_REG_ADC_VBUS, &val); if (rv) return 0; @@ -799,3 +817,33 @@ int charger_get_vbus_voltage(int port) return val; } + +const struct charger_drv isl923x_drv = { + .init = &isl923x_init, + .post_init = &isl923x_post_init, + .get_info = &isl923x_get_info, + .get_status = &isl923x_get_status, + .set_mode = &isl923x_set_mode, +#if defined(CONFIG_CHARGER_OTG) && defined(CONFIG_CHARGER_ISL9238) + .enable_otg_power = &isl923x_enable_otg_power, + .set_otg_current_voltage = &isl923x_set_otg_current_voltage, +#endif + .get_current = &isl923x_get_current, + .set_current = &isl923x_set_current, + .get_voltage = &isl923x_get_voltage, + .set_voltage = &isl923x_set_voltage, + .discharge_on_ac = &isl923x_discharge_on_ac, + .get_vbus_voltage = &isl923x_get_vbus_voltage, + .set_input_current = &isl923x_set_input_current, + .get_input_current = &isl923x_get_input_current, + .manufacturer_id = &isl923x_manufacturer_id, + .device_id = &isl923x_device_id, + .get_option = &isl923x_get_option, + .set_option = &isl923x_set_option, +#ifdef CONFIG_CHARGE_RAMP_HW + .set_hw_ramp = &isl923x_set_hw_ramp, + .ramp_is_stable = &isl923x_ramp_is_stable, + .ramp_is_detected = &isl923x_ramp_is_detected, + .ramp_get_current_limit = &isl923x_ramp_get_current_limit, +#endif +}; diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h index 0f9605f2de..e4d6f72502 100644 --- a/driver/charger/isl923x.h +++ b/driver/charger/isl923x.h @@ -325,6 +325,9 @@ enum isl9237_fsm_state { #define INPUT_I_STEP 4 #define I2C_ADDR_CHARGER_FLAGS ISL923X_ADDR_FLAGS + +extern const struct charger_drv isl923x_drv; + #endif /* __CROS_EC_ISL923X_H */ /** diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c index ce40fac353..b21048fb84 100644 --- a/driver/charger/isl9241.c +++ b/driver/charger/isl9241.c @@ -58,22 +58,30 @@ static const struct charger_info isl9241_charger_info = { .input_current_step = INPUT_I_STEP, }; -static inline int isl9241_read(int offset, int *value) +static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable); + +static inline enum ec_error_list isl9241_read(int chgnum, int offset, + int *value) { - return i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_read16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static inline int isl9241_write(int offset, int value) +static inline enum ec_error_list isl9241_write(int chgnum, int offset, + int value) { - return i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_write16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, value); } -static inline int isl9241_update(int offset, uint16_t mask, - enum mask_update_action action) +static inline enum ec_error_list isl9241_update(int chgnum, int offset, + uint16_t mask, + enum mask_update_action action) { - return i2c_update16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER_FLAGS, + return i2c_update16(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, offset, mask, action); } @@ -81,23 +89,26 @@ static inline int isl9241_update(int offset, uint16_t mask, /*****************************************************************************/ /* Charger interfaces */ -int charger_set_input_current(int input_current) +static enum ec_error_list isl9241_set_input_current(int chgnum, + int input_current) { int rv; uint16_t reg = AC_CURRENT_TO_REG(input_current); - rv = isl9241_write(ISL9241_REG_ADAPTER_CUR_LIMIT1, reg); + rv = isl9241_write(chgnum, ISL9241_REG_ADAPTER_CUR_LIMIT1, reg); if (rv) return rv; - return isl9241_write(ISL9241_REG_ADAPTER_CUR_LIMIT2, reg); + return isl9241_write(chgnum, ISL9241_REG_ADAPTER_CUR_LIMIT2, reg); } -int charger_get_input_current(int *input_current) +static enum ec_error_list isl9241_get_input_current(int chgnum, + int *input_current) { int rv; - rv = isl9241_read(ISL9241_REG_ADAPTER_CUR_LIMIT1, input_current); + rv = isl9241_read(chgnum, ISL9241_REG_ADAPTER_CUR_LIMIT1, + input_current); if (rv) return rv; @@ -105,28 +116,28 @@ int charger_get_input_current(int *input_current) return EC_SUCCESS; } -int charger_manufacturer_id(int *id) +static enum ec_error_list isl9241_manufacturer_id(int chgnum, int *id) { - return isl9241_read(ISL9241_REG_MANUFACTURER_ID, id); + return isl9241_read(chgnum, ISL9241_REG_MANUFACTURER_ID, id); } -int charger_device_id(int *id) +static enum ec_error_list isl9241_device_id(int chgnum, int *id) { - return isl9241_read(ISL9241_REG_DEVICE_ID, id); + return isl9241_read(chgnum, ISL9241_REG_DEVICE_ID, id); } -int charger_get_option(int *option) +static enum ec_error_list isl9241_get_option(int chgnum, int *option) { int rv; uint32_t controls; int reg; - rv = isl9241_read(ISL9241_REG_CONTROL0, ®); + rv = isl9241_read(chgnum, ISL9241_REG_CONTROL0, ®); if (rv) return rv; controls = reg; - rv = isl9241_read(ISL9241_REG_CONTROL1, ®); + rv = isl9241_read(chgnum, ISL9241_REG_CONTROL1, ®); if (rv) return rv; @@ -135,23 +146,24 @@ int charger_get_option(int *option) return EC_SUCCESS; } -int charger_set_option(int option) +static enum ec_error_list isl9241_set_option(int chgnum, int option) { int rv; - rv = isl9241_write(ISL9241_REG_CONTROL0, option & 0xFFFF); + rv = isl9241_write(chgnum, ISL9241_REG_CONTROL0, option & 0xFFFF); if (rv) return rv; - return isl9241_write(ISL9241_REG_CONTROL1, (option >> 16) & 0xFFFF); + return isl9241_write(chgnum, ISL9241_REG_CONTROL1, + (option >> 16) & 0xFFFF); } -const struct charger_info *charger_get_info(void) +static const struct charger_info *isl9241_get_info(int chgnum) { return &isl9241_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list isl9241_get_status(int chgnum, int *status) { int rv; int reg; @@ -160,14 +172,14 @@ int charger_get_status(int *status) *status = CHARGER_LEVEL_2; /* Charge inhibit status */ - rv = isl9241_read(ISL9241_REG_MIN_SYSTEM_VOLTAGE, ®); + rv = isl9241_read(chgnum, 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, ®); + rv = isl9241_read(chgnum, ISL9241_REG_INFORMATION2, ®); if (rv) return rv; if (!(reg & ISL9241_INFORMATION2_BATGONE_PIN)) @@ -178,7 +190,7 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list isl9241_set_mode(int chgnum, int mode) { int rv; @@ -187,7 +199,7 @@ int charger_set_mode(int mode) * explicitly. */ if (!learn_mode) { - rv = charger_discharge_on_ac(0); + rv = isl9241_discharge_on_ac(chgnum, 0); if (rv) return rv; } @@ -196,7 +208,7 @@ int charger_set_mode(int mode) * Charger inhibit * MinSystemVoltage 0x00h = disables all battery charging */ - rv = isl9241_write(ISL9241_REG_MIN_SYSTEM_VOLTAGE, + rv = isl9241_write(chgnum, ISL9241_REG_MIN_SYSTEM_VOLTAGE, mode & CHARGE_FLAG_INHIBIT_CHARGE ? 0 : battery_get_info()->voltage_min); if (rv) @@ -204,18 +216,18 @@ int charger_set_mode(int mode) /* POR reset */ if (mode & CHARGE_FLAG_POR_RESET) { - rv = isl9241_write(ISL9241_REG_CONTROL3, + rv = isl9241_write(chgnum, ISL9241_REG_CONTROL3, ISL9241_CONTROL3_DIGITAL_RESET); } return rv; } -int charger_get_current(int *current) +static enum ec_error_list isl9241_get_current(int chgnum, int *current) { int rv; - rv = isl9241_read(ISL9241_REG_CHG_CURRENT_LIMIT, current); + rv = isl9241_read(chgnum, ISL9241_REG_CHG_CURRENT_LIMIT, current); if (rv) return rv; @@ -223,43 +235,43 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list isl9241_set_current(int chgnum, int current) { - return isl9241_write(ISL9241_REG_CHG_CURRENT_LIMIT, + return isl9241_write(chgnum, ISL9241_REG_CHG_CURRENT_LIMIT, BC_CURRENT_TO_REG(current)); } -int charger_get_voltage(int *voltage) +static enum ec_error_list isl9241_get_voltage(int chgnum, int *voltage) { - return isl9241_read(ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); + return isl9241_read(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); } -int charger_set_voltage(int voltage) +static enum ec_error_list isl9241_set_voltage(int chgnum, int voltage) { - return isl9241_write(ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); + return isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage); } -int charger_get_vbus_voltage(int port) +static int isl9241_get_vbus_voltage(int chgnum, int port) { int adc_val = 0; int ctl3_val; int rv; /* Get current Control3 value */ - rv = isl9241_read(ISL9241_REG_CONTROL3, &ctl3_val); + rv = isl9241_read(chgnum, ISL9241_REG_CONTROL3, &ctl3_val); if (rv) goto error; /* Enable ADC */ if (!(ctl3_val & ISL9241_CONTROL3_ENABLE_ADC)) { - rv = isl9241_write(ISL9241_REG_CONTROL3, + rv = isl9241_write(chgnum, 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); + rv = isl9241_read(chgnum, ISL9241_REG_VIN_ADC_RESULTS, &adc_val); if (rv) goto error_restore_ctl3; @@ -276,7 +288,7 @@ int charger_get_vbus_voltage(int port) error_restore_ctl3: /* Restore Control3 value */ if (!(ctl3_val & ISL9241_CONTROL3_ENABLE_ADC)) - (void)isl9241_write(ISL9241_REG_CONTROL3, ctl3_val); + (void)isl9241_write(chgnum, ISL9241_REG_CONTROL3, ctl3_val); error: if (rv) @@ -285,18 +297,18 @@ error: return adc_val; } -int charger_post_init(void) +static enum ec_error_list isl9241_post_init(int chgnum) { return EC_SUCCESS; } -int charger_discharge_on_ac(int enable) +static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable) { int rv; mutex_lock(&control1_mutex); - rv = isl9241_update(ISL9241_REG_CONTROL1, + rv = isl9241_update(chgnum, ISL9241_REG_CONTROL1, ISL9241_CONTROL1_LEARN_MODE, (enable) ? MASK_SET : MASK_CLR); if (!rv) @@ -308,7 +320,7 @@ int charger_discharge_on_ac(int enable) /*****************************************************************************/ /* ISL-9241 initialization */ -static void isl9241_init(void) +static void isl9241_init(int chgnum) { const struct battery_info *bi = battery_get_info(); @@ -316,14 +328,16 @@ static void isl9241_init(void) * Set the MaxSystemVoltage to battery maximum, * 0x00=disables switching charger states */ - if (isl9241_write(ISL9241_REG_MAX_SYSTEM_VOLTAGE, bi->voltage_max)) + if (isl9241_write(chgnum, 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)) + if (isl9241_write(chgnum, ISL9241_REG_MIN_SYSTEM_VOLTAGE, + bi->voltage_min)) goto init_fail; /* @@ -331,7 +345,7 @@ static void isl9241_init(void) * [15:13]: Trickle Charging Current (battery pre-charge current) * [10:9] : Prochot# Debounce time (1000us) */ - if (isl9241_update(ISL9241_REG_CONTROL2, + if (isl9241_update(chgnum, ISL9241_REG_CONTROL2, (ISL9241_CONTROL2_TRICKLE_CHG_CURR( bi->precharge_current) | ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000), @@ -342,13 +356,13 @@ static void isl9241_init(void) * Set control3 register to * [14]: ACLIM Reload (Do not reload) */ - if (isl9241_update(ISL9241_REG_CONTROL3, + if (isl9241_update(chgnum, ISL9241_REG_CONTROL3, ISL9241_CONTROL3_ACLIM_RELOAD, MASK_SET)) goto init_fail; #ifndef CONFIG_CHARGE_RAMP_HW - if (isl9241_update(ISL9241_REG_CONTROL0, + if (isl9241_update(chgnum, ISL9241_REG_CONTROL0, ISL9241_CONTROL0_INPUT_VTG_REGULATION, MASK_SET)) goto init_fail; @@ -362,7 +376,7 @@ static void isl9241_init(void) return; /* Initialize the input current limit to the board's default. */ - if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) + if (isl9241_set_input_current(chgnum, CONFIG_CHARGER_INPUT_CURRENT)) goto init_fail; return; @@ -370,21 +384,20 @@ static void isl9241_init(void) 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) +static enum ec_error_list isl9241_set_hw_ramp(int chgnum, int enable) { /* HW ramp is controlled by input voltage regulation reference bits */ - return isl9241_update(ISL9241_REG_CONTROL0, + return isl9241_update(chgnum, ISL9241_REG_CONTROL0, ISL9241_CONTROL0_INPUT_VTG_REGULATION, (enable) ? MASK_CLR : MASK_SET); } -int chg_ramp_is_stable(void) +static int isl9241_ramp_is_stable(int chgnum) { /* * Since ISL cannot read the current limit that the ramp has settled @@ -394,16 +407,16 @@ int chg_ramp_is_stable(void) return 0; } -int chg_ramp_is_detected(void) +static int isl9241_ramp_is_detected(int chgnum) { return 1; } -int chg_ramp_get_current_limit(void) +static int isl9241_ramp_get_current_limit(int chgnum) { int reg; - if (isl9241_read(ISL9241_REG_IADP_ADC_RESULTS, ®)) + if (isl9241_read(chgnum, ISL9241_REG_IADP_ADC_RESULTS, ®)) return 0; /* LSB value of register = 22.2mA */ @@ -413,7 +426,7 @@ int chg_ramp_get_current_limit(void) /*****************************************************************************/ #ifdef CONFIG_CMD_CHARGER_DUMP -static void dump_reg_range(int low, int high) +static void dump_reg_range(int chgnum, int low, int high) { int reg; int regval; @@ -421,7 +434,7 @@ static void dump_reg_range(int low, int high) for (reg = low; reg <= high; reg++) { CPRINTF("[%Xh] = ", reg); - rv = isl9241_read(reg, ®val); + rv = isl9241_read(chgnum, reg, ®val); if (!rv) CPRINTF("0x%04x\n", regval); else @@ -432,16 +445,52 @@ static void dump_reg_range(int low, int high) 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); + char *e; + int chgnum = 0; + + if (argc >= 2) { + chgnum = strtoi(argv[1], &e, 10); + if (*e) + return EC_ERROR_PARAM1; + } + + dump_reg_range(chgnum, 0x14, 0x15); + dump_reg_range(chgnum, 0x38, 0x40); + dump_reg_range(chgnum, 0x43, 0x43); + dump_reg_range(chgnum, 0x47, 0x4F); + dump_reg_range(chgnum, 0x80, 0x87); + dump_reg_range(chgnum, 0x90, 0x91); + dump_reg_range(chgnum, 0xFE, 0xFF); return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(charger_dump, command_isl9241_dump, "", +DECLARE_CONSOLE_COMMAND(charger_dump, command_isl9241_dump, + "charger_dump <chgnum>", "Dumps ISL9241 registers"); #endif /* CONFIG_CMD_CHARGER_DUMP */ + +const struct charger_drv isl9241_drv = { + .init = &isl9241_init, + .post_init = &isl9241_post_init, + .get_info = &isl9241_get_info, + .get_status = &isl9241_get_status, + .set_mode = &isl9241_set_mode, + .get_current = &isl9241_get_current, + .set_current = &isl9241_set_current, + .get_voltage = &isl9241_get_voltage, + .set_voltage = &isl9241_set_voltage, + .discharge_on_ac = &isl9241_discharge_on_ac, + .get_vbus_voltage = &isl9241_get_vbus_voltage, + .set_input_current = &isl9241_set_input_current, + .get_input_current = &isl9241_get_input_current, + .manufacturer_id = &isl9241_manufacturer_id, + .device_id = &isl9241_device_id, + .get_option = &isl9241_get_option, + .set_option = &isl9241_set_option, +#ifdef CONFIG_CHARGE_RAMP_HW + .set_hw_ramp = &isl9241_set_hw_ramp, + .ramp_is_stable = &isl9241_ramp_is_stable, + .ramp_is_detected = &isl9241_ramp_is_detected, + .ramp_get_current_limit = &isl9241_ramp_get_current_limit, +#endif +}; diff --git a/driver/charger/isl9241.h b/driver/charger/isl9241.h index b14c15f780..3e5c9ad749 100644 --- a/driver/charger/isl9241.h +++ b/driver/charger/isl9241.h @@ -9,7 +9,6 @@ #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 @@ -117,4 +116,6 @@ #define ISL9241_VIN_ADC_BIT_OFFSET 6 #define ISL9241_VIN_ADC_STEP_MV 96 +extern const struct charger_drv isl9241_drv; + #endif /* __CROS_EC_ISL9241_H */ diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c index 71ab72c818..1a2c8dedba 100644 --- a/driver/charger/rt946x.c +++ b/driver/charger/rt946x.c @@ -193,56 +193,67 @@ static const uint8_t rt946x_irq_maskall[RT946X_IRQ_COUNT] = { }; #endif +static enum ec_error_list rt946x_set_current(int chgnum, int current); +static enum ec_error_list rt946x_get_current(int chgnum, int *current); +static enum ec_error_list rt946x_set_voltage(int chgnum, int voltage); +static enum ec_error_list rt946x_enable_otg_power(int chgnum, int enabled); +static const struct charger_info *rt946x_get_info(int chgnum); + /* 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) +static enum ec_error_list rt946x_read8(int chgnum, int reg, int *val) { - return i2c_read8(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, reg, val); + return i2c_read8(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, reg, val); } -static int rt946x_write8(int reg, int val) +static enum ec_error_list rt946x_write8(int chgnum, int reg, int val) { - return i2c_write8(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, reg, val); + return i2c_write8(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, reg, val); } -static int rt946x_block_write(int reg, const uint8_t *val, int len) +static enum ec_error_list rt946x_block_write(int chgnum, int reg, + const uint8_t *val, int len) { - return i2c_write_block(I2C_PORT_CHARGER, RT946X_ADDR_FLAGS, + return i2c_write_block(chg_chips[chgnum].i2c_port, + chg_chips[chgnum].i2c_addr_flags, reg, val, len); } -static int rt946x_update_bits(int reg, int mask, int val) +static int rt946x_update_bits(int chgnum, int reg, int mask, int val) { int rv; int reg_val = 0; - rv = rt946x_read8(reg, ®_val); + rv = rt946x_read8(chgnum, reg, ®_val); if (rv) return rv; reg_val &= ~mask; reg_val |= (mask & val); - rv = rt946x_write8(reg, reg_val); + rv = rt946x_write8(chgnum, reg, reg_val); return rv; } -static inline int rt946x_set_bit(int reg, int mask) +static inline int rt946x_set_bit(int chgnum, int reg, int mask) { - return rt946x_update_bits(reg, mask, mask); + return rt946x_update_bits(chgnum, reg, mask, mask); } -static inline int rt946x_clr_bit(int reg, int mask) +static inline int rt946x_clr_bit(int chgnum, int reg, int mask) { - return rt946x_update_bits(reg, mask, 0x00); + return rt946x_update_bits(chgnum, reg, mask, 0x00); } -static inline int mt6370_pmu_reg_test_bit(int cmd, int shift, int *is_one) +static inline int mt6370_pmu_reg_test_bit(int chgnum, int cmd, int shift, + int *is_one) { int rv, data; - rv = rt946x_read8(cmd, &data); + rv = rt946x_read8(chgnum, cmd, &data); if (rv) { *is_one = 0; return rv; @@ -262,11 +273,11 @@ static inline uint8_t rt946x_closest_reg(uint16_t min, uint16_t max, return (target - min) / step; } -static int rt946x_get_ieoc(uint32_t *ieoc) +static int rt946x_get_ieoc(int chgnum, uint32_t *ieoc) { int ret, reg_ieoc; - ret = rt946x_read8(RT946X_REG_CHGCTRL9, ®_ieoc); + ret = rt946x_read8(chgnum, RT946X_REG_CHGCTRL9, ®_ieoc); if (ret) return ret; @@ -278,7 +289,7 @@ static int rt946x_get_ieoc(uint32_t *ieoc) } #ifdef CONFIG_CHARGER_MT6370 -static int mt6370_enable_hidden_mode(int en) +static int mt6370_enable_hidden_mode(int chgnum, int en) { int rv = 0; @@ -290,7 +301,8 @@ static int mt6370_enable_hidden_mode(int en) mutex_lock(&hidden_mode_lock); if (en) { if (hidden_mode_cnt == 0) { - rv = rt946x_block_write(mt6370_reg_en_hidden_mode[0], + rv = rt946x_block_write(chgnum, + mt6370_reg_en_hidden_mode[0], mt6370_val_en_hidden_mode, ARRAY_SIZE(mt6370_val_en_hidden_mode)); if (rv) @@ -299,7 +311,8 @@ static int mt6370_enable_hidden_mode(int en) hidden_mode_cnt++; } else { if (hidden_mode_cnt == 1) /* last one */ - rv = rt946x_write8(mt6370_reg_en_hidden_mode[0], 0x00); + rv = rt946x_write8(chgnum, mt6370_reg_en_hidden_mode[0], + 0x00); hidden_mode_cnt--; if (rv) goto out; @@ -323,7 +336,7 @@ out: * 2. forbids Ichg <= 400mA (this is done natually on mt6370, since mt6370's * minimum current is 512) */ -static int mt6370_ichg_workaround(int new_ichg) +static int mt6370_ichg_workaround(int chgnum, int new_ichg) { int rv = EC_SUCCESS; int curr_ichg; @@ -336,39 +349,39 @@ static int mt6370_ichg_workaround(int new_ichg) if (!IS_ENABLED(CONFIG_CHARGER_MT6370)) return EC_SUCCESS; - rv = charger_get_current(&curr_ichg); + rv = rt946x_get_current(chgnum, &curr_ichg); if (rv) return rv; - mt6370_enable_hidden_mode(1); + mt6370_enable_hidden_mode(chgnum, 1); /* disable Vsys protect if if the new ichg is below 900mA */ if (curr_ichg >= 900 && new_ichg < 900) - rv = rt946x_update_bits(RT946X_REG_CHGHIDDENCTRL7, + rv = rt946x_update_bits(chgnum, RT946X_REG_CHGHIDDENCTRL7, RT946X_MASK_HIDDENCTRL7_VSYS_PROTECT, 0); /* enable Vsys protect if the new ichg is above 900mA */ else if (new_ichg >= 900 && curr_ichg < 900) - rv = rt946x_update_bits(RT946X_REG_CHGHIDDENCTRL7, + rv = rt946x_update_bits(chgnum, RT946X_REG_CHGHIDDENCTRL7, RT946X_MASK_HIDDENCTRL7_VSYS_PROTECT, RT946X_ENABLE_VSYS_PROTECT); - mt6370_enable_hidden_mode(0); + mt6370_enable_hidden_mode(chgnum, 0); return rv; } #endif /* CONFIG_CHARGER_MT6370 */ -static inline int rt946x_enable_wdt(int en) +static inline int rt946x_enable_wdt(int chgnum, int en) { return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL13, RT946X_MASK_WDT_EN); + (chgnum, RT946X_REG_CHGCTRL13, RT946X_MASK_WDT_EN); } /* Enable high-impedance mode */ -static inline int rt946x_enable_hz(int en) +static inline int rt946x_enable_hz(int chgnum, int en) { return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL1, RT946X_MASK_HZ_EN); + (chgnum, RT946X_REG_CHGCTRL1, RT946X_MASK_HZ_EN); } int rt946x_por_reset(void) @@ -382,35 +395,37 @@ int rt946x_por_reset(void) * 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); + rv = rt946x_write8(CHARGER_SOLO, MT6370_REG_RSTPASCODE1, + MT6370_MASK_RSTPASCODE1); + rv |= rt946x_write8(CHARGER_SOLO, MT6370_REG_RSTPASCODE2, + MT6370_MASK_RSTPASCODE2); #else /* Hard reset, may take several milliseconds. */ val = RT946X_MASK_RST; - rv = rt946x_enable_hz(0); + rv = rt946x_enable_hz(CHARGER_SOLO, 0); #endif if (rv) return rv; - return rt946x_set_bit(RT946X_REG_CORECTRL_RST, val); + return rt946x_set_bit(CHARGER_SOLO, RT946X_REG_CORECTRL_RST, val); } -static int rt946x_reset_to_zero(void) +static int rt946x_reset_to_zero(int chgnum) { int rv; - rv = charger_set_current(0); + rv = rt946x_set_current(chgnum, 0); if (rv) return rv; - rv = charger_set_voltage(0); + rv = rt946x_set_voltage(chgnum, 0); if (rv) return rv; - return rt946x_enable_hz(1); + return rt946x_enable_hz(chgnum, 1); } -static int rt946x_enable_bc12_detection(int en) +static int rt946x_enable_bc12_detection(int chgnum, int en) { #if defined(CONFIG_CHARGER_RT9467) || defined(CONFIG_CHARGER_MT6370) int rv; @@ -419,10 +434,11 @@ static int rt946x_enable_bc12_detection(int 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); + return rt946x_set_bit(chgnum, RT946X_REG_DPDM1, + RT946X_MASK_USBCHGEN); } - rv = rt946x_clr_bit(RT946X_REG_DPDM1, RT946X_MASK_USBCHGEN); + rv = rt946x_clr_bit(chgnum, 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 */ @@ -431,7 +447,7 @@ static int rt946x_enable_bc12_detection(int en) return 0; } -static int rt946x_set_ieoc(unsigned int ieoc) +static int rt946x_set_ieoc(int chgnum, unsigned int ieoc) { uint8_t reg_ieoc; @@ -440,11 +456,11 @@ static int rt946x_set_ieoc(unsigned int ieoc) CPRINTS("ieoc=%d", ieoc); - return rt946x_update_bits(RT946X_REG_CHGCTRL9, RT946X_MASK_IEOC, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL9, RT946X_MASK_IEOC, reg_ieoc << RT946X_SHIFT_IEOC); } -static int rt946x_set_mivr(unsigned int mivr) +static int rt946x_set_mivr(int chgnum, unsigned int mivr) { uint8_t reg_mivr = 0; @@ -453,11 +469,11 @@ static int rt946x_set_mivr(unsigned int mivr) CPRINTS("mivr=%d", mivr); - return rt946x_update_bits(RT946X_REG_CHGCTRL6, RT946X_MASK_MIVR, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL6, RT946X_MASK_MIVR, reg_mivr << RT946X_SHIFT_MIVR); } -static int rt946x_set_boost_voltage(unsigned int voltage) +static int rt946x_set_boost_voltage(int chgnum, unsigned int voltage) { uint8_t reg_voltage = 0; @@ -466,12 +482,12 @@ static int rt946x_set_boost_voltage(unsigned int voltage) CPRINTS("voltage=%d", voltage); - return rt946x_update_bits(RT946X_REG_CHGCTRL5, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL5, RT946X_MASK_BOOST_VOLTAGE, reg_voltage << RT946X_SHIFT_BOOST_VOLTAGE); } -static int rt946x_set_boost_current(unsigned int current) +static int rt946x_set_boost_current(int chgnum, unsigned int current) { int i; @@ -487,12 +503,12 @@ static int rt946x_set_boost_current(unsigned int current) CPRINTS("current=%d", current); - return rt946x_update_bits(RT946X_REG_CHGCTRL10, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL10, RT946X_MASK_BOOST_CURRENT, i << RT946X_SHIFT_BOOST_CURRENT); } -static int rt946x_set_ircmp_vclamp(unsigned int vclamp) +static int rt946x_set_ircmp_vclamp(int chgnum, unsigned int vclamp) { uint8_t reg_vclamp = 0; @@ -501,12 +517,12 @@ static int rt946x_set_ircmp_vclamp(unsigned int vclamp) CPRINTS("vclamp=%d", vclamp); - return rt946x_update_bits(RT946X_REG_CHGCTRL18, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL18, RT946X_MASK_IRCMP_VCLAMP, reg_vclamp << RT946X_SHIFT_IRCMP_VCLAMP); } -static int rt946x_set_ircmp_res(unsigned int res) +static int rt946x_set_ircmp_res(int chgnum, unsigned int res) { uint8_t reg_res = 0; @@ -515,11 +531,12 @@ static int rt946x_set_ircmp_res(unsigned int res) CPRINTS("res=%d", res); - return rt946x_update_bits(RT946X_REG_CHGCTRL18, RT946X_MASK_IRCMP_RES, - reg_res << RT946X_SHIFT_IRCMP_RES); + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL18, + RT946X_MASK_IRCMP_RES, + reg_res << RT946X_SHIFT_IRCMP_RES); } -static int rt946x_set_vprec(unsigned int vprec) +static int rt946x_set_vprec(int chgnum, unsigned int vprec) { uint8_t reg_vprec = 0; @@ -528,11 +545,12 @@ static int rt946x_set_vprec(unsigned int vprec) CPRINTS("vprec=%d", vprec); - return rt946x_update_bits(RT946X_REG_CHGCTRL8, RT946X_MASK_VPREC, - reg_vprec << RT946X_SHIFT_VPREC); + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL8, + RT946X_MASK_VPREC, + reg_vprec << RT946X_SHIFT_VPREC); } -static int rt946x_set_iprec(unsigned int iprec) +static int rt946x_set_iprec(int chgnum, unsigned int iprec) { uint8_t reg_iprec = 0; @@ -541,35 +559,36 @@ static int rt946x_set_iprec(unsigned int iprec) CPRINTS("iprec=%d", iprec); - return rt946x_update_bits(RT946X_REG_CHGCTRL8, RT946X_MASK_IPREC, - reg_iprec << RT946X_SHIFT_IPREC); + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL8, + RT946X_MASK_IPREC, + reg_iprec << RT946X_SHIFT_IPREC); } -static int rt946x_init_irq(void) +static int rt946x_init_irq(int chgnum) { int rv = 0; int dummy; int i; /* Mask all interrupts */ - rv = rt946x_block_write(RT946X_REG_CHGSTATCCTRL, rt946x_irq_maskall, - RT946X_IRQ_COUNT); + rv = rt946x_block_write(chgnum, 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); + rv = rt946x_read8(chgnum, RT946X_REG_CHGSTATC + i, &dummy); if (rv) return rv; } /* Init interrupt */ - return rt946x_block_write(RT946X_REG_CHGSTATCCTRL, rt946x_irqmask, - ARRAY_SIZE(rt946x_irqmask)); + return rt946x_block_write(chgnum, RT946X_REG_CHGSTATCCTRL, + rt946x_irqmask, ARRAY_SIZE(rt946x_irqmask)); } -static int rt946x_init_setting(void) +static int rt946x_init_setting(int chgnum) { int rv = 0; const struct battery_info *batt_info = battery_get_info(); @@ -577,89 +596,91 @@ static int rt946x_init_setting(void) #ifdef CONFIG_CHARGER_OTG /* Disable boost-mode output voltage */ - rv = charger_enable_otg_power(0); + rv = rt946x_enable_otg_power(chgnum, 0); if (rv) return rv; #endif /* Disable BC 1.2 detection by default. It will be enabled on demand */ - rv = rt946x_enable_bc12_detection(0); + rv = rt946x_enable_bc12_detection(chgnum, 0); if (rv) return rv; /* Disable WDT */ - rv = rt946x_enable_wdt(0); + rv = rt946x_enable_wdt(chgnum, 0); if (rv) return rv; /* Disable battery thermal protection */ - rv = rt946x_clr_bit(RT946X_REG_CHGCTRL16, RT946X_MASK_JEITA_EN); + rv = rt946x_clr_bit(chgnum, 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); + rv = rt946x_clr_bit(chgnum, RT946X_REG_CHGCTRL12, RT946X_MASK_TMR_EN); if (rv) return rv; - rv = rt946x_set_mivr(setting->mivr); + rv = rt946x_set_mivr(chgnum, setting->mivr); if (rv) return rv; - rv = rt946x_set_ieoc(setting->eoc_current); + rv = rt946x_set_ieoc(chgnum, setting->eoc_current); if (rv) return rv; - rv = rt946x_set_boost_voltage( + rv = rt946x_set_boost_voltage(chgnum, setting->boost_voltage); if (rv) return rv; - rv = rt946x_set_boost_current( + rv = rt946x_set_boost_current(chgnum, setting->boost_current); if (rv) return rv; - rv = rt946x_set_ircmp_vclamp(setting->ircmp_vclamp); + rv = rt946x_set_ircmp_vclamp(chgnum, setting->ircmp_vclamp); if (rv) return rv; - rv = rt946x_set_ircmp_res(setting->ircmp_res); + rv = rt946x_set_ircmp_res(chgnum, setting->ircmp_res); if (rv) return rv; - rv = rt946x_set_vprec(batt_info->precharge_voltage ? + rv = rt946x_set_vprec(chgnum, batt_info->precharge_voltage ? batt_info->precharge_voltage : batt_info->voltage_min); if (rv) return rv; - rv = rt946x_set_iprec(batt_info->precharge_current); + rv = rt946x_set_iprec(chgnum, batt_info->precharge_current); if (rv) return rv; #ifdef CONFIG_CHARGER_MT6370_BACKLIGHT - rt946x_write8(MT6370_BACKLIGHT_BLEN, + rt946x_write8(chgnum, 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, + rt946x_update_bits(chgnum, MT6370_BACKLIGHT_BLPWM, + MT6370_MASK_BLPWM_BLED_PWM, BIT(MT6370_SHIFT_BLPWM_BLED_PWM)); #endif - return rt946x_init_irq(); + return rt946x_init_irq(chgnum); } #ifdef CONFIG_CHARGER_OTG -int charger_enable_otg_power(int enabled) +static enum ec_error_list rt946x_enable_otg_power(int chgnum, int enabled) { return (enabled ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL1, RT946X_MASK_OPA_MODE); + (chgnum, RT946X_REG_CHGCTRL1, RT946X_MASK_OPA_MODE); } int charger_is_sourcing_otg_power(int port) { int val; - if (rt946x_read8(RT946X_REG_CHGCTRL1, &val)) + if (rt946x_read8(CHARGER_SOLO, RT946X_REG_CHGCTRL1, &val)) return 0; return !!(val & RT946X_MASK_OPA_MODE); } #endif -int charger_set_input_current(int input_current) +static enum ec_error_list rt946x_set_input_current(int chgnum, + int input_current) { uint8_t reg_iin = 0; - const struct charger_info * const info = charger_get_info(); + const struct charger_info * const info = rt946x_get_info(chgnum); reg_iin = rt946x_closest_reg(info->input_current_min, info->input_current_max, info->input_current_step, @@ -667,17 +688,18 @@ int charger_set_input_current(int input_current) CPRINTS("iin=%d", input_current); - return rt946x_update_bits(RT946X_REG_CHGCTRL3, RT946X_MASK_AICR, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL3, RT946X_MASK_AICR, reg_iin << RT946X_SHIFT_AICR); } -int charger_get_input_current(int *input_current) +static enum ec_error_list rt946x_get_input_current(int chgnum, + int *input_current) { int rv; int val = 0; - const struct charger_info * const info = charger_get_info(); + const struct charger_info * const info = rt946x_get_info(chgnum); - rv = rt946x_read8(RT946X_REG_CHGCTRL3, &val); + rv = rt946x_read8(chgnum, RT946X_REG_CHGCTRL3, &val); if (rv) return rv; @@ -688,59 +710,59 @@ int charger_get_input_current(int *input_current) return EC_SUCCESS; } -int charger_manufacturer_id(int *id) +static enum ec_error_list rt946x_manufacturer_id(int chgnum, int *id) { return EC_ERROR_UNIMPLEMENTED; } -int charger_device_id(int *id) +static enum ec_error_list rt946x_device_id(int chgnum, int *id) { int rv; - rv = rt946x_read8(RT946X_REG_DEVICEID, id); + rv = rt946x_read8(chgnum, RT946X_REG_DEVICEID, id); if (rv == EC_SUCCESS) *id &= RT946X_MASK_VENDOR_ID; return rv; } -int charger_get_option(int *option) +static enum ec_error_list rt946x_get_option(int chgnum, int *option) { /* Ignored: does not exist */ *option = 0; return EC_SUCCESS; } -int charger_set_option(int option) +static enum ec_error_list rt946x_set_option(int chgnum, int option) { /* Ignored: does not exist */ return EC_SUCCESS; } -const struct charger_info *charger_get_info(void) +static const struct charger_info *rt946x_get_info(int chgnum) { return &rt946x_charger_info; } -int charger_get_status(int *status) +static enum ec_error_list rt946x_get_status(int chgnum, int *status) { int rv; int val = 0; - rv = rt946x_read8(RT946X_REG_CHGCTRL2, &val); + rv = rt946x_read8(chgnum, 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); + rv = rt946x_read8(chgnum, 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); + rv = rt946x_read8(chgnum, RT946X_REG_CHGNTC, &val); if (rv) return rv; val = (val & RT946X_MASK_BATNTC_FAULT) >> RT946X_SHIFT_BATNTC_FAULT; @@ -767,7 +789,7 @@ int charger_get_status(int *status) return EC_SUCCESS; } -int charger_set_mode(int mode) +static enum ec_error_list rt946x_set_mode(int chgnum, int mode) { int rv; @@ -778,7 +800,7 @@ int charger_set_mode(int mode) } if (mode & CHARGE_FLAG_RESET_TO_ZERO) { - rv = rt946x_reset_to_zero(); + rv = rt946x_reset_to_zero(chgnum); if (rv) return rv; } @@ -786,13 +808,13 @@ int charger_set_mode(int mode) return EC_SUCCESS; } -int charger_get_current(int *current) +static enum ec_error_list rt946x_get_current(int chgnum, int *current) { int rv; int val = 0; - const struct charger_info * const info = charger_get_info(); + const struct charger_info * const info = rt946x_get_info(chgnum); - rv = rt946x_read8(RT946X_REG_CHGCTRL7, &val); + rv = rt946x_read8(chgnum, RT946X_REG_CHGCTRL7, &val); if (rv) return rv; @@ -802,22 +824,22 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +static enum ec_error_list rt946x_set_current(int chgnum, int current) { int rv; uint8_t reg_icc; static int workaround; - const struct charger_info *const info = charger_get_info(); + const struct charger_info *const info = rt946x_get_info(chgnum); /* - * mt6370's minimun regulated current is 500mA REG17[7:2] 0b100, + * mt6370's minimum regulated current is 500mA REG17[7:2] 0b100, * values below 0b100 are preserved. */ if (IS_ENABLED(CONFIG_CHARGER_MT6370)) current = MAX(500, current); #ifdef CONFIG_CHARGER_MT6370 - rv = mt6370_ichg_workaround(current); + rv = mt6370_ichg_workaround(chgnum, current); if (rv) return rv; #endif @@ -825,7 +847,7 @@ int charger_set_current(int 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, + rv = rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL7, RT946X_MASK_ICHG, reg_icc << RT946X_SHIFT_ICHG); if (rv) return rv; @@ -841,31 +863,31 @@ int charger_set_current(int current) * the power path will only be partially turned on. So under * such situation, the IEOC is inaccurate. */ - rv = rt946x_get_ieoc(&curr_ieoc); + rv = rt946x_get_ieoc(chgnum, &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); + rv = rt946x_set_ieoc(chgnum, 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); + rv = rt946x_set_ieoc(chgnum, curr_ieoc - 100); } } return rv; } -int charger_get_voltage(int *voltage) +static enum ec_error_list rt946x_get_voltage(int chgnum, int *voltage) { int rv; int val = 0; - const struct charger_info * const info = charger_get_info(); + const struct charger_info * const info = rt946x_get_info(chgnum); - rv = rt946x_read8(RT946X_REG_CHGCTRL4, &val); + rv = rt946x_read8(chgnum, RT946X_REG_CHGCTRL4, &val); if (rv) return rv; @@ -875,53 +897,54 @@ int charger_get_voltage(int *voltage) return EC_SUCCESS; } -int charger_set_voltage(int voltage) +static enum ec_error_list rt946x_set_voltage(int chgnum, int voltage) { uint8_t reg_cv = 0; - const struct charger_info * const info = charger_get_info(); + const struct charger_info * const info = rt946x_get_info(chgnum); 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, + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL4, RT946X_MASK_CV, reg_cv << RT946X_SHIFT_CV); } -int charger_discharge_on_ac(int enable) +static enum ec_error_list rt946x_discharge_on_ac(int chgnum, int enable) { - return rt946x_enable_hz(enable); + return rt946x_enable_hz(chgnum, enable); } /* Setup sourcing current to prevent overload */ #ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED -static int rt946x_enable_ilim_pin(int en) +static int rt946x_enable_ilim_pin(int chgnum, int en) { int ret; ret = (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL3, RT946X_MASK_ILIMEN); + (chgnum, RT946X_REG_CHGCTRL3, RT946X_MASK_ILIMEN); return ret; } -static int rt946x_select_ilmt(enum rt946x_ilmtsel sel) +static int rt946x_select_ilmt(int chgnum, enum rt946x_ilmtsel sel) { int ret; - ret = rt946x_update_bits(RT946X_REG_CHGCTRL2, RT946X_MASK_ILMTSEL, - sel << RT946X_SHIFT_ILMTSEL); + ret = rt946x_update_bits(chgnum, 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) +static enum ec_error_list rt946x_post_init(int chgnum) { #ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED int rv; - rv = rt946x_select_ilmt(RT946X_ILMTSEL_AICR); + rv = rt946x_select_ilmt(chgnum, RT946X_ILMTSEL_AICR); if (rv) return rv; @@ -929,7 +952,7 @@ int charger_post_init(void) msleep(5); /* Disable ILIM pin */ - rv = rt946x_enable_ilim_pin(0); + rv = rt946x_enable_ilim_pin(chgnum, 0); if (rv) return rv; #endif @@ -938,12 +961,12 @@ int charger_post_init(void) /* Hardware current ramping (aka AICL: Average Input Current Level) */ #ifdef CONFIG_CHARGE_RAMP_HW -static int rt946x_get_mivr(int *mivr) +static int rt946x_get_mivr(int chgnum, int *mivr) { int rv; int val = 0; - rv = rt946x_read8(RT946X_REG_CHGCTRL6, &val); + rv = rt946x_read8(chgnum, RT946X_REG_CHGCTRL6, &val); if (rv) return rv; @@ -953,28 +976,30 @@ static int rt946x_get_mivr(int *mivr) return EC_SUCCESS; } -static int rt946x_set_aicl_vth(uint8_t aicl_vth) +static int rt946x_set_aicl_vth(int chgnum, 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); + return rt946x_update_bits(chgnum, RT946X_REG_CHGCTRL14, + RT946X_MASK_AICLVTH, + reg_aicl_vth << RT946X_SHIFT_AICLVTH); } -int charger_set_hw_ramp(int enable) +static enum ec_error_list rt946x_set_hw_ramp(int chgnum, int enable) { int rv; unsigned int mivr = 0; if (!enable) { - rv = rt946x_clr_bit(RT946X_REG_CHGCTRL14, RT946X_MASK_AICLMEAS); + rv = rt946x_clr_bit(chgnum, RT946X_REG_CHGCTRL14, + RT946X_MASK_AICLMEAS); return rv; } - rv = rt946x_get_mivr(&mivr); + rv = rt946x_get_mivr(chgnum, &mivr); if (rv < 0) return rv; @@ -987,51 +1012,51 @@ int charger_set_hw_ramp(int enable) return EC_ERROR_INVAL; } - rv = rt946x_set_aicl_vth(mivr + 200); + rv = rt946x_set_aicl_vth(chgnum, mivr + 200); if (rv < 0) return rv; - return rt946x_set_bit(RT946X_REG_CHGCTRL14, RT946X_MASK_AICLMEAS); + return rt946x_set_bit(chgnum, RT946X_REG_CHGCTRL14, + RT946X_MASK_AICLMEAS); } -int chg_ramp_is_stable(void) +static int rt946x_ramp_is_stable(int chgnum) { int rv; int val = 0; - rv = rt946x_read8(RT946X_REG_CHGCTRL14, &val); + rv = rt946x_read8(chgnum, RT946X_REG_CHGCTRL14, &val); val = (val & RT946X_MASK_AICLMEAS) >> RT946X_SHIFT_AICLMEAS; return (!rv && !val); } -int chg_ramp_is_detected(void) +static int rt946x_ramp_is_detected(int chgnum) { return 1; } -int chg_ramp_get_current_limit(void) +static int rt946x_ramp_get_current_limit(int chgnum) { int rv; int input_current = 0; - rv = charger_get_input_current(&input_current); + rv = rt946x_get_input_current(chgnum, &input_current); return rv ? -1 : input_current; } #endif /* CONFIG_CHARGE_RAMP_HW */ -static void rt946x_init(void) +static void rt946x_init(int chgnum) { - int ret = rt946x_init_setting(); + int ret = rt946x_init_setting(chgnum); - CPRINTS("init %s(%d)", ret ? "fail" : "good", ret); + CPRINTS("init%d %s(%d)", chgnum, ret ? "fail" : "good", ret); } -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) +static int mt6370_detect_apple_samsung_ta(int chgnum, int usb_stat) { int ret, reg; int chg_type = @@ -1050,9 +1075,10 @@ static int mt6370_detect_apple_samsung_ta(int usb_stat) return chg_type; /* Check D+ > 0.9V */ - ret = rt946x_update_bits(MT6370_REG_QCSTATUS2, MT6360_MASK_CHECK_DPDM, + ret = rt946x_update_bits(chgnum, MT6370_REG_QCSTATUS2, + MT6360_MASK_CHECK_DPDM, MT6370_MASK_APP_SS_EN | MT6370_MASK_APP_SS_PL); - ret |= rt946x_read8(MT6370_REG_QCSTATUS2, ®); + ret |= rt946x_read8(chgnum, MT6370_REG_QCSTATUS2, ®); if (ret) return chg_type; @@ -1066,18 +1092,19 @@ static int mt6370_detect_apple_samsung_ta(int usb_stat) 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, ®); + ret = rt946x_update_bits(chgnum, MT6370_REG_QCSTATUS2, + MT6360_MASK_CHECK_DPDM, + MT6370_MASK_APP_REF | MT6370_MASK_APP_SS_PL | + MT6370_MASK_APP_SS_EN); + ret |= rt946x_read8(chgnum, MT6370_REG_QCSTATUS2, ®); dp_2_3v = reg & MT6370_MASK_APP_OUT; /* Check D- > 2.3 V */ - ret |= rt946x_update_bits( + ret |= rt946x_update_bits(chgnum, 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, ®); + ret |= rt946x_read8(chgnum, MT6370_REG_QCSTATUS2, ®); dm_2_3v = reg & MT6370_MASK_APP_OUT; if (ret) @@ -1120,14 +1147,14 @@ static int mt6370_get_bc12_device_type(int charger_type) } /* Returns a mt6370 charger_type. */ -static int mt6370_get_charger_type(void) +static int mt6370_get_charger_type(int chgnum) { #ifdef CONFIG_CHARGER_MT6370 int reg; - if (rt946x_read8(MT6370_REG_USBSTATUS1, ®)) + if (rt946x_read8(chgnum, MT6370_REG_USBSTATUS1, ®)) return CHARGE_SUPPLIER_NONE; - return mt6370_detect_apple_samsung_ta(reg); + return mt6370_detect_apple_samsung_ta(chgnum, reg); #else return CHARGE_SUPPLIER_NONE; #endif @@ -1162,11 +1189,11 @@ static int mt6370_get_bc12_ilim(int charge_supplier) } } -static int rt946x_get_bc12_device_type(int charger_type) +static int rt946x_get_bc12_device_type(int chgnum, int charger_type) { int reg; - if (rt946x_read8(RT946X_REG_DPDM1, ®)) + if (rt946x_read8(chgnum, RT946X_REG_DPDM1, ®)) return CHARGE_SUPPLIER_NONE; switch (reg & RT946X_MASK_BC12_TYPE) { @@ -1224,12 +1251,12 @@ void rt946x_interrupt(enum gpio_signal signal) int rt946x_toggle_bc12_detection(void) { int rv; - rv = rt946x_enable_bc12_detection(0); + rv = rt946x_enable_bc12_detection(CHARGER_SOLO, 0); if (rv) return rv; /* mt6370 requires 40us delay to toggle RT946X_MASK_USBCHGEN */ udelay(40); - return rt946x_enable_bc12_detection(1); + return rt946x_enable_bc12_detection(CHARGER_SOLO, 1); } static void check_pd_capable(void) @@ -1288,12 +1315,13 @@ int rt946x_get_adc(enum rt946x_adc_in_sel adc_sel, int *adc_val) } mutex_lock(&adc_access_lock); #ifdef CONFIG_CHARGER_MT6370 - mt6370_enable_hidden_mode(1); + mt6370_enable_hidden_mode(CHARGER_SOLO, 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); + rv = rt946x_update_bits(CHARGER_SOLO, RT946X_REG_CHGADC, + RT946X_MASK_ADC_IN_SEL, + adc_sel << RT946X_SHIFT_ADC_IN_SEL); if (rv) goto out; @@ -1304,13 +1332,14 @@ int rt946x_get_adc(enum rt946x_adc_in_sel adc_sel, int *adc_val) } /* Start ADC conversation */ - rv = rt946x_set_bit(RT946X_REG_CHGADC, RT946X_MASK_ADC_START); + rv = rt946x_set_bit(CHARGER_SOLO, 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, + rv = mt6370_pmu_reg_test_bit(CHARGER_SOLO, RT946X_REG_CHGADC, RT946X_SHIFT_ADC_START, &adc_start); if (!adc_start && rv == 0) @@ -1320,8 +1349,8 @@ int rt946x_get_adc(enum rt946x_adc_in_sel adc_sel, int *adc_val) CPRINTS("conversion fail sel=%d", adc_sel); /* Read ADC data */ - rv = rt946x_read8(RT946X_REG_ADCDATAH, &adc_data_h); - rv = rt946x_read8(RT946X_REG_ADCDATAL, &adc_data_l); + rv = rt946x_read8(CHARGER_SOLO, RT946X_REG_ADCDATAH, &adc_data_h); + rv = rt946x_read8(CHARGER_SOLO, RT946X_REG_ADCDATAL, &adc_data_l); if (rv) goto out; @@ -1352,13 +1381,13 @@ out: *adc_val = adc_result / 1000; else *adc_val = adc_result; - mt6370_enable_hidden_mode(0); + mt6370_enable_hidden_mode(CHARGER_SOLO, 0); #endif mutex_unlock(&adc_access_lock); return rv; } -int charger_get_vbus_voltage(int port) +static int rt946x_get_vbus_voltage(int chgnum, int port) { static int vbus_mv; @@ -1371,7 +1400,7 @@ static int mt6370_toggle_cfo(void) { int rv, data; - rv = rt946x_read8(MT6370_REG_FLEDEN, &data); + rv = rt946x_read8(CHARGER_SOLO, MT6370_REG_FLEDEN, &data); if (rv) return rv; @@ -1379,26 +1408,26 @@ static int mt6370_toggle_cfo(void) return rv; /* read data */ - rv = rt946x_read8(RT946X_REG_CHGCTRL2, &data); + rv = rt946x_read8(CHARGER_SOLO, RT946X_REG_CHGCTRL2, &data); if (rv) return rv; /* cfo off */ data &= ~RT946X_MASK_CFO_EN; - rv = rt946x_write8(RT946X_REG_CHGCTRL2, data); + rv = rt946x_write8(CHARGER_SOLO, RT946X_REG_CHGCTRL2, data); if (rv) return rv; /* cfo on */ data |= RT946X_MASK_CFO_EN; - return rt946x_write8(RT946X_REG_CHGCTRL2, data); + return rt946x_write8(CHARGER_SOLO, RT946X_REG_CHGCTRL2, data); } -static int mt6370_pmu_chg_mivr_irq_handler(void) +static int mt6370_pmu_chg_mivr_irq_handler(int chgnum) { int rv, ibus = 0, mivr_stat; - rv = mt6370_pmu_reg_test_bit(MT6370_REG_CHGSTAT1, + rv = mt6370_pmu_reg_test_bit(chgnum, MT6370_REG_CHGSTAT1, MT6370_SHIFT_MIVR_STAT, &mivr_stat); if (rv) return rv; @@ -1418,39 +1447,39 @@ static int mt6370_pmu_chg_mivr_irq_handler(void) return rv; } -static int mt6370_irq_handler(void) +static int mt6370_irq_handler(int chgnum) { 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); + ret = rt946x_write8(chgnum, MT6370_REG_IRQMASK, MT6370_IRQ_MASK_ALL); if (ret) return ret; - ret = rt946x_read8(MT6370_REG_IRQIND, ®_val); + ret = rt946x_read8(chgnum, MT6370_REG_IRQIND, ®_val); if (ret) return ret; /* read stat before reading irq evt */ - ret = rt946x_read8(MT6370_REG_CHGSTAT1, &stat_old); + ret = rt946x_read8(chgnum, 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); + ret = rt946x_read8(chgnum, MT6370_REG_CHGIRQ1, &data); if (ret) return ret; /* read stat after reading irq evt */ - ret = rt946x_read8(MT6370_REG_CHGSTAT1, &stat_new); + ret = rt946x_read8(chgnum, MT6370_REG_CHGSTAT1, &stat_new); if (ret) return ret; - ret = rt946x_read8(MT6370_REG_CHGMASK1, &mask); + ret = rt946x_read8(chgnum, MT6370_REG_CHGMASK1, &mask); if (ret) return ret; - ret = rt946x_write8(MT6370_REG_IRQMASK, 0x00); + ret = rt946x_write8(chgnum, MT6370_REG_IRQMASK, 0x00); if (ret) return ret; @@ -1459,7 +1488,7 @@ static int mt6370_irq_handler(void) data |= (stat_chg & valid_chg); data &= ~mask; if (data) - ret = mt6370_pmu_chg_mivr_irq_handler(); + ret = mt6370_pmu_chg_mivr_irq_handler(chgnum); return ret; } #endif /* CONFIG_CHARGER_MT6370 */ @@ -1492,23 +1521,25 @@ void usb_charger_task(void *u) chg.voltage = USB_CHARGER_VOLTAGE_MV; while (1) { #ifdef CONFIG_CHARGER_MT6370 - mt6370_irq_handler(); + mt6370_irq_handler(CHARGER_SOLO); #endif /* CONFIG_CHARGER_MT6370 */ - rt946x_read8(RT946X_REG_DPDMIRQ, ®); + rt946x_read8(CHARGER_SOLO, 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(); + chg_type = + mt6370_get_charger_type(CHARGER_SOLO); 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); + rt946x_get_bc12_device_type(CHARGER_SOLO, + chg_type); chg.current = rt946x_get_bc12_ilim(bc12_type); } CPRINTS("BC12 type %d", bc12_type); @@ -1533,7 +1564,7 @@ void usb_charger_task(void *u) charge_manager_update_charge(bc12_type, 0, &chg); bc12_none: - rt946x_enable_bc12_detection(0); + rt946x_enable_bc12_detection(CHARGER_SOLO, 0); } /* VBUS detach event */ @@ -1568,7 +1599,7 @@ int usb_charger_ramp_max(int supplier, int sup_curr) int rt946x_enable_charger_boost(int en) { return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL2, RT946X_MASK_CHG_EN); + (CHARGER_SOLO, RT946X_REG_CHGCTRL2, RT946X_MASK_CHG_EN); } /* @@ -1579,7 +1610,7 @@ int rt946x_is_vbus_ready(void) { int val = 0; - return rt946x_read8(RT946X_REG_CHGSTATC, &val) ? + return rt946x_read8(CHARGER_SOLO, RT946X_REG_CHGSTATC, &val) ? 0 : !!(val & RT946X_MASK_PWR_RDY); } @@ -1587,7 +1618,7 @@ int rt946x_is_charge_done(void) { int val = 0; - if (rt946x_read8(RT946X_REG_CHGSTAT, &val)) + if (rt946x_read8(CHARGER_SOLO, RT946X_REG_CHGSTAT, &val)) return 0; val = (val & RT946X_MASK_CHG_STAT) >> RT946X_SHIFT_CHG_STAT; @@ -1606,48 +1637,52 @@ int rt946x_cutoff_battery(void) int rv; mutex_lock(&adc_access_lock); - rv = rt946x_write8(MT6370_REG_RSTPASCODE1, MT6370_MASK_RSTPASCODE1); + rv = rt946x_write8(CHARGER_SOLO, MT6370_REG_RSTPASCODE1, + MT6370_MASK_RSTPASCODE1); if (rv) goto out; - rv = rt946x_write8(MT6370_REG_RSTPASCODE2, MT6370_MASK_RSTPASCODE2); + rv = rt946x_write8(CHARGER_SOLO, MT6370_REG_RSTPASCODE2, + MT6370_MASK_RSTPASCODE2); if (rv) goto out; /* reset all chg/fled/ldo/rgb/bl/db reg and logic */ - rv = rt946x_write8(RT946X_REG_CORECTRL2, 0x7F); + rv = rt946x_write8(CHARGER_SOLO, RT946X_REG_CORECTRL2, 0x7F); if (rv) goto out; /* disable chg auto sensing */ - mt6370_enable_hidden_mode(1); - rv = rt946x_clr_bit(MT6370_REG_CHGHIDDENCTRL15, + mt6370_enable_hidden_mode(CHARGER_SOLO, 1); + rv = rt946x_clr_bit(CHARGER_SOLO, MT6370_REG_CHGHIDDENCTRL15, MT6370_MASK_ADC_TS_AUTO); - mt6370_enable_hidden_mode(0); + mt6370_enable_hidden_mode(CHARGER_SOLO, 0); if (rv) goto out; msleep(50); /* enter shipping mode */ - rv = rt946x_set_bit(RT946X_REG_CHGCTRL2, RT946X_MASK_SHIP_MODE); + rv = rt946x_set_bit(CHARGER_SOLO, RT946X_REG_CHGCTRL2, + RT946X_MASK_SHIP_MODE); out: mutex_unlock(&adc_access_lock); return rv; #endif /* enter shipping mode */ - return rt946x_set_bit(RT946X_REG_CHGCTRL2, RT946X_MASK_SHIP_MODE); + return rt946x_set_bit(CHARGER_SOLO, RT946X_REG_CHGCTRL2, + RT946X_MASK_SHIP_MODE); } int rt946x_enable_charge_termination(int en) { return (en ? rt946x_set_bit : rt946x_clr_bit) - (RT946X_REG_CHGCTRL2, RT946X_MASK_TE); + (CHARGER_SOLO, 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); + (CHARGER_SOLO, RT946X_REG_CHGCTRL9, RT946X_MASK_EOC); } #ifdef CONFIG_CHARGER_MT6370 @@ -1660,25 +1695,28 @@ int mt6370_set_ldo_voltage(int mv) 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); + rv = rt946x_update_bits(CHARGER_SOLO, 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, + return rt946x_clr_bit(CHARGER_SOLO, 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); + return rt946x_update_bits(CHARGER_SOLO, 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, + return rt946x_update_bits(CHARGER_SOLO, MT6370_REG_DBCTRL1, + MT6370_MASK_DB_EXT_EN, en << MT6370_SHIFT_DB_EXT_EN); } @@ -1687,25 +1725,28 @@ 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, + rv = rt946x_update_bits(CHARGER_SOLO, 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, + rv |= rt946x_update_bits(CHARGER_SOLO, 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, + rv |= rt946x_update_bits(CHARGER_SOLO, 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( + rv |= rt946x_update_bits(CHARGER_SOLO, MT6370_REG_DBCTRL2, MT6370_MASK_DB_VNEG_DISC | MT6370_MASK_DB_VPOS_DISC, MT6370_MASK_DB_VNEG_DISC | MT6370_MASK_DB_VPOS_DISC); @@ -1720,12 +1761,13 @@ 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); + rv = rt946x_write8(CHARGER_SOLO, MT6370_BACKLIGHT_BLDIM2, + dim & MT6370_MASK_BLDIM2); if (rv) return rv; - rv = rt946x_write8(MT6370_BACKLIGHT_BLDIM, + rv = rt946x_write8(CHARGER_SOLO, MT6370_BACKLIGHT_BLDIM, (dim >> MT6370_SHIFT_BLDIM_MSB) & MT6370_MASK_BLDIM); return rv; @@ -1739,7 +1781,7 @@ int mt6370_led_set_dim_mode(enum mt6370_led_index index, if (index <= MT6370_LED_ID_OFF || index >= MT6370_LED_ID_COUNT) return EC_ERROR_INVAL; - rt946x_update_bits(MT6370_REG_RGBDIM_BASE + index, + rt946x_update_bits(CHARGER_SOLO, MT6370_REG_RGBDIM_BASE + index, MT6370_MASK_RGB_DIMMODE, mode << MT6370_SHIFT_RGB_DIMMODE); return EC_SUCCESS; @@ -1747,8 +1789,8 @@ int mt6370_led_set_dim_mode(enum mt6370_led_index index, int mt6370_led_set_color(uint8_t mask) { - return rt946x_update_bits(MT6370_REG_RGBEN, MT6370_MASK_RGB_ISNK_ALL_EN, - mask); + return rt946x_update_bits(CHARGER_SOLO, MT6370_REG_RGBEN, + MT6370_MASK_RGB_ISNK_ALL_EN, mask); } int mt6370_led_set_brightness(enum mt6370_led_index index, uint8_t brightness) @@ -1756,7 +1798,7 @@ 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, + rt946x_update_bits(CHARGER_SOLO, MT6370_REG_RGBISNK_BASE + index, MT6370_MASK_RGBISNK_CURSEL, brightness << MT6370_SHIFT_RGBISNK_CURSEL); return EC_SUCCESS; @@ -1767,7 +1809,7 @@ 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, + rt946x_update_bits(CHARGER_SOLO, MT6370_REG_RGBDIM_BASE + index, MT6370_MASK_RGB_DIMDUTY, dim_duty << MT6370_SHIFT_RGB_DIMDUTY); return EC_SUCCESS; @@ -1779,7 +1821,7 @@ int mt6370_led_set_pwm_frequency(enum mt6370_led_index index, if (index >= MT6370_LED_ID_COUNT || index <= MT6370_LED_ID_OFF) return EC_ERROR_INVAL; - rt946x_update_bits(MT6370_REG_RGBISNK_BASE + index, + rt946x_update_bits(CHARGER_SOLO, MT6370_REG_RGBISNK_BASE + index, MT6370_MASK_RGBISNK_DIMFSEL, freq << MT6370_SHIFT_RGBISNK_DIMFSEL); return EC_SUCCESS; @@ -1790,29 +1832,58 @@ int mt6370_reduce_db_bl_driving(void) int rv; /* Enter test mode */ - rv = rt946x_block_write(MT6370_REG_TM_PAS_CODE1, + rv = rt946x_block_write(CHARGER_SOLO, MT6370_REG_TM_PAS_CODE1, mt6370_val_en_test_mode, ARRAY_SIZE(mt6370_val_en_test_mode)); if (rv) return rv; msleep(1); - rv = rt946x_write8(MT6370_REG_BANK, MT6370_MASK_REG_TM); + rv = rt946x_write8(CHARGER_SOLO, MT6370_REG_BANK, MT6370_MASK_REG_TM); if (rv) return rv; msleep(1); /* reduce bl driving */ - rv = rt946x_update_bits(MT6370_TM_REG_BL3, MT6370_TM_MASK_BL3_SL, - MT6370_TM_REDUCE_BL3_SL); + rv = rt946x_update_bits(CHARGER_SOLO, MT6370_TM_REG_BL3, + MT6370_TM_MASK_BL3_SL, MT6370_TM_REDUCE_BL3_SL); if (rv) return rv; msleep(1); /* reduce db driving */ - rv = rt946x_update_bits(MT6370_TM_REG_DSV1, MT6370_TM_MASK_DSV1_SL, + rv = rt946x_update_bits(CHARGER_SOLO, MT6370_TM_REG_DSV1, + MT6370_TM_MASK_DSV1_SL, MT6370_TM_REDUCE_DSV1_SL); if (rv) return rv; msleep(1); /* Leave test mode */ - return rt946x_write8(MT6370_REG_TM_PAS_CODE1, MT6370_LEAVE_TM); + return rt946x_write8(CHARGER_SOLO, MT6370_REG_TM_PAS_CODE1, + MT6370_LEAVE_TM); } #endif /* CONFIG_CHARGER_MT6370 */ + +const struct charger_drv rt946x_drv = { + .init = &rt946x_init, + .post_init = &rt946x_post_init, + .get_info = &rt946x_get_info, + .get_status = &rt946x_get_status, + .set_mode = &rt946x_set_mode, + .enable_otg_power = &rt946x_enable_otg_power, + .get_current = &rt946x_get_current, + .set_current = &rt946x_set_current, + .get_voltage = &rt946x_get_voltage, + .set_voltage = &rt946x_set_voltage, + .discharge_on_ac = &rt946x_discharge_on_ac, + .get_vbus_voltage = &rt946x_get_vbus_voltage, + .set_input_current = &rt946x_set_input_current, + .get_input_current = &rt946x_get_input_current, + .manufacturer_id = &rt946x_manufacturer_id, + .device_id = &rt946x_device_id, + .get_option = &rt946x_get_option, + .set_option = &rt946x_set_option, +#ifdef CONFIG_CHARGE_RAMP_HW + .set_hw_ramp = &rt946x_set_hw_ramp, + .ramp_is_stable = &rt946x_ramp_is_stable, + .ramp_is_detected = &rt946x_ramp_is_detected, + .ramp_get_current_limit = &rt946x_ramp_get_current_limit, +#endif +}; diff --git a/driver/charger/rt946x.h b/driver/charger/rt946x.h index 275969878e..461e0b472d 100644 --- a/driver/charger/rt946x.h +++ b/driver/charger/rt946x.h @@ -858,4 +858,6 @@ int mt6370_led_set_pwm_frequency(enum mt6370_led_index index, int mt6370_reduce_db_bl_driving(void); #endif +extern const struct charger_drv rt946x_drv; + #endif /* __CROS_EC_RT946X_H */ diff --git a/include/charger.h b/include/charger.h index 342f6a7b48..6aebf3b94c 100644 --- a/include/charger.h +++ b/include/charger.h @@ -40,6 +40,86 @@ struct charger_params { int flags; }; +struct charger_drv { + /* Function to call during HOOK_INIT after i2c init */ + void (*init)(int chgnum); + + /* Power state machine post init */ + enum ec_error_list (*post_init)(int chgnum); + + /* Get charger information */ + const struct charger_info * (*get_info)(int chgnum); + + /* Get smart battery charger status. Supported flags may vary. */ + enum ec_error_list (*get_status)(int chgnum, int *status); + + /* Set smart battery charger mode. Supported modes may vary. */ + enum ec_error_list (*set_mode)(int chgnum, int mode); + + /* + * For chargers that are able to supply output power for OTG dongle, + * this function enables or disables power output. + */ + enum ec_error_list (*enable_otg_power)(int chgnum, int enabled); + + /* + * Sets OTG current limit and voltage (independent of whether OTG + * power is currently enabled). + */ + enum ec_error_list (*set_otg_current_voltage)(int chgnum, + int output_current, + int output_voltage); + + /* Get/set charge current limit in mA */ + enum ec_error_list (*get_current)(int chgnum, int *current); + enum ec_error_list (*set_current)(int chgnum, int current); + + /* Get/set charge voltage limit in mV */ + enum ec_error_list (*get_voltage)(int chgnum, int *voltage); + enum ec_error_list (*set_voltage)(int chgnum, int voltage); + + /* Discharge battery when on AC power. */ + enum ec_error_list (*discharge_on_ac)(int chgnum, int enable); + + /* Get the VBUS voltage (mV) from the charger */ + int (*get_vbus_voltage)(int chgnum, int port); + + /* Set desired input current value */ + enum ec_error_list (*set_input_current)(int chgnum, int input_current); + + /* Get actual input current value */ + enum ec_error_list (*get_input_current)(int chgnum, int *input_current); + + enum ec_error_list (*manufacturer_id)(int chgnum, int *id); + enum ec_error_list (*device_id)(int chgnum, int *id); + enum ec_error_list (*get_option)(int chgnum, int *option); + enum ec_error_list (*set_option)(int chgnum, int option); + + /* Charge ramp functions */ + enum ec_error_list (*set_hw_ramp)(int chgnum, int enable); + int (*ramp_is_stable)(int chgnum); + int (*ramp_is_detected)(int chgnum); + int (*ramp_get_current_limit)(int chgnum); +}; + +struct charger_config_t { + int i2c_port; + uint16_t i2c_addr_flags; + const struct charger_drv *drv; +}; + +/* TODO(b/147672225): structure should be defined in board.c files */ +#ifndef CONFIG_CHARGER_RUNTIME_CONFIG +extern const struct charger_config_t chg_chips[]; +#else +extern struct charger_config_t chg_chips[]; +#endif +extern const unsigned int chg_cnt; + +#ifdef CONFIG_CHARGER_SINGLE_CHIP +#define CHARGER_SOLO 0 +#endif + /* Get the current charger_params. Failures are reported in .flags */ void charger_get_params(struct charger_params *chg); @@ -52,23 +132,48 @@ void charger_get_params(struct charger_params *chg); /* All of the above CHG_FLAG_BAD_* bits */ #define CHG_FLAG_BAD_ANY 0x0000001f +/** + * Return the closest match the charger can supply to the requested current. + * + * @param current Requested current in mA. + * + * @return Current the charger will actually supply if <current> is requested. + */ +int charger_closest_current(int current); + +/** + * Return the closest match the charger can supply to the requested voltage. + * + * @param voltage Requested voltage in mV. + * + * @return Voltage the charger will actually supply if <voltage> is requested. + */ +int charger_closest_voltage(int voltage); + +/* Driver wrapper functions */ + +/* + * TODO(b/147672225): charger_* functions should take chip arg, hardcode + * calls into driver to 0 for now. + */ + /* Power state machine post init */ -int charger_post_init(void); +enum ec_error_list charger_post_init(void); /* Get charger information. */ const struct charger_info *charger_get_info(void); /* Get smart battery charger status. Supported flags may vary. */ -int charger_get_status(int *status); +enum ec_error_list charger_get_status(int *status); /* Set smart battery charger mode. Supported modes may vary. */ -int charger_set_mode(int mode); +enum ec_error_list charger_set_mode(int mode); /** * For chargers that are able to supply output power for OTG dongle, this * function enables or disables power output. */ -int charger_enable_otg_power(int enabled); +enum ec_error_list charger_enable_otg_power(int enabled); /** * Sets OTG current limit and voltage (independent of whether OTG power is @@ -86,7 +191,8 @@ int charger_enable_otg_power(int enabled); * * @return EC_SUCCESS on success, an error otherwise. */ -int charger_set_otg_current_voltage(int output_current, int output_voltage); +enum ec_error_list charger_set_otg_current_voltage(int output_current, + int output_voltage); /** * Is the charger sourcing VBUS / OTG power? @@ -96,34 +202,16 @@ int charger_set_otg_current_voltage(int output_current, int output_voltage); */ int charger_is_sourcing_otg_power(int port); -/** - * Return the closest match the charger can supply to the requested current. - * - * @param current Requested current in mA. - * - * @return Current the charger will actually supply if <current> is requested. - */ -int charger_closest_current(int current); - -/** - * Return the closest match the charger can supply to the requested voltage. - * - * @param voltage Requested voltage in mV. - * - * @return Voltage the charger will actually supply if <voltage> is requested. - */ -int charger_closest_voltage(int voltage); - /* Get/set charge current limit in mA */ -int charger_get_current(int *current); -int charger_set_current(int current); +enum ec_error_list charger_get_current(int *current); +enum ec_error_list charger_set_current(int current); /* Get/set charge voltage limit in mV */ -int charger_get_voltage(int *voltage); -int charger_set_voltage(int voltage); +enum ec_error_list charger_get_voltage(int *voltage); +enum ec_error_list charger_set_voltage(int voltage); /* Discharge battery when on AC power. */ -int charger_discharge_on_ac(int enable); +enum ec_error_list charger_discharge_on_ac(int enable); /* Get the VBUS voltage (mV) from the charger */ int charger_get_vbus_voltage(int port); @@ -140,20 +228,20 @@ int charger_get_system_power(void); /* Other parameters that may be charger-specific, but are common so far. */ /* Set desired input current value */ -int charger_set_input_current(int input_current); +enum ec_error_list charger_set_input_current(int input_current); /* * Get actual input current value. * Actual input current may be less than the desired input current set * due to current ratings of the wall adapter. */ -int charger_get_input_current(int *input_current); +enum ec_error_list charger_get_input_current(int *input_current); -int charger_manufacturer_id(int *id); -int charger_device_id(int *id); -int charger_get_option(int *option); -int charger_set_option(int option); -int charger_set_hw_ramp(int enable); +enum ec_error_list charger_manufacturer_id(int *id); +enum ec_error_list charger_device_id(int *id); +enum ec_error_list charger_get_option(int *option); +enum ec_error_list charger_set_option(int option); +enum ec_error_list charger_set_hw_ramp(int enable); /* Print all charger info for debugging purposes */ void print_charger_debug(void); diff --git a/include/config.h b/include/config.h index 823210d2d7..5f3e4a0c4b 100644 --- a/include/config.h +++ b/include/config.h @@ -798,6 +798,15 @@ #undef CONFIG_CHARGER_RT9467 #undef CONFIG_CHARGER_SY21612 +/* Allow run-time completion of the charger driver structure */ +#undef CONFIG_CHARGER_RUNTIME_CONFIG + +/* + * Board has only one charger chip (default, undef when board contains multiple + * charger chips + */ +#define CONFIG_CHARGER_SINGLE_CHIP + /* * Enable the CHG_EN at initialization to turn-on the BGATE which allows voltage * to be applied to the battery PACK & wakes the battery if it is in shipmode. |