From fd06cd7c97fb0e1cb2aeb57ae0fe47a28efaec08 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Wed, 10 May 2023 09:26:33 -0500 Subject: [PATCH] drivers: charger: Introduces BQ24190 support Adds support for the BQ24190 family of charging ICs. Signed-off-by: Ricardo Rivera-Matos --- drivers/charger/CMakeLists.txt | 1 + drivers/charger/Kconfig | 1 + drivers/charger/Kconfig.bq24190 | 10 + drivers/charger/bq24190.c | 493 ++++++++++++++++++++++++++++++++ drivers/charger/bq24190.h | 167 +++++++++++ 5 files changed, 672 insertions(+) create mode 100644 drivers/charger/Kconfig.bq24190 create mode 100644 drivers/charger/bq24190.c create mode 100644 drivers/charger/bq24190.h diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt index 6b4b36ae61..84b3400942 100644 --- a/drivers/charger/CMakeLists.txt +++ b/drivers/charger/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) +zephyr_library_sources_ifdef(CONFIG_BQ24190 bq24190.c) zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig index 532a0a4545..4a6071fd8f 100644 --- a/drivers/charger/Kconfig +++ b/drivers/charger/Kconfig @@ -20,5 +20,6 @@ config CHARGER_INIT_PRIORITY Battery charger initialization priority. source "drivers/charger/Kconfig.sbs_charger" +source "drivers/charger/Kconfig.bq24190" endif # CHARGER diff --git a/drivers/charger/Kconfig.bq24190 b/drivers/charger/Kconfig.bq24190 new file mode 100644 index 0000000000..3327f671c6 --- /dev/null +++ b/drivers/charger/Kconfig.bq24190 @@ -0,0 +1,10 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BQ24190 + bool "BQ24190 Battery Charger" + default y + depends on DT_HAS_TI_BQ24190_ENABLED + select I2C + help + Enable I2C-based driver for the TI BQ24190 Battery Charger. diff --git a/drivers/charger/bq24190.c b/drivers/charger/bq24190.c new file mode 100644 index 0000000000..0661bd9279 --- /dev/null +++ b/drivers/charger/bq24190.c @@ -0,0 +1,493 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_bq24190 + +#include + +#include "bq24190.h" + +#include "zephyr/device.h" +#include "zephyr/drivers/charger.h" +#include "zephyr/drivers/i2c.h" +#include "zephyr/kernel.h" +#include "zephyr/sys/util.h" +#include "zephyr/logging/log.h" +#include + +LOG_MODULE_REGISTER(ti_bq24190); + +struct bq24190_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec ce_gpio; +}; + +struct bq24190_data { + uint8_t ss_reg; + unsigned int ichg_ua; + unsigned int vreg_uv; + enum charger_status state; + enum charger_online online; +}; + +static int bq24190_register_reset(const struct device *dev) +{ + const struct bq24190_config *const config = dev->config; + int ret, limit = BQ24190_RESET_MAX_TRIES; + uint8_t val; + + ret = i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_POC, BQ24190_REG_POC_RESET_MASK, + BQ24190_REG_POC_RESET_MASK); + if (ret) { + return ret; + } + + /* + * No explicit reset timing characteristcs are provided in the datasheet. + * Instead, poll every 100µs for 100 attempts to see if the reset request + * bit has cleared. + */ + do { + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &val); + if (ret) { + return ret; + } + + if (!(val & BQ24190_REG_POC_RESET_MASK)) { + return 0; + } + + k_usleep(100); + } while (--limit); + + return -EIO; +} + +static int bq24190_charger_get_charge_type(const struct device *dev, + enum charger_charge_type *charge_type) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + *charge_type = CHARGER_CHARGE_TYPE_UNKNOWN; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_POC_CHG_CONFIG_MASK, v); + + if (!v) { + *charge_type = CHARGER_CHARGE_TYPE_NONE; + } else { + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_CCC_FORCE_20PCT_MASK, v); + + if (v) { + *charge_type = CHARGER_CHARGE_TYPE_TRICKLE; + } else { + *charge_type = CHARGER_CHARGE_TYPE_FAST; + } + } + + return 0; +} + +static int bq24190_charger_get_health(const struct device *dev, enum charger_health *health) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &v); + if (ret) { + return ret; + } + + if (v & BQ24190_REG_F_NTC_FAULT_MASK) { + switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) { + case BQ24190_NTC_FAULT_TS1_COLD: + case BQ24190_NTC_FAULT_TS2_COLD: + case BQ24190_NTC_FAULT_TS1_TS2_COLD: + *health = CHARGER_HEALTH_COLD; + break; + case BQ24190_NTC_FAULT_TS1_HOT: + case BQ24190_NTC_FAULT_TS2_HOT: + case BQ24190_NTC_FAULT_TS1_TS2_HOT: + *health = CHARGER_HEALTH_HOT; + break; + default: + *health = CHARGER_HEALTH_UNKNOWN; + } + } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) { + *health = CHARGER_HEALTH_OVERVOLTAGE; + } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) { + switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) { + case BQ24190_CHRG_FAULT_INPUT_FAULT: + /* + * This could be over-voltage or under-voltage + * and there's no way to tell which. Instead + * of looking foolish and returning 'OVERVOLTAGE' + * when its really under-voltage, just return + * 'UNSPEC_FAILURE'. + */ + *health = CHARGER_HEALTH_UNSPEC_FAILURE; + break; + case BQ24190_CHRG_FAULT_TSHUT: + *health = CHARGER_HEALTH_OVERHEAT; + break; + case BQ24190_CHRG_SAFETY_TIMER: + *health = CHARGER_HEALTH_SAFETY_TIMER_EXPIRE; + break; + default: /* prevent compiler warning */ + *health = CHARGER_HEALTH_UNKNOWN; + } + } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { + /* + * This could be over-current or over-voltage but there's + * no way to tell which. Return 'OVERVOLTAGE' since there + * isn't an 'OVERCURRENT' value defined that we can return + * even if it was over-current. + */ + *health = CHARGER_HEALTH_OVERVOLTAGE; + } else { + *health = CHARGER_HEALTH_GOOD; + } + + return 0; +} + +static int bq24190_charger_get_online(const struct device *dev, enum charger_online *online) +{ + const struct bq24190_config *const config = dev->config; + uint8_t pg_stat, batfet_disable; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &pg_stat); + if (ret) { + return ret; + } + + pg_stat = FIELD_GET(BQ24190_REG_SS_PG_STAT_MASK, pg_stat); + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_MOC, &batfet_disable); + if (ret) { + return ret; + } + + batfet_disable = FIELD_GET(BQ24190_REG_MOC_BATFET_DISABLE_MASK, batfet_disable); + + if (pg_stat && !batfet_disable) { + *online = CHARGER_ONLINE_FIXED; + } else { + *online = CHARGER_ONLINE_OFFLINE; + } + + return 0; +} + +static int bq24190_charger_get_status(const struct device *dev, enum charger_status *status) +{ + const struct bq24190_config *const config = dev->config; + uint8_t ss_reg, chrg_fault; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &chrg_fault); + if (ret) { + return ret; + } + + chrg_fault = FIELD_GET(BQ24190_REG_F_CHRG_FAULT_MASK, chrg_fault); + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &ss_reg); + if (ret) { + return ret; + } + + /* + * The battery must be discharging when any of these are true: + * - there is no good power source; + * - there is a charge fault. + * Could also be discharging when in "supplement mode" but + * there is no way to tell when its in that mode. + */ + if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) { + *status = CHARGER_STATUS_DISCHARGING; + } else { + ss_reg = FIELD_GET(BQ24190_REG_SS_CHRG_STAT_MASK, ss_reg); + + switch (ss_reg) { + case BQ24190_CHRG_STAT_NOT_CHRGING: + *status = CHARGER_STATUS_NOT_CHARGING; + break; + case BQ24190_CHRG_STAT_PRECHRG: + case BQ24190_CHRG_STAT_FAST_CHRG: + *status = CHARGER_STATUS_CHARGING; + break; + case BQ24190_CHRG_STAT_CHRG_TERM: + *status = CHARGER_STATUS_FULL; + break; + default: + return -EIO; + } + } + + return 0; +} + +static int bq24190_charger_get_constant_charge_current(const struct device *dev, + uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + bool frc_20pct; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK; + + v = FIELD_GET(BQ24190_REG_CCC_ICHG_MASK, v); + + *current_ua = (v * BQ24190_REG_CCC_ICHG_STEP_UA) + BQ24190_REG_CCC_ICHG_OFFSET_UA; + + if (frc_20pct) { + *current_ua /= 5; + } + + return 0; +} + +static int bq24190_charger_get_precharge_current(const struct device *dev, uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + bool frc_20pct; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret) { + return ret; + } + + frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_PCTCC_IPRECHG_MASK, v); + + *current_ua = (v * BQ24190_REG_PCTCC_IPRECHG_STEP_UA) + BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA; + + if (frc_20pct) { + *current_ua /= 2; + } + + return 0; +} + +static int bq24190_charger_get_charge_term_current(const struct device *dev, uint32_t *current_ua) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v); + if (ret) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_PCTCC_ITERM_MASK, v); + + *current_ua = (v * BQ24190_REG_PCTCC_ITERM_STEP_UA) + BQ24190_REG_PCTCC_ITERM_OFFSET_UA; + + return 0; +} + +static int bq24190_get_constant_charge_voltage(const struct device *dev, uint32_t *voltage_uv) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CVC, &v); + if (ret < 0) { + return ret; + } + + v = FIELD_GET(BQ24190_REG_CVC_VREG_MASK, v); + + *voltage_uv = (v * BQ24190_REG_CVC_VREG_STEP_UV) + BQ24190_REG_CVC_VREG_OFFSET_UV; + + return 0; +} + +static int bq24190_set_constant_charge_current(const struct device *dev, uint32_t current_ua) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v); + if (ret < 0) { + return ret; + } + + v &= BQ24190_REG_CCC_FORCE_20PCT_MASK; + + if (v) { + current_ua *= 5; + } + + current_ua = CLAMP(current_ua, BQ24190_REG_CCC_ICHG_MIN_UA, BQ24190_REG_CCC_ICHG_MAX_UA); + + v = (current_ua - BQ24190_REG_CCC_ICHG_OFFSET_UA) / BQ24190_REG_CCC_ICHG_STEP_UA; + + v = FIELD_PREP(BQ24190_REG_CCC_ICHG_MASK, v); + + return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CCC, BQ24190_REG_CCC_ICHG_MASK, v); +} + +static int bq24190_set_constant_charge_voltage(const struct device *dev, uint32_t voltage_uv) +{ + const struct bq24190_config *const config = dev->config; + uint8_t v; + + voltage_uv = CLAMP(voltage_uv, BQ24190_REG_CVC_VREG_MIN_UV, BQ24190_REG_CVC_VREG_MAX_UV); + + v = (voltage_uv - BQ24190_REG_CVC_VREG_OFFSET_UV) / BQ24190_REG_CVC_VREG_STEP_UV; + + v = FIELD_PREP(BQ24190_REG_CVC_VREG_MASK, v); + + return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CVC, BQ24190_REG_CVC_VREG_MASK, v); +} + +static int bq24190_set_config(const struct device *dev) +{ + struct bq24190_data *data = dev->data; + union charger_propval val; + int ret; + + val.const_charge_current_ua = data->ichg_ua; + + ret = bq24190_set_constant_charge_current(dev, val.const_charge_current_ua); + if (ret < 0) { + return ret; + } + + val.const_charge_voltage_uv = data->vreg_uv; + + return bq24190_set_constant_charge_voltage(dev, val.const_charge_voltage_uv); +} + +static int bq24190_get_prop(const struct device *dev, charger_prop_t prop, + union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_ONLINE: + return bq24190_charger_get_online(dev, &val->online); + case CHARGER_PROP_CHARGE_TYPE: + return bq24190_charger_get_charge_type(dev, &val->charge_type); + case CHARGER_PROP_HEALTH: + return bq24190_charger_get_health(dev, &val->health); + case CHARGER_PROP_STATUS: + return bq24190_charger_get_status(dev, &val->status); + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return bq24190_charger_get_constant_charge_current(dev, + &val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return bq24190_get_constant_charge_voltage(dev, &val->const_charge_voltage_uv); + case CHARGER_PROP_PRECHARGE_CURRENT_UA: + return bq24190_charger_get_precharge_current(dev, &val->precharge_current_ua); + case CHARGER_PROP_CHARGE_TERM_CURRENT_UA: + return bq24190_charger_get_charge_term_current(dev, &val->charge_term_current_ua); + default: + return -ENOTSUP; + } +} + +static int bq24190_set_prop(const struct device *dev, charger_prop_t prop, + const union charger_propval *val) +{ + switch (prop) { + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + return bq24190_set_constant_charge_current(dev, val->const_charge_current_ua); + case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV: + return bq24190_set_constant_charge_voltage(dev, val->const_charge_voltage_uv); + default: + return -ENOTSUP; + } +} + +static int bq24190_init(const struct device *dev) +{ + const struct bq24190_config *const config = dev->config; + struct bq24190_data *data = dev->data; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_VPRS, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(BQ24190_REG_VPRS_PN_MASK, val); + + switch (val) { + case BQ24190_REG_VPRS_PN_24190: + case BQ24190_REG_VPRS_PN_24192: + case BQ24190_REG_VPRS_PN_24192I: + break; + default: + LOG_ERR("Error unknown model: 0x%02x\n", val); + return -ENODEV; + } + + ret = bq24190_register_reset(dev); + if (ret) { + return ret; + } + + ret = bq24190_set_config(dev); + if (ret) { + return ret; + } + + return i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &data->ss_reg); +} + +static const struct charger_driver_api bq24190_driver_api = { + .get_property = &bq24190_get_prop, + .set_property = &bq24190_set_prop, +}; + +#define BQ24190_INIT(inst) \ + \ + static const struct bq24190_config bq24190_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + static struct bq24190_data bq24190_data_##inst = { \ + .ichg_ua = DT_INST_PROP(inst, constant_charge_current_max_microamp), \ + .vreg_uv = DT_INST_PROP(inst, constant_charge_voltage_max_microvolt), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &bq24190_init, NULL, &bq24190_data_##inst, \ + &bq24190_config_##inst, POST_KERNEL, CONFIG_CHARGER_INIT_PRIORITY, \ + &bq24190_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BQ24190_INIT) diff --git a/drivers/charger/bq24190.h b/drivers/charger/bq24190.h new file mode 100644 index 0000000000..06d5d3ba29 --- /dev/null +++ b/drivers/charger/bq24190.h @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CHARGER_BQ24190_H_ +#define ZEPHYR_DRIVERS_CHARGER_BQ24190_H_ + +/* Input Source Control */ +#define BQ24190_REG_ISC 0x00 +#define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7) +#define BQ24190_REG_ISC_EN_HIZ_SHIFT 7 +#define BQ24190_REG_ISC_VINDPM_MASK GENMASK(6, 3) +#define BQ24190_REG_ISC_VINDPM_SHIFT 3 +#define BQ24190_REG_ISC_IINLIM_MASK GENMASK(2, 0) + +/* Power-On Configuration */ +#define BQ24190_REG_POC 0x01 +#define BQ24190_REG_POC_RESET_MASK BIT(7) +#define BQ24190_REG_POC_RESET_SHIFT 7 +#define BQ24190_RESET_MAX_TRIES 100 +#define BQ24190_REG_POC_WDT_RESET_MASK BIT(6) +#define BQ24190_REG_POC_WDT_RESET_SHIFT 6 +#define BQ24190_REG_POC_CHG_CONFIG_MASK GENMASK(5, 4) +#define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4 +#define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0 +#define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1 +#define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2 +#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3 +#define BQ24190_REG_POC_SYS_MIN_MASK GENMASK(3, 1) +#define BQ24190_REG_POC_SYS_MIN_SHIFT 1 +#define BQ24190_REG_POC_SYS_MIN_MIN_UV 3000000 +#define BQ24190_REG_POC_SYS_MIN_MAX_UV 3700000 +#define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0) +#define BQ24190_REG_POC_BOOST_LIM_SHIFT 0 + +/* Charge Current Control */ +#define BQ24190_REG_CCC 0x02 +#define BQ24190_REG_CCC_ICHG_MASK GENMASK(7, 2) +#define BQ24190_REG_CCC_ICHG_SHIFT 2 +#define BQ24190_REG_CCC_ICHG_STEP_UA 64000 +#define BQ24190_REG_CCC_ICHG_OFFSET_UA 512000 +#define BQ24190_REG_CCC_ICHG_MIN_UA BQ24190_REG_CCC_ICHG_OFFSET_UA +#define BQ24190_REG_CCC_ICHG_MAX_UA 4544000 +#define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0) +#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0 + +/* Pre-charge/Termination Current Cntl */ +#define BQ24190_REG_PCTCC 0x03 +#define BQ24190_REG_PCTCC_IPRECHG_MASK GENMASK(7, 4) +#define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4 +#define BQ24190_REG_PCTCC_IPRECHG_STEP_UA 128000 +#define BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA 128000 +#define BQ24190_REG_PCTCC_IPRECHG_MIN_UA BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA +#define BQ24190_REG_PCTCC_IPRECHG_MAX_UA 2048000 +#define BQ24190_REG_PCTCC_ITERM_MASK GENMASK(3, 0) +#define BQ24190_REG_PCTCC_ITERM_SHIFT 0 +#define BQ24190_REG_PCTCC_ITERM_STEP_UA 128000 +#define BQ24190_REG_PCTCC_ITERM_OFFSET_UA 128000 +#define BQ24190_REG_PCTCC_ITERM_MIN_UA BQ24190_REG_PCTCC_ITERM_OFFSET_UA +#define BQ24190_REG_PCTCC_ITERM_MAX_UA 2048000 + +/* Charge Voltage Control */ +#define BQ24190_REG_CVC 0x04 +#define BQ24190_REG_CVC_VREG_MASK GENMASK(7, 2) +#define BQ24190_REG_CVC_VREG_SHIFT 2 +#define BQ24190_REG_CVC_VREG_STEP_UV 16000 +#define BQ24190_REG_CVC_VREG_OFFSET_UV 3504000 +#define BQ24190_REG_CVC_VREG_MIN_UV BQ24190_REG_CVC_VREG_OFFSET_UV +#define BQ24190_REG_CVC_VREG_MAX_UV 4400000 +#define BQ24190_REG_CVC_BATLOWV_MASK BIT(1) +#define BQ24190_REG_CVC_BATLOWV_SHIFT 1 +#define BQ24190_REG_CVC_VRECHG_MASK BIT(0) +#define BQ24190_REG_CVC_VRECHG_SHIFT 0 + +/* Charge Term/Timer Control */ +#define BQ24190_REG_CTTC 0x05 +#define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7) +#define BQ24190_REG_CTTC_EN_TERM_SHIFT 7 +#define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6) +#define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6 +#define BQ24190_REG_CTTC_WATCHDOG_MASK GENMASK(5, 4) +#define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4 +#define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3) +#define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3 +#define BQ24190_REG_CTTC_CHG_TIMER_MASK GENMASK(2, 1) +#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1 +#define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0) +#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0 + +/* IR Comp/Thermal Regulation Control */ +#define BQ24190_REG_ICTRC 0x06 +#define BQ24190_REG_ICTRC_BAT_COMP_MASK GENMASK(7, 5) +#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5 +#define BQ24190_REG_ICTRC_VCLAMP_MASK GENMASK(4, 2) +#define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2 +#define BQ24190_REG_ICTRC_TREG_MASK GENMASK(1, 0) +#define BQ24190_REG_ICTRC_TREG_SHIFT 0 + +/* Misc. Operation Control */ +#define BQ24190_REG_MOC 0x07 +#define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7) +#define BQ24190_REG_MOC_DPDM_EN_SHIFT 7 +#define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6) +#define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6 +#define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5) +#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5 +#define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4) +#define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4 +#define BQ24190_REG_MOC_INT_MASK_MASK GENMASK(1, 0) +#define BQ24190_REG_MOC_INT_MASK_SHIFT 0 + +/* System Status */ +#define BQ24190_REG_SS 0x08 +#define BQ24190_REG_SS_VBUS_STAT_MASK GENMASK(7, 6) +#define BQ24190_REG_SS_VBUS_STAT_SHIFT 6 +#define BQ24190_REG_SS_CHRG_STAT_MASK GENMASK(5, 4) +#define BQ24190_REG_SS_CHRG_STAT_SHIFT 4 +#define BQ24190_CHRG_STAT_NOT_CHRGING 0x0 +#define BQ24190_CHRG_STAT_PRECHRG 0x1 +#define BQ24190_CHRG_STAT_FAST_CHRG 0x2 +#define BQ24190_CHRG_STAT_CHRG_TERM 0x3 +#define BQ24190_REG_SS_DPM_STAT_MASK BIT(3) +#define BQ24190_REG_SS_DPM_STAT_SHIFT 3 +#define BQ24190_REG_SS_PG_STAT_MASK BIT(2) +#define BQ24190_REG_SS_PG_STAT_SHIFT 2 +#define BQ24190_REG_SS_THERM_STAT_MASK BIT(1) +#define BQ24190_REG_SS_THERM_STAT_SHIFT 1 +#define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0) +#define BQ24190_REG_SS_VSYS_STAT_SHIFT 0 + +/* Fault */ +#define BQ24190_REG_F 0x09 +#define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7) +#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7 +#define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6) +#define BQ24190_REG_F_BOOST_FAULT_SHIFT 6 +#define BQ24190_REG_F_CHRG_FAULT_MASK GENMASK(5, 4) +#define BQ24190_REG_F_CHRG_FAULT_SHIFT 4 +#define BQ24190_CHRG_FAULT_INPUT_FAULT 0x1 +#define BQ24190_CHRG_FAULT_TSHUT 0x2 +#define BQ24190_CHRG_SAFETY_TIMER 0x3 +#define BQ24190_REG_F_BAT_FAULT_MASK BIT(3) +#define BQ24190_REG_F_BAT_FAULT_SHIFT 3 +#define BQ24190_REG_F_NTC_FAULT_MASK GENMASK(2, 0) +#define BQ24190_REG_F_NTC_FAULT_SHIFT 0 +#define BQ24190_NTC_FAULT_TS1_COLD 0x1 +#define BQ24190_NTC_FAULT_TS1_HOT 0x2 +#define BQ24190_NTC_FAULT_TS2_COLD 0x3 +#define BQ24190_NTC_FAULT_TS2_HOT 0x4 +#define BQ24190_NTC_FAULT_TS1_TS2_COLD 0x5 +#define BQ24190_NTC_FAULT_TS1_TS2_HOT 0x6 + +/* Vendor/Part/Revision Status */ +#define BQ24190_REG_VPRS 0x0A +#define BQ24190_REG_VPRS_PN_MASK GENMASK(5, 3) +#define BQ24190_REG_VPRS_PN_SHIFT 3 +#define BQ24190_REG_VPRS_PN_24190 0x4 +#define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193, 24196 */ +#define BQ24190_REG_VPRS_PN_24192I 0x3 +#define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2) +#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2 +#define BQ24190_REG_VPRS_DEV_REG_MASK GENMASK(1, 0) +#define BQ24190_REG_VPRS_DEV_REG_SHIFT 0 + +#endif