diff options
Diffstat (limited to 'driver/charger/isl9241.c')
-rw-r--r-- | driver/charger/isl9241.c | 189 |
1 files changed, 119 insertions, 70 deletions
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 +}; |