Commit 0902f836 authored by Matti Vaittinen's avatar Matti Vaittinen Committed by Sebastian Reichel

power: supply: Support ROHM bd99954 charger

The ROHM BD99954 is a Battery Management LSI for 1-4 cell Lithium-Ion
secondary battery intended to be used in space-constraint equipment such
as Low profile Notebook PC, Tablets and other applications. BD99954
provides a Dual-source Battery Charger, two port BC1.2 detection and a
Battery Monitor.

Support ROHM BD99954 Charger IC.
Signed-off-by: default avatarMatti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent 2a75c8a4
......@@ -713,6 +713,15 @@ config CHARGER_BD70528
information and altering charger configurations from charger
block of the ROHM BD70528 Power Management IC.
config CHARGER_BD99954
tristate "ROHM bd99954 charger driver"
depends on I2C
select LINEAR_RANGES
help
Say Y here to enable support for getting battery and charger
information and altering charger configurations from the ROHM
BD99954 charger IC.
config CHARGER_WILCO
tristate "Wilco EC based charger for ChromeOS"
depends on WILCO_EC
......
......@@ -92,4 +92,5 @@ obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o
obj-$(CONFIG_FUEL_GAUGE_SC27XX) += sc27xx_fuel_gauge.o
obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o
obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o
obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
// SPDX-License-Identifier: GPL-2.0-only
/*
* ROHM BD99954 charger driver
*
* Copyright (C) 2020 Rohm Semiconductors
* Originally written by:
* Mikko Mutanen <mikko.mutanen@fi.rohmeurope.com>
* Markus Laine <markus.laine@fi.rohmeurope.com>
* Bugs added by:
* Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
*/
/*
* The battery charging profile of BD99954.
*
* Curve (1) represents charging current.
* Curve (2) represents battery voltage.
*
* The BD99954 data sheet divides charging to three phases.
* a) Trickle-charge with constant current (8).
* b) pre-charge with constant current (6)
* c) fast-charge, first with constant current (5) phase. After
* the battery voltage has reached target level (4) we have constant
* voltage phase until charging current has dropped to termination
* level (7)
*
* V ^ ^ I
* . .
* . .
*(4)` `.` ` ` ` ` ` ` ` ` ` ` ` ` ` ----------------------------.
* . :/ .
* . o----+/:/ ` ` ` ` ` ` ` ` ` ` ` ` `.` ` (5)
* . + :: + .
* . + /- -- .
* . +`/- + .
* . o/- -: .
* . .s. +` .
* . .--+ `/ .
* . ..`` + .: .
* . -` + -- .
* . (2) ...`` + :- .
* . ...`` + -: .
*(3)` `.`."" ` ` ` `+-------- ` ` ` ` ` ` `.:` ` ` ` ` ` ` ` ` .` ` (6)
* . + `:. .
* . + -: .
* . + -:. .
* . + .--. .
* . (1) + `.+` ` ` `.` ` (7)
* -..............` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` + ` ` ` .` ` (8)
* . + -
* -------------------------------------------------+++++++++-->
* | trickle | pre | fast |
*
* Details of DT properties for different limits can be found from BD99954
* device tree binding documentation.
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/linear_range.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/power_supply.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include "bd99954-charger.h"
struct battery_data {
u16 precharge_current; /* Trickle-charge Current */
u16 fc_reg_voltage; /* Fast Charging Regulation Voltage */
u16 voltage_min;
u16 voltage_max;
};
/* Initial field values, converted to initial register values */
struct bd9995x_init_data {
u16 vsysreg_set; /* VSYS Regulation Setting */
u16 ibus_lim_set; /* VBUS input current limitation */
u16 icc_lim_set; /* VCC/VACP Input Current Limit Setting */
u16 itrich_set; /* Trickle-charge Current Setting */
u16 iprech_set; /* Pre-Charge Current Setting */
u16 ichg_set; /* Fast-Charge constant current */
u16 vfastchg_reg_set1; /* Fast Charging Regulation Voltage */
u16 vprechg_th_set; /* Pre-charge Voltage Threshold Setting */
u16 vrechg_set; /* Re-charge Battery Voltage Setting */
u16 vbatovp_set; /* Battery Over Voltage Threshold Setting */
u16 iterm_set; /* Charging termination current */
};
struct bd9995x_state {
u8 online;
u16 chgstm_status;
u16 vbat_vsys_status;
u16 vbus_vcc_status;
};
struct bd9995x_device {
struct i2c_client *client;
struct device *dev;
struct power_supply *charger;
struct regmap *rmap;
struct regmap_field *rmap_fields[F_MAX_FIELDS];
int chip_id;
int chip_rev;
struct bd9995x_init_data init_data;
struct bd9995x_state state;
struct mutex lock; /* Protect state data */
};
static const struct regmap_range bd9995x_readonly_reg_ranges[] = {
regmap_reg_range(CHGSTM_STATUS, SEL_ILIM_VAL),
regmap_reg_range(IOUT_DACIN_VAL, IOUT_DACIN_VAL),
regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS),
regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS),
regmap_reg_range(CHIP_ID, CHIP_REV),
regmap_reg_range(SYSTEM_STATUS, SYSTEM_STATUS),
regmap_reg_range(IBATP_VAL, VBAT_AVE_VAL),
regmap_reg_range(VTH_VAL, EXTIADP_AVE_VAL),
};
static const struct regmap_access_table bd9995x_writeable_regs = {
.no_ranges = bd9995x_readonly_reg_ranges,
.n_no_ranges = ARRAY_SIZE(bd9995x_readonly_reg_ranges),
};
static const struct regmap_range bd9995x_volatile_reg_ranges[] = {
regmap_reg_range(CHGSTM_STATUS, WDT_STATUS),
regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS),
regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS),
regmap_reg_range(INT0_STATUS, INT7_STATUS),
regmap_reg_range(SYSTEM_STATUS, SYSTEM_CTRL_SET),
regmap_reg_range(IBATP_VAL, EXTIADP_AVE_VAL), /* Measurement regs */
};
static const struct regmap_access_table bd9995x_volatile_regs = {
.yes_ranges = bd9995x_volatile_reg_ranges,
.n_yes_ranges = ARRAY_SIZE(bd9995x_volatile_reg_ranges),
};
static const struct regmap_range_cfg regmap_range_cfg[] = {
{
.selector_reg = MAP_SET,
.selector_mask = 0xFFFF,
.selector_shift = 0,
.window_start = 0,
.window_len = 0x100,
.range_min = 0 * 0x100,
.range_max = 3 * 0x100,
},
};
static const struct regmap_config bd9995x_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.reg_stride = 1,
.max_register = 3 * 0x100,
.cache_type = REGCACHE_RBTREE,
.ranges = regmap_range_cfg,
.num_ranges = ARRAY_SIZE(regmap_range_cfg),
.val_format_endian = REGMAP_ENDIAN_LITTLE,
.wr_table = &bd9995x_writeable_regs,
.volatile_table = &bd9995x_volatile_regs,
};
enum bd9995x_chrg_fault {
CHRG_FAULT_NORMAL,
CHRG_FAULT_INPUT,
CHRG_FAULT_THERMAL_SHUTDOWN,
CHRG_FAULT_TIMER_EXPIRED,
};
static int bd9995x_get_prop_batt_health(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
if (ret)
return POWER_SUPPLY_HEALTH_UNKNOWN;
/* TODO: Check these against datasheet page 34 */
switch (tmp) {
case ROOM:
return POWER_SUPPLY_HEALTH_GOOD;
case HOT1:
case HOT2:
case HOT3:
return POWER_SUPPLY_HEALTH_OVERHEAT;
case COLD1:
case COLD2:
return POWER_SUPPLY_HEALTH_COLD;
case TEMP_DIS:
case BATT_OPEN:
default:
return POWER_SUPPLY_HEALTH_UNKNOWN;
}
}
static int bd9995x_get_prop_charge_type(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_CHGSTM_STATE], &tmp);
if (ret)
return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
switch (tmp) {
case CHGSTM_TRICKLE_CHARGE:
case CHGSTM_PRE_CHARGE:
return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
case CHGSTM_FAST_CHARGE:
return POWER_SUPPLY_CHARGE_TYPE_FAST;
case CHGSTM_TOP_OFF:
case CHGSTM_DONE:
case CHGSTM_SUSPEND:
return POWER_SUPPLY_CHARGE_TYPE_NONE;
default: /* Rest of the states are error related, no charging */
return POWER_SUPPLY_CHARGE_TYPE_NONE;
}
}
static bool bd9995x_get_prop_batt_present(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
if (ret)
return false;
return tmp != BATT_OPEN;
}
static int bd9995x_get_prop_batt_voltage(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_VBAT_VAL], &tmp);
if (ret)
return 0;
tmp = min(tmp, 19200);
return tmp * 1000;
}
static int bd9995x_get_prop_batt_current(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
if (ret)
return 0;
return tmp * 1000;
}
#define DEFAULT_BATTERY_TEMPERATURE 250
static int bd9995x_get_prop_batt_temp(struct bd9995x_device *bd)
{
int ret, tmp;
ret = regmap_field_read(bd->rmap_fields[F_THERM_VAL], &tmp);
if (ret)
return DEFAULT_BATTERY_TEMPERATURE;
return (200 - tmp) * 10;
}
static int bd9995x_power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret, tmp;
struct bd9995x_device *bd = power_supply_get_drvdata(psy);
struct bd9995x_state state;
mutex_lock(&bd->lock);
state = bd->state;
mutex_unlock(&bd->lock);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
switch (state.chgstm_status) {
case CHGSTM_TRICKLE_CHARGE:
case CHGSTM_PRE_CHARGE:
case CHGSTM_FAST_CHARGE:
case CHGSTM_TOP_OFF:
val->intval = POWER_SUPPLY_STATUS_CHARGING;
break;
case CHGSTM_DONE:
val->intval = POWER_SUPPLY_STATUS_FULL;
break;
case CHGSTM_SUSPEND:
case CHGSTM_TEMPERATURE_ERROR_1:
case CHGSTM_TEMPERATURE_ERROR_2:
case CHGSTM_TEMPERATURE_ERROR_3:
case CHGSTM_TEMPERATURE_ERROR_4:
case CHGSTM_TEMPERATURE_ERROR_5:
case CHGSTM_TEMPERATURE_ERROR_6:
case CHGSTM_TEMPERATURE_ERROR_7:
case CHGSTM_THERMAL_SHUT_DOWN_1:
case CHGSTM_THERMAL_SHUT_DOWN_2:
case CHGSTM_THERMAL_SHUT_DOWN_3:
case CHGSTM_THERMAL_SHUT_DOWN_4:
case CHGSTM_THERMAL_SHUT_DOWN_5:
case CHGSTM_THERMAL_SHUT_DOWN_6:
case CHGSTM_THERMAL_SHUT_DOWN_7:
case CHGSTM_BATTERY_ERROR:
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
break;
default:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
break;
}
break;
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = BD9995X_MANUFACTURER;
break;
case POWER_SUPPLY_PROP_ONLINE:
val->intval = state.online;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
if (ret)
return ret;
val->intval = tmp * 1000;
break;
case POWER_SUPPLY_PROP_CHARGE_AVG:
ret = regmap_field_read(bd->rmap_fields[F_IBATP_AVE_VAL], &tmp);
if (ret)
return ret;
val->intval = tmp * 1000;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
/*
* Currently the DT uses this property to give the
* target current for fast-charging constant current phase.
* I think it is correct in a sense.
*
* Yet, this prop we read and return here is the programmed
* safety limit for combined input currents. This feels
* also correct in a sense.
*
* However, this results a mismatch to DT value and value
* read from sysfs.
*/
ret = regmap_field_read(bd->rmap_fields[F_SEL_ILIM_VAL], &tmp);
if (ret)
return ret;
val->intval = tmp * 1000;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
if (!state.online) {
val->intval = 0;
break;
}
ret = regmap_field_read(bd->rmap_fields[F_VFASTCHG_REG_SET1],
&tmp);
if (ret)
return ret;
/*
* The actual range : 2560 to 19200 mV. No matter what the
* register says
*/
val->intval = clamp_val(tmp << 4, 2560, 19200);
val->intval *= 1000;
break;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
ret = regmap_field_read(bd->rmap_fields[F_ITERM_SET], &tmp);
if (ret)
return ret;
/* Start step is 64 mA */
val->intval = tmp << 6;
/* Maximum is 1024 mA - no matter what register says */
val->intval = min(val->intval, 1024);
val->intval *= 1000;
break;
/* Battery properties which we access through charger */
case POWER_SUPPLY_PROP_PRESENT:
val->intval = bd9995x_get_prop_batt_present(bd);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = bd9995x_get_prop_batt_voltage(bd);
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = bd9995x_get_prop_batt_current(bd);
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
val->intval = bd9995x_get_prop_charge_type(bd);
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = bd9995x_get_prop_batt_health(bd);
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = bd9995x_get_prop_batt_temp(bd);
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = "bd99954";
break;
default:
return -EINVAL;
}
return 0;
}
static int bd9995x_get_chip_state(struct bd9995x_device *bd,
struct bd9995x_state *state)
{
int i, ret, tmp;
struct {
struct regmap_field *id;
u16 *data;
} state_fields[] = {
{
bd->rmap_fields[F_CHGSTM_STATE], &state->chgstm_status,
}, {
bd->rmap_fields[F_VBAT_VSYS_STATUS],
&state->vbat_vsys_status,
}, {
bd->rmap_fields[F_VBUS_VCC_STATUS],
&state->vbus_vcc_status,
},
};
for (i = 0; i < ARRAY_SIZE(state_fields); i++) {
ret = regmap_field_read(state_fields[i].id, &tmp);
if (ret)
return ret;
*state_fields[i].data = tmp;
}
if (state->vbus_vcc_status & STATUS_VCC_DET ||
state->vbus_vcc_status & STATUS_VBUS_DET)
state->online = 1;
else
state->online = 0;
return 0;
}
static irqreturn_t bd9995x_irq_handler_thread(int irq, void *private)
{
struct bd9995x_device *bd = private;
int ret, status, mask, i;
unsigned long tmp;
struct bd9995x_state state;
/*
* The bd9995x does not seem to generate big amount of interrupts.
* The logic regarding which interrupts can cause relevant
* status changes seem to be pretty complex.
*
* So lets implement really simple and hopefully bullet-proof handler:
* It does not really matter which IRQ we handle, we just go and
* re-read all interesting statuses + give the framework a nudge.
*
* Other option would be building a _complex_ and error prone logic
* trying to decide what could have been changed (resulting this IRQ
* we are now handling). During the normal operation the BD99954 does
* not seem to be generating much of interrupts so benefit from such
* logic would probably be minimal.
*/
ret = regmap_read(bd->rmap, INT0_STATUS, &status);
if (ret) {
dev_err(bd->dev, "Failed to read IRQ status\n");
return IRQ_NONE;
}
ret = regmap_field_read(bd->rmap_fields[F_INT0_SET], &mask);
if (ret) {
dev_err(bd->dev, "Failed to read IRQ mask\n");
return IRQ_NONE;
}
/* Handle only IRQs that are not masked */
status &= mask;
tmp = status;
/* Lowest bit does not represent any sub-registers */
tmp >>= 1;
/*
* Mask and ack IRQs we will handle (+ the idiot bit)
*/
ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], 0);
if (ret) {
dev_err(bd->dev, "Failed to mask F_INT0\n");
return IRQ_NONE;
}
ret = regmap_write(bd->rmap, INT0_STATUS, status);
if (ret) {
dev_err(bd->dev, "Failed to ack F_INT0\n");
goto err_umask;
}
for_each_set_bit(i, &tmp, 7) {
int sub_status, sub_mask;
int sub_status_reg[] = {
INT1_STATUS, INT2_STATUS, INT3_STATUS, INT4_STATUS,
INT5_STATUS, INT6_STATUS, INT7_STATUS,
};
struct regmap_field *sub_mask_f[] = {
bd->rmap_fields[F_INT1_SET],
bd->rmap_fields[F_INT2_SET],
bd->rmap_fields[F_INT3_SET],
bd->rmap_fields[F_INT4_SET],
bd->rmap_fields[F_INT5_SET],
bd->rmap_fields[F_INT6_SET],
bd->rmap_fields[F_INT7_SET],
};
/* Clear sub IRQs */
ret = regmap_read(bd->rmap, sub_status_reg[i], &sub_status);
if (ret) {
dev_err(bd->dev, "Failed to read IRQ sub-status\n");
goto err_umask;
}
ret = regmap_field_read(sub_mask_f[i], &sub_mask);
if (ret) {
dev_err(bd->dev, "Failed to read IRQ sub-mask\n");
goto err_umask;
}
/* Ack active sub-statuses */
sub_status &= sub_mask;
ret = regmap_write(bd->rmap, sub_status_reg[i], sub_status);
if (ret) {
dev_err(bd->dev, "Failed to ack sub-IRQ\n");
goto err_umask;
}
}
ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
if (ret)
/* May as well retry once */
goto err_umask;
/* Read whole chip state */
ret = bd9995x_get_chip_state(bd, &state);
if (ret < 0) {
dev_err(bd->dev, "Failed to read chip state\n");
} else {
mutex_lock(&bd->lock);
bd->state = state;
mutex_unlock(&bd->lock);
power_supply_changed(bd->charger);
}
return IRQ_HANDLED;
err_umask:
ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
if (ret)
dev_err(bd->dev,
"Failed to un-mask F_INT0 - IRQ permanently disabled\n");
return IRQ_NONE;
}
static int __bd9995x_chip_reset(struct bd9995x_device *bd)
{
int ret, state;
int rst_check_counter = 10;
u16 tmp = ALLRST | OTPLD;
ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
if (ret < 0)
return ret;
do {
ret = regmap_field_read(bd->rmap_fields[F_OTPLD_STATE], &state);
if (ret)
return ret;
msleep(10);
} while (state == 0 && --rst_check_counter);
if (!rst_check_counter) {
dev_err(bd->dev, "chip reset not completed\n");
return -ETIMEDOUT;
}
tmp = 0;
ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
return ret;
}
static int bd9995x_hw_init(struct bd9995x_device *bd)
{
int ret;
int i;
struct bd9995x_state state;
struct bd9995x_init_data *id = &bd->init_data;
const struct {
enum bd9995x_fields id;
u16 value;
} init_data[] = {
/* Enable the charging trigger after SDP charger attached */
{F_SDP_CHG_TRIG_EN, 1},
/* Enable charging trigger after SDP charger attached */
{F_SDP_CHG_TRIG, 1},
/* Disable charging trigger by BC1.2 detection */
{F_VBUS_BC_DISEN, 1},
/* Disable charging trigger by BC1.2 detection */
{F_VCC_BC_DISEN, 1},
/* Disable automatic limitation of the input current */
{F_ILIM_AUTO_DISEN, 1},
/* Select current limitation when SDP charger attached*/
{F_SDP_500_SEL, 1},
/* Select current limitation when DCP charger attached */
{F_DCP_2500_SEL, 1},
{F_VSYSREG_SET, id->vsysreg_set},
/* Activate USB charging and DC/DC converter */
{F_USB_SUS, 0},
/* DCDC clock: 1200 kHz*/
{F_DCDC_CLK_SEL, 3},
/* Enable charging */
{F_CHG_EN, 1},
/* Disable Input current Limit setting voltage measurement */
{F_EXTIADPEN, 0},
/* Disable input current limiting */
{F_VSYS_PRIORITY, 1},
{F_IBUS_LIM_SET, id->ibus_lim_set},
{F_ICC_LIM_SET, id->icc_lim_set},
/* Charge Termination Current Setting to 0*/
{F_ITERM_SET, id->iterm_set},
/* Trickle-charge Current Setting */
{F_ITRICH_SET, id->itrich_set},
/* Pre-charge Current setting */
{F_IPRECH_SET, id->iprech_set},
/* Fast Charge Current for constant current phase */
{F_ICHG_SET, id->ichg_set},
/* Fast Charge Voltage Regulation Setting */
{F_VFASTCHG_REG_SET1, id->vfastchg_reg_set1},
/* Set Pre-charge Voltage Threshold for trickle charging. */
{F_VPRECHG_TH_SET, id->vprechg_th_set},
{F_VRECHG_SET, id->vrechg_set},
{F_VBATOVP_SET, id->vbatovp_set},
/* Reverse buck boost voltage Setting */
{F_VRBOOST_SET, 0},
/* Disable fast-charging watchdog */
{F_WDT_FST, 0},
/* Disable pre-charging watchdog */
{F_WDT_PRE, 0},
/* Power save off */
{F_POWER_SAVE_MODE, 0},
{F_INT1_SET, INT1_ALL},
{F_INT2_SET, INT2_ALL},
{F_INT3_SET, INT3_ALL},
{F_INT4_SET, INT4_ALL},
{F_INT5_SET, INT5_ALL},
{F_INT6_SET, INT6_ALL},
{F_INT7_SET, INT7_ALL},
};
/*
* Currently we initialize charger to a known state at startup.
* If we want to allow for example the boot code to initialize
* charger we should get rid of this.
*/
ret = __bd9995x_chip_reset(bd);
if (ret < 0)
return ret;
/* Initialize currents/voltages and other parameters */
for (i = 0; i < ARRAY_SIZE(init_data); i++) {
ret = regmap_field_write(bd->rmap_fields[init_data[i].id],
init_data[i].value);
if (ret) {
dev_err(bd->dev, "failed to initialize charger (%d)\n",
ret);
return ret;
}
}
ret = bd9995x_get_chip_state(bd, &state);
if (ret < 0)
return ret;
mutex_lock(&bd->lock);
bd->state = state;
mutex_unlock(&bd->lock);
return 0;
}
static enum power_supply_property bd9995x_power_supply_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
POWER_SUPPLY_PROP_CHARGE_AVG,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
/* Battery props we access through charger */
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_MODEL_NAME,
};
static const struct power_supply_desc bd9995x_power_supply_desc = {
.name = "bd9995x-charger",
.type = POWER_SUPPLY_TYPE_USB,
.properties = bd9995x_power_supply_props,
.num_properties = ARRAY_SIZE(bd9995x_power_supply_props),
.get_property = bd9995x_power_supply_get_property,
};
/*
* Limit configurations for vbus-input-current and vcc-vacp-input-current
* Minimum limit is 0 uA. Max is 511 * 32000 uA = 16352000 uA. This is
* configured by writing a register so that each increment in register
* value equals to 32000 uA limit increment.
*
* Eg, value 0x0 is limit 0, value 0x1 is limit 32000, ...
* Describe the setting in linear_range table.
*/
static const struct linear_range input_current_limit_ranges[] = {
{
.min = 0,
.step = 32000,
.min_sel = 0x0,
.max_sel = 0x1ff,
},
};
/* Possible trickle, pre-charging and termination current values */
static const struct linear_range charging_current_ranges[] = {
{
.min = 0,
.step = 64000,
.min_sel = 0x0,
.max_sel = 0x10,
}, {
.min = 1024000,
.step = 0,
.min_sel = 0x11,
.max_sel = 0x1f,
},
};
/*
* Fast charging voltage regulation, starting re-charging limit
* and battery over voltage protection have same possible values
*/
static const struct linear_range charge_voltage_regulation_ranges[] = {
{
.min = 2560000,
.step = 0,
.min_sel = 0,
.max_sel = 0xA0,
}, {
.min = 2560000,
.step = 16000,
.min_sel = 0xA0,
.max_sel = 0x4B0,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x4B0,
.max_sel = 0x7FF,
},
};
/* Possible VSYS voltage regulation values */
static const struct linear_range vsys_voltage_regulation_ranges[] = {
{
.min = 2560000,
.step = 0,
.min_sel = 0,
.max_sel = 0x28,
}, {
.min = 2560000,
.step = 64000,
.min_sel = 0x28,
.max_sel = 0x12C,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x12C,
.max_sel = 0x1FF,
},
};
/* Possible settings for switching from trickle to pre-charging limits */
static const struct linear_range trickle_to_pre_threshold_ranges[] = {
{
.min = 2048000,
.step = 0,
.min_sel = 0,
.max_sel = 0x20,
}, {
.min = 2048000,
.step = 64000,
.min_sel = 0x20,
.max_sel = 0x12C,
}, {
.min = 19200000,
.step = 0,
.min_sel = 0x12C,
.max_sel = 0x1FF
}
};
/* Possible current values for fast-charging constant current phase */
static const struct linear_range fast_charge_current_ranges[] = {
{
.min = 0,
.step = 64000,
.min_sel = 0,
.max_sel = 0xFF,
}
};
struct battery_init {
const char *name;
int *info_data;
const struct linear_range *range;
int ranges;
u16 *data;
};
struct dt_init {
char *prop;
const struct linear_range *range;
int ranges;
u16 *data;
};
static int bd9995x_fw_probe(struct bd9995x_device *bd)
{
int ret;
struct power_supply_battery_info info;
u32 property;
int i;
int regval;
bool found;
struct bd9995x_init_data *init = &bd->init_data;
struct battery_init battery_inits[] = {
{
.name = "trickle-charging current",
.info_data = &info.tricklecharge_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->itrich_set,
}, {
.name = "pre-charging current",
.info_data = &info.precharge_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->iprech_set,
}, {
.name = "pre-to-trickle charge voltage threshold",
.info_data = &info.precharge_voltage_max_uv,
.range = &trickle_to_pre_threshold_ranges[0],
.ranges = 2,
.data = &init->vprechg_th_set,
}, {
.name = "charging termination current",
.info_data = &info.charge_term_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->iterm_set,
}, {
.name = "charging re-start voltage",
.info_data = &info.charge_restart_voltage_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vrechg_set,
}, {
.name = "battery overvoltage limit",
.info_data = &info.overvoltage_limit_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vbatovp_set,
}, {
.name = "fast-charging max current",
.info_data = &info.constant_charge_current_max_ua,
.range = &fast_charge_current_ranges[0],
.ranges = 1,
.data = &init->ichg_set,
}, {
.name = "fast-charging voltage",
.info_data = &info.constant_charge_voltage_max_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vfastchg_reg_set1,
},
};
struct dt_init props[] = {
{
.prop = "rohm,vsys-regulation-microvolt",
.range = &vsys_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vsysreg_set,
}, {
.prop = "rohm,vbus-input-current-limit-microamp",
.range = &input_current_limit_ranges[0],
.ranges = 1,
.data = &init->ibus_lim_set,
}, {
.prop = "rohm,vcc-input-current-limit-microamp",
.range = &input_current_limit_ranges[0],
.ranges = 1,
.data = &init->icc_lim_set,
},
};
/*
* The power_supply_get_battery_info() does not support getting values
* from ACPI. Let's fix it if ACPI is required here.
*/
ret = power_supply_get_battery_info(bd->charger, &info);
if (ret < 0)
return ret;
for (i = 0; i < ARRAY_SIZE(battery_inits); i++) {
int val = *battery_inits[i].info_data;
const struct linear_range *range = battery_inits[i].range;
int ranges = battery_inits[i].ranges;
if (val == -EINVAL)
continue;
ret = linear_range_get_selector_low_array(range, ranges, val,
&regval, &found);
if (ret) {
dev_err(bd->dev, "Unsupported value for %s\n",
battery_inits[i].name);
power_supply_put_battery_info(bd->charger, &info);
return -EINVAL;
}
if (!found) {
dev_warn(bd->dev,
"Unsupported value for %s - using smaller\n",
battery_inits[i].name);
}
*(battery_inits[i].data) = regval;
}
power_supply_put_battery_info(bd->charger, &info);
for (i = 0; i < ARRAY_SIZE(props); i++) {
ret = device_property_read_u32(bd->dev, props[i].prop,
&property);
if (ret < 0) {
dev_err(bd->dev, "failed to read %s", props[i].prop);
return ret;
}
ret = linear_range_get_selector_low_array(props[i].range,
props[i].ranges,
property, &regval,
&found);
if (ret) {
dev_err(bd->dev, "Unsupported value for '%s'\n",
props[i].prop);
return -EINVAL;
}
if (!found) {
dev_warn(bd->dev,
"Unsupported value for '%s' - using smaller\n",
props[i].prop);
}
*(props[i].data) = regval;
}
return 0;
}
void bd9995x_chip_reset(void *bd)
{
__bd9995x_chip_reset(bd);
}
static int bd9995x_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct bd9995x_device *bd;
struct power_supply_config psy_cfg = {};
int ret;
int i;
bd = devm_kzalloc(dev, sizeof(*bd), GFP_KERNEL);
if (!bd)
return -ENOMEM;
bd->client = client;
bd->dev = dev;
psy_cfg.drv_data = bd;
psy_cfg.of_node = dev->of_node;
mutex_init(&bd->lock);
bd->rmap = devm_regmap_init_i2c(client, &bd9995x_regmap_config);
if (IS_ERR(bd->rmap)) {
dev_err(dev, "Failed to setup register access via i2c\n");
return PTR_ERR(bd->rmap);
}
for (i = 0; i < ARRAY_SIZE(bd9995x_reg_fields); i++) {
const struct reg_field *reg_fields = bd9995x_reg_fields;
bd->rmap_fields[i] = devm_regmap_field_alloc(dev, bd->rmap,
reg_fields[i]);
if (IS_ERR(bd->rmap_fields[i])) {
dev_err(dev, "cannot allocate regmap field\n");
return PTR_ERR(bd->rmap_fields[i]);
}
}
i2c_set_clientdata(client, bd);
ret = regmap_field_read(bd->rmap_fields[F_CHIP_ID], &bd->chip_id);
if (ret) {
dev_err(dev, "Cannot read chip ID.\n");
return ret;
}
if (bd->chip_id != BD99954_ID) {
dev_err(dev, "Chip with ID=0x%x, not supported!\n",
bd->chip_id);
return -ENODEV;
}
ret = regmap_field_read(bd->rmap_fields[F_CHIP_REV], &bd->chip_rev);
if (ret) {
dev_err(dev, "Cannot read revision.\n");
return ret;
}
dev_info(bd->dev, "Found BD99954 chip rev %d\n", bd->chip_rev);
/*
* We need to init the psy before we can call
* power_supply_get_battery_info() for it
*/
bd->charger = devm_power_supply_register(bd->dev,
&bd9995x_power_supply_desc,
&psy_cfg);
if (IS_ERR(bd->charger)) {
dev_err(dev, "Failed to register power supply\n");
return PTR_ERR(bd->charger);
}
ret = bd9995x_fw_probe(bd);
if (ret < 0) {
dev_err(dev, "Cannot read device properties.\n");
return ret;
}
ret = bd9995x_hw_init(bd);
if (ret < 0) {
dev_err(dev, "Cannot initialize the chip.\n");
return ret;
}
ret = devm_add_action_or_reset(dev, bd9995x_chip_reset, bd);
if (ret)
return ret;
return devm_request_threaded_irq(dev, client->irq, NULL,
bd9995x_irq_handler_thread,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
BD9995X_IRQ_PIN, bd);
}
static const struct of_device_id bd9995x_of_match[] = {
{ .compatible = "rohm,bd99954", },
{ }
};
MODULE_DEVICE_TABLE(of, bd9995x_of_match);
static struct i2c_driver bd9995x_driver = {
.driver = {
.name = "bd9995x-charger",
.of_match_table = bd9995x_of_match,
},
.probe_new = bd9995x_probe,
};
module_i2c_driver(bd9995x_driver);
MODULE_AUTHOR("Laine Markus <markus.laine@fi.rohmeurope.com>");
MODULE_DESCRIPTION("ROHM BD99954 charger driver");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (C) 2020 ROHM Semiconductors */
#ifndef BD99954_CHARGER_H
#define BD99954_CHARGER_H
#include <linux/regmap.h>
#define BD9995X_MANUFACTURER "Rohm Semiconductor"
#define BD9995X_IRQ_PIN "bd9995x_irq"
#define BD9995X_VSYS_PRECHARGE_OFFSET_MV 200
#define BD99954_ID 0x346
#define BD99955_ID 0x221
#define BD99956_ID 0x331
/* Battery Charger Commands */
#define CHARGING_CURRENT 0x14
#define CHARGING_VOLTAGE 0x15
#define PROTECT_SET 0x3E
#define MAP_SET 0x3F
/* Extended commands */
#define CHGSTM_STATUS 0x100
#define VBAT_VSYS_STATUS 0x101
#define VBUS_VCC_STATUS 0x102
#define CHGOP_STATUS 0x103
#define WDT_STATUS 0x104
#define CUR_ILIM_VAL 0x105
#define SEL_ILIM_VAL 0x106
#define IBUS_LIM_SET 0x107
#define ICC_LIM_SET 0x108
#define IOTG_LIM_SET 0x109
#define VIN_CTRL_SET 0x10A
#define CHGOP_SET1 0x10B
#define CHGOP_SET2 0x10C
#define VBUSCLPS_TH_SET 0x10D
#define VCCCLPS_TH_SET 0x10E
#define CHGWDT_SET 0x10F
#define BATTWDT_SET 0x110
#define VSYSREG_SET 0x111
#define VSYSVAL_THH_SET 0x112
#define VSYSVAL_THL_SET 0x113
#define ITRICH_SET 0x114
#define IPRECH_SET 0x115
#define ICHG_SET 0x116
#define ITERM_SET 0x117
#define VPRECHG_TH_SET 0x118
#define VRBOOST_SET 0x119
#define VFASTCHG_REG_SET1 0x11A
#define VFASTCHG_REG_SET2 0x11B
#define VFASTCHG_REG_SET3 0x11C
#define VRECHG_SET 0x11D
#define VBATOVP_SET 0x11E
#define IBATSHORT_SET 0x11F
#define PROCHOT_CTRL_SET 0x120
#define PROCHOT_ICRIT_SET 0x121
#define PROCHOT_INORM_SET 0x122
#define PROCHOT_IDCHG_SET 0x123
#define PROCHOT_VSYS_SET 0x124
#define PMON_IOUT_CTRL_SET 0x125
#define PMON_DACIN_VAL 0x126
#define IOUT_DACIN_VAL 0x127
#define VCC_UCD_SET 0x128
#define VCC_UCD_STATUS 0x129
#define VCC_IDD_STATUS 0x12A
#define VCC_UCD_FCTRL_SET 0x12B
#define VCC_UCD_FCTRL_EN 0x12C
#define VBUS_UCD_SET 0x130
#define VBUS_UCD_STATUS 0x131
#define VBUS_IDD_STATUS 0x132
#define VBUS_UCD_FCTRL_SET 0x133
#define VBUS_UCD_FCTRL_EN 0x134
#define CHIP_ID 0x138
#define CHIP_REV 0x139
#define IC_SET1 0x13A
#define IC_SET2 0x13B
#define SYSTEM_STATUS 0x13C
#define SYSTEM_CTRL_SET 0x13D
#define VM_CTRL_SET 0x140
#define THERM_WINDOW_SET1 0x141
#define THERM_WINDOW_SET2 0x142
#define THERM_WINDOW_SET3 0x143
#define THERM_WINDOW_SET4 0x144
#define THERM_WINDOW_SET5 0x145
#define IBATP_TH_SET 0x146
#define IBATM_TH_SET 0x147
#define VBAT_TH_SET 0x148
#define THERM_TH_SET 0x149
#define IACP_TH_SET 0x14A
#define VACP_TH_SET 0x14B
#define VBUS_TH_SET 0x14C
#define VCC_TH_SET 0x14D
#define VSYS_TH_SET 0x14E
#define EXTIADP_TH_SET 0x14F
#define IBATP_VAL 0x150
#define IBATP_AVE_VAL 0x151
#define IBATM_VAL 0x152
#define IBATM_AVE_VAL 0x153
#define VBAT_VAL 0x154
#define VBAT_AVE_VAL 0x155
#define THERM_VAL 0x156
#define VTH_VAL 0x157
#define IACP_VAL 0x158
#define IACP_AVE_VAL 0x159
#define VACP_VAL 0x15A
#define VACP_AVE_VAL 0x15B
#define VBUS_VAL 0x15C
#define VBUS_AVE_VAL 0x15D
#define VCC_VAL 0x15E
#define VCC_AVE_VAL 0x15F
#define VSYS_VAL 0x160
#define VSYS_AVE_VAL 0x161
#define EXTIADP_VAL 0x162
#define EXTIADP_AVE_VAL 0x163
#define VACPCLPS_TH_SET 0x164
#define INT0_SET 0x168
#define INT1_SET 0x169
#define INT2_SET 0x16A
#define INT3_SET 0x16B
#define INT4_SET 0x16C
#define INT5_SET 0x16D
#define INT6_SET 0x16E
#define INT7_SET 0x16F
#define INT0_STATUS 0x170
#define INT1_STATUS 0x171
#define INT2_STATUS 0x172
#define INT3_STATUS 0x173
#define INT4_STATUS 0x174
#define INT5_STATUS 0x175
#define INT6_STATUS 0x176
#define INT7_STATUS 0x177
#define OTPREG0 0x17A
#define OTPREG1 0x17B
#define SMBREG 0x17C
#define DEBUG_MODE_SET 0x17F
#define DEBUG0x14 0x214
#define DEBUG0x1A 0x21A
enum bd9995x_fields {
F_PREV_CHGSTM_STATE, F_CHGSTM_STATE,
F_VBAT_VSYS_STATUS,
F_VBUS_VCC_STATUS,
F_BATTEMP, F_VRECHG_DET, F_RBOOST_UV, F_RBOOSTS,
F_THERMWDT_VAL, F_CHGWDT_VAL,
F_CUR_ILIM_VAL,
F_SEL_ILIM_VAL,
F_IBUS_LIM_SET,
F_ICC_LIM_SET,
F_IOTG_LIM_SET,
F_OTG_BOTH_EN,
F_VRBOOST_TRIG,
F_VRBOOST_EN,
F_PP_BOTH_THRU,
F_VIN_ORD,
F_VBUS_EN,
F_VCC_EN,
F_VSYS_PRIORITY,
F_PPC_SUB_CAP,
F_PPC_CAP,
F_DCP_2500_SEL,
F_SDP_500_SEL,
F_ILIM_AUTO_DISEN,
F_VCC_BC_DISEN,
F_VBUS_BC_DISEN,
F_SDP_CHG_TRIG_EN,
F_SDP_CHG_TRIG,
F_AUTO_TOF,
F_AUTO_FST,
F_AUTO_RECH,
F_ILIM_RESET_EN,
F_DCDC_1MS_SEL,
F_SEL_ILIM_DIV,
F_BATT_LEARN,
F_CHG_EN,
F_USB_SUS,
F_CHOP_SS_INIT,
F_CHOP_ALL_INIT,
F_DCDC_CLK_SEL,
F_CHOP_SS,
F_CHOP_ALL,
F_VBUSCLPS_TH_SET,
F_VCCCLPS_TH_SET,
F_WDT_FST,
F_WDT_PRE,
F_WDT_IBAT_SHORT,
F_WDT_THERM,
F_VSYSREG_SET,
F_VSYSVAL_THH_SET,
F_VSYSVAL_THL_SET,
F_ITRICH_SET,
F_IPRECH_SET,
F_ICHG_SET,
F_ITERM_SET,
F_VPRECHG_TH_SET,
F_VRBOOST_SET,
F_VFASTCHG_REG_SET1,
F_VFASTCHG_REG_SET2,
F_VFASTCHG_REG_SET3,
F_VRECHG_SET,
F_VBATOVP_SET,
F_IBATM_SHORT_SET,
F_PROCHOT_DG_SET,
F_PROCHOT_ICRIT_DG_SET,
F_PROCHOT_IDCHG_DG_SET,
F_PROCHOT_EN,
F_PROCHOT_ICRIT_SET,
F_PROCHOT_INORM_SET,
F_PROCHOT_IDCHG_SET,
F_PROCHOT_VSYS_SET,
F_IMON_INSEL,
F_PMON_INSEL,
F_IOUT_OUT_EN,
F_IOUT_SOURCE_SEL,
F_IOUT_GAIN_SET,
F_PMON_OUT_EN,
F_PMON_GAIN_SET,
F_PMON_DACIN_VAL,
F_IOUT_DACIN_VAL,
F_VCC_BCSRETRY,
F_VCC_ADCRTRY,
F_VCC_USBDETEN,
F_VCC_IDRDETEN,
F_VCC_ENUMRDY,
F_VCC_ADCPOLEN,
F_VCC_DCDMODE,
F_VCC_USB_SW_EN,
F_VCC_USB_SW,
F_VCC_DCDFAIL,
F_VCC_CHGPORT,
F_VCC_PUPDET,
F_VCC_VBUS_VLD,
F_VCC_CHGDET,
F_VCC_OTGDET,
F_VCC_VBINOP,
F_VCC_EXTID,
F_VCC_IDRDET,
F_VCC_INDO,
F_VCC_UCDSWEN,
F_VCC_RREF_EN,
F_VCC_DPPU_EN,
F_VCC_DPREF_EN,
F_VCC_DMREF_EN,
F_VCC_DPDET_EN,
F_VCC_DMDET_EN,
F_VCC_DPSINK_EN,
F_VCC_DMSINK_EN,
F_VCC_DP_BUFF_EN,
F_VCC_DM_BUFF_EN,
F_VCC_EXTCLKENBL,
F_VCC_PLSTESTEN,
F_VCC_UCDSWEN_TSTENB,
F_VCC_RREF_EN_TSTENB,
F_VCC_DPPU_EN_TSTENB,
F_VCC_DPREF_EN_TSTENB,
F_VCC_DMREF_EN_TSTENB,
F_VCC_DPDET_EN_TSTENB,
F_VCC_DMDET_EN_TSTENB,
F_VCC_DPSINK_EN_TSTENB,
F_VCC_DMSINK_EN_TSTENB,
F_VCC_DP_BUFF_EN_TSTENB,
F_VCC_DM_BUFF_EN_TSTENB,
F_VBUS_BCSRETRY,
F_VBUS_ADCRTRY,
F_VBUS_USBDETEN,
F_VBUS_IDRDETEN,
F_VBUS_ENUMRDY,
F_VBUS_ADCPOLEN,
F_VBUS_DCDMODE,
F_VBUS_USB_SW_EN,
F_VBUS_USB_SW,
F_VBUS_DCDFAIL,
F_VBUS_CHGPORT,
F_VBUS_PUPDET,
F_VBUS_VBUS_VLD,
F_VBUS_CHGDET,
F_VBUS_OTGDET,
F_VBUS_VBINOP,
F_VBUS_EXTID,
F_VBUS_IDRDET,
F_VBUS_INDO,
F_VBUS_UCDSWEN,
F_VBUS_RREF_EN,
F_VBUS_DPPU_EN,
F_VBUS_DPREF_EN,
F_VBUS_DMREF_EN,
F_VBUS_DPDET_EN,
F_VBUS_DMDET_EN,
F_VBUS_DPSINK_EN,
F_VBUS_DMSINK_EN,
F_VBUS_DP_BUFF_EN,
F_VBUS_DM_BUFF_EN,
F_VBUS_EXTCLKENBL,
F_VBUS_PLSTESTEN,
F_VBUS_UCDSWEN_TSTENB,
F_VBUS_RREF_EN_TSTENB,
F_VBUS_DPPU_EN_TSTENB,
F_VBUS_DPREF_EN_TSTENB,
F_VBUS_DMREF_EN_TSTENB,
F_VBUS_DPDET_EN_TSTENB,
F_VBUS_DMDET_EN_TSTENB,
F_VBUS_DPSINK_EN_TSTENB,
F_VBUS_DMSINK_EN_TSTENB,
F_VBUS_DP_BUFF_EN_TSTENB,
F_VBUS_DM_BUFF_EN_TSTENB,
F_CHIP_ID,
F_CHIP_REV,
F_ONE_CELL_MODE,
F_cell,
F_VACP_AUTO_DISCHG,
F_VACP_LOAD,
F_ACOK_POL,
F_ACOK_DISEN,
F_DEBUG_SET1,
F_DEBUG_SET0,
F_MONRST_STATE,
F_ALMRST_STATE,
F_CHGRST_STATE,
F_OTPLD_STATE,
F_ALLRST_STATE,
F_PROTECT_SET,
F_MAP_SET,
F_ADCINTERVAL,
F_ADCMOD,
F_ADCTMOD,
F_EXTIADPEN,
F_VSYSENB,
F_VCCENB,
F_VBUSENB,
F_VACPENB,
F_IACPENB,
F_THERMENB,
F_VBATENB,
F_IBATMENB,
F_IBATPENB,
F_TMPTHR1B,
F_TMPTHR1A,
F_TMPTHR2B,
F_TMPTHR2A,
F_TMPTHR3B,
F_TMPTHR3A,
F_TMPTHR4B,
F_TMPTHR4A,
F_TMPTHR5B,
F_TMPTHR5A,
F_IBATP_TH_SET,
F_IBATM_TH_SET,
F_VBAT_TH_SET,
F_THERM_TH_SET,
F_IACP_TH_SET,
F_VACP_TH_SET,
F_VBUS_TH_SET,
F_VCC_TH_SET,
F_VSYS_TH_SET,
F_EXTIADP_TH_SET,
F_IBATP_VAL,
F_IBATP_AVE_VAL,
F_IBATM_VAL,
F_IBATM_AVE_VAL,
F_VBAT_VAL,
F_VBAT_AVE_VAL,
F_THERM_VAL,
F_VTH_VAL,
F_IACP_VAL,
F_IACP_AVE_VAL,
F_VACP_VAL,
F_VACP_AVE_VAL,
F_VBUS_VAL,
F_VBUS_AVE_VAL,
F_VCC_VAL,
F_VCC_AVE_VAL,
F_VSYS_VAL,
F_VSYS_AVE_VAL,
F_EXTIADP_VAL,
F_EXTIADP_AVE_VAL,
F_VACPCLPS_TH_SET,
F_INT7_SET,
F_INT6_SET,
F_INT5_SET,
F_INT4_SET,
F_INT3_SET,
F_INT2_SET,
F_INT1_SET,
F_INT0_SET,
F_VBUS_RBUV_DET,
F_VBUS_RBUV_RES,
F_VBUS_TH_DET,
F_VBUS_TH_RES,
F_VBUS_IIN_MOD,
F_VBUS_OV_DET,
F_VBUS_OV_RES,
F_VBUS_CLPS_DET,
F_VBUS_CLPS,
F_VBUS_DET,
F_VBUS_RES,
F_VCC_RBUV_DET,
F_VCC_RBUV_RES,
F_VCC_TH_DET,
F_VCC_TH_RES,
F_VCC_IIN_MOD,
F_VCC_OVP_DET,
F_VCC_OVP_RES,
F_VCC_CLPS_DET,
F_VCC_CLPS_RES,
F_VCC_DET,
F_VCC_RES,
F_TH_DET,
F_TH_RMV,
F_TMP_OUT_DET,
F_TMP_OUT_RES,
F_VBAT_TH_DET,
F_VBAT_TH_RES,
F_IBAT_SHORT_DET,
F_IBAT_SHORT_RES,
F_VBAT_OV_DET,
F_VBAT_OV_RES,
F_BAT_ASSIST_DET,
F_BAT_ASSIST_RES,
F_VSYS_TH_DET,
F_VSYS_TH_RES,
F_VSYS_OV_DET,
F_VSYS_OV_RES,
F_VSYS_SHT_DET,
F_VSYS_SHT_RES,
F_VSYS_UV_DET,
F_VSYS_UV_RES,
F_OTP_LOAD_DONE,
F_PWR_ON,
F_EXTIADP_TRNS,
F_EXTIADP_TH_DET,
F_EXIADP_TH_RES,
F_BAT_MNT_DET,
F_BAT_MNT_RES,
F_TSD_DET,
F_TSD_RES,
F_CHGWDT_EXP,
F_THERMWDT_EXP,
F_TMP_TRNS,
F_CHG_TRNS,
F_VBUS_UCD_PORT_DET,
F_VBUS_UCD_UCHG_DET,
F_VBUS_UCD_URID_RMV,
F_VBUS_UCD_OTG_DET,
F_VBUS_UCD_URID_MOD,
F_VCC_UCD_PORT_DET,
F_VCC_UCD_UCHG_DET,
F_VCC_UCD_URID_RMV,
F_VCC_UCD_OTG_DET,
F_VCC_UCD_URID_MOD,
F_PROCHOT_DET,
F_PROCHOT_RES,
F_VACP_DET,
F_VACP_RES,
F_VACP_TH_DET,
F_VACP_TH_RES,
F_IACP_TH_DET,
F_IACP_THE_RES,
F_THERM_TH_DET,
F_THERM_TH_RES,
F_IBATM_TH_DET,
F_IBATM_TH_RES,
F_IBATP_TH_DET,
F_IBATP_TH_RES,
F_INT7_STATUS,
F_INT6_STATUS,
F_INT5_STATUS,
F_INT4_STATUS,
F_INT3_STATUS,
F_INT2_STATUS,
F_INT1_STATUS,
F_INT0_STATUS,
F_ILIM_DECREASE,
F_RESERVE_OTPREG1,
F_POWER_SAVE_MODE,
F_DEBUG_MODE_SET,
F_DEBUG0x14,
F_DEBUG0x1A,
F_MAX_FIELDS
};
static const struct reg_field bd9995x_reg_fields[] = {
[F_PREV_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 8, 14),
[F_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 0, 6),
[F_VBAT_VSYS_STATUS] = REG_FIELD(VBAT_VSYS_STATUS, 0, 15),
[F_VBUS_VCC_STATUS] = REG_FIELD(VBUS_VCC_STATUS, 0, 12),
[F_BATTEMP] = REG_FIELD(CHGOP_STATUS, 8, 10),
[F_VRECHG_DET] = REG_FIELD(CHGOP_STATUS, 6, 6),
[F_RBOOST_UV] = REG_FIELD(CHGOP_STATUS, 1, 1),
[F_RBOOSTS] = REG_FIELD(CHGOP_STATUS, 0, 0),
[F_THERMWDT_VAL] = REG_FIELD(WDT_STATUS, 8, 15),
[F_CHGWDT_VAL] = REG_FIELD(WDT_STATUS, 0, 7),
[F_CUR_ILIM_VAL] = REG_FIELD(CUR_ILIM_VAL, 0, 13),
[F_SEL_ILIM_VAL] = REG_FIELD(SEL_ILIM_VAL, 0, 13),
[F_IBUS_LIM_SET] = REG_FIELD(IBUS_LIM_SET, 5, 13),
[F_ICC_LIM_SET] = REG_FIELD(ICC_LIM_SET, 5, 13),
[F_IOTG_LIM_SET] = REG_FIELD(IOTG_LIM_SET, 5, 13),
[F_OTG_BOTH_EN] = REG_FIELD(VIN_CTRL_SET, 15, 15),
[F_VRBOOST_TRIG] = REG_FIELD(VIN_CTRL_SET, 14, 14),
[F_VRBOOST_EN] = REG_FIELD(VIN_CTRL_SET, 12, 13),
[F_PP_BOTH_THRU] = REG_FIELD(VIN_CTRL_SET, 11, 11),
[F_VIN_ORD] = REG_FIELD(VIN_CTRL_SET, 7, 7),
[F_VBUS_EN] = REG_FIELD(VIN_CTRL_SET, 6, 6),
[F_VCC_EN] = REG_FIELD(VIN_CTRL_SET, 5, 5),
[F_VSYS_PRIORITY] = REG_FIELD(VIN_CTRL_SET, 4, 4),
[F_PPC_SUB_CAP] = REG_FIELD(VIN_CTRL_SET, 2, 3),
[F_PPC_CAP] = REG_FIELD(VIN_CTRL_SET, 0, 1),
[F_DCP_2500_SEL] = REG_FIELD(CHGOP_SET1, 15, 15),
[F_SDP_500_SEL] = REG_FIELD(CHGOP_SET1, 14, 14),
[F_ILIM_AUTO_DISEN] = REG_FIELD(CHGOP_SET1, 13, 13),
[F_VCC_BC_DISEN] = REG_FIELD(CHGOP_SET1, 11, 11),
[F_VBUS_BC_DISEN] = REG_FIELD(CHGOP_SET1, 10, 10),
[F_SDP_CHG_TRIG_EN] = REG_FIELD(CHGOP_SET1, 9, 9),
[F_SDP_CHG_TRIG] = REG_FIELD(CHGOP_SET1, 8, 8),
[F_AUTO_TOF] = REG_FIELD(CHGOP_SET1, 6, 6),
[F_AUTO_FST] = REG_FIELD(CHGOP_SET1, 5, 5),
[F_AUTO_RECH] = REG_FIELD(CHGOP_SET1, 3, 3),
[F_ILIM_RESET_EN] = REG_FIELD(CHGOP_SET2, 14, 14),
[F_DCDC_1MS_SEL] = REG_FIELD(CHGOP_SET2, 12, 13),
[F_SEL_ILIM_DIV] = REG_FIELD(CHGOP_SET2, 10, 10),
[F_BATT_LEARN] = REG_FIELD(CHGOP_SET2, 8, 8),
[F_CHG_EN] = REG_FIELD(CHGOP_SET2, 7, 7),
[F_USB_SUS] = REG_FIELD(CHGOP_SET2, 6, 6),
[F_CHOP_SS_INIT] = REG_FIELD(CHGOP_SET2, 5, 5),
[F_CHOP_ALL_INIT] = REG_FIELD(CHGOP_SET2, 4, 4),
[F_DCDC_CLK_SEL] = REG_FIELD(CHGOP_SET2, 2, 3),
[F_CHOP_SS] = REG_FIELD(CHGOP_SET2, 1, 1),
[F_CHOP_ALL] = REG_FIELD(CHGOP_SET2, 0, 0),
[F_VBUSCLPS_TH_SET] = REG_FIELD(VBUSCLPS_TH_SET, 7, 14),
[F_VCCCLPS_TH_SET] = REG_FIELD(VCCCLPS_TH_SET, 7, 14),
[F_WDT_FST] = REG_FIELD(CHGWDT_SET, 8, 15),
[F_WDT_PRE] = REG_FIELD(CHGWDT_SET, 0, 7),
[F_WDT_IBAT_SHORT] = REG_FIELD(BATTWDT_SET, 8, 15),
[F_WDT_THERM] = REG_FIELD(BATTWDT_SET, 0, 7),
[F_VSYSREG_SET] = REG_FIELD(VSYSREG_SET, 6, 14),
[F_VSYSVAL_THH_SET] = REG_FIELD(VSYSVAL_THH_SET, 6, 14),
[F_VSYSVAL_THL_SET] = REG_FIELD(VSYSVAL_THL_SET, 6, 14),
[F_ITRICH_SET] = REG_FIELD(ITRICH_SET, 6, 10),
[F_IPRECH_SET] = REG_FIELD(IPRECH_SET, 6, 10),
[F_ICHG_SET] = REG_FIELD(ICHG_SET, 6, 13),
[F_ITERM_SET] = REG_FIELD(ITERM_SET, 6, 10),
[F_VPRECHG_TH_SET] = REG_FIELD(VPRECHG_TH_SET, 6, 14),
[F_VRBOOST_SET] = REG_FIELD(VRBOOST_SET, 6, 14),
[F_VFASTCHG_REG_SET1] = REG_FIELD(VFASTCHG_REG_SET1, 4, 14),
[F_VFASTCHG_REG_SET2] = REG_FIELD(VFASTCHG_REG_SET2, 4, 14),
[F_VFASTCHG_REG_SET3] = REG_FIELD(VFASTCHG_REG_SET3, 4, 14),
[F_VRECHG_SET] = REG_FIELD(VRECHG_SET, 4, 14),
[F_VBATOVP_SET] = REG_FIELD(VBATOVP_SET, 4, 14),
[F_IBATM_SHORT_SET] = REG_FIELD(IBATSHORT_SET, 0, 14),
[F_PROCHOT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 14, 15),
[F_PROCHOT_ICRIT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 10, 11),
[F_PROCHOT_IDCHG_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 8, 9),
[F_PROCHOT_EN] = REG_FIELD(PROCHOT_CTRL_SET, 0, 4),
[F_PROCHOT_ICRIT_SET] = REG_FIELD(PROCHOT_ICRIT_SET, 0, 14),
[F_PROCHOT_INORM_SET] = REG_FIELD(PROCHOT_INORM_SET, 0, 14),
[F_PROCHOT_IDCHG_SET] = REG_FIELD(PROCHOT_IDCHG_SET, 0, 14),
[F_PROCHOT_VSYS_SET] = REG_FIELD(PROCHOT_VSYS_SET, 0, 14),
[F_IMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 9, 9),
[F_PMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 8, 8),
[F_IOUT_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 7, 7),
[F_IOUT_SOURCE_SEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 6, 6),
[F_IOUT_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 4, 5),
[F_PMON_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 3, 3),
[F_PMON_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 0, 2),
[F_PMON_DACIN_VAL] = REG_FIELD(PMON_DACIN_VAL, 0, 9),
[F_IOUT_DACIN_VAL] = REG_FIELD(IOUT_DACIN_VAL, 0, 11),
[F_VCC_BCSRETRY] = REG_FIELD(VCC_UCD_SET, 12, 12),
[F_VCC_ADCRTRY] = REG_FIELD(VCC_UCD_SET, 8, 8),
[F_VCC_USBDETEN] = REG_FIELD(VCC_UCD_SET, 7, 7),
[F_VCC_IDRDETEN] = REG_FIELD(VCC_UCD_SET, 6, 6),
[F_VCC_ENUMRDY] = REG_FIELD(VCC_UCD_SET, 5, 5),
[F_VCC_ADCPOLEN] = REG_FIELD(VCC_UCD_SET, 4, 4),
[F_VCC_DCDMODE] = REG_FIELD(VCC_UCD_SET, 3, 3),
[F_VCC_USB_SW_EN] = REG_FIELD(VCC_UCD_SET, 1, 1),
[F_VCC_USB_SW] = REG_FIELD(VCC_UCD_SET, 0, 0),
[F_VCC_DCDFAIL] = REG_FIELD(VCC_UCD_STATUS, 15, 15),
[F_VCC_CHGPORT] = REG_FIELD(VCC_UCD_STATUS, 12, 13),
[F_VCC_PUPDET] = REG_FIELD(VCC_UCD_STATUS, 11, 11),
[F_VCC_VBUS_VLD] = REG_FIELD(VCC_UCD_STATUS, 7, 7),
[F_VCC_CHGDET] = REG_FIELD(VCC_UCD_STATUS, 6, 6),
[F_VCC_OTGDET] = REG_FIELD(VCC_UCD_STATUS, 3, 3),
[F_VCC_VBINOP] = REG_FIELD(VCC_IDD_STATUS, 6, 6),
[F_VCC_EXTID] = REG_FIELD(VCC_IDD_STATUS, 5, 5),
[F_VCC_IDRDET] = REG_FIELD(VCC_IDD_STATUS, 4, 4),
[F_VCC_INDO] = REG_FIELD(VCC_IDD_STATUS, 0, 3),
[F_VCC_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10),
[F_VCC_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9),
[F_VCC_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8),
[F_VCC_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7),
[F_VCC_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6),
[F_VCC_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5),
[F_VCC_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4),
[F_VCC_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3),
[F_VCC_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2),
[F_VCC_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1),
[F_VCC_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0),
[F_VCC_EXTCLKENBL] = REG_FIELD(VCC_UCD_FCTRL_EN, 15, 15),
[F_VCC_PLSTESTEN] = REG_FIELD(VCC_UCD_FCTRL_EN, 14, 14),
[F_VCC_UCDSWEN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 10, 10),
[F_VCC_RREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 9, 9),
[F_VCC_DPPU_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 8, 8),
[F_VCC_DPREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 7, 7),
[F_VCC_DMREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 6, 6),
[F_VCC_DPDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 5, 5),
[F_VCC_DMDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 4, 4),
[F_VCC_DPSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 3, 3),
[F_VCC_DMSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 2, 2),
[F_VCC_DP_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 1, 1),
[F_VCC_DM_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 0, 0),
[F_VBUS_BCSRETRY] = REG_FIELD(VBUS_UCD_SET, 12, 12),
[F_VBUS_ADCRTRY] = REG_FIELD(VBUS_UCD_SET, 8, 8),
[F_VBUS_USBDETEN] = REG_FIELD(VBUS_UCD_SET, 7, 7),
[F_VBUS_IDRDETEN] = REG_FIELD(VBUS_UCD_SET, 6, 6),
[F_VBUS_ENUMRDY] = REG_FIELD(VBUS_UCD_SET, 5, 5),
[F_VBUS_ADCPOLEN] = REG_FIELD(VBUS_UCD_SET, 4, 4),
[F_VBUS_DCDMODE] = REG_FIELD(VBUS_UCD_SET, 3, 3),
[F_VBUS_USB_SW_EN] = REG_FIELD(VBUS_UCD_SET, 1, 1),
[F_VBUS_USB_SW] = REG_FIELD(VBUS_UCD_SET, 0, 0),
[F_VBUS_DCDFAIL] = REG_FIELD(VBUS_UCD_STATUS, 15, 15),
[F_VBUS_CHGPORT] = REG_FIELD(VBUS_UCD_STATUS, 12, 13),
[F_VBUS_PUPDET] = REG_FIELD(VBUS_UCD_STATUS, 11, 11),
[F_VBUS_VBUS_VLD] = REG_FIELD(VBUS_UCD_STATUS, 7, 7),
[F_VBUS_CHGDET] = REG_FIELD(VBUS_UCD_STATUS, 6, 6),
[F_VBUS_OTGDET] = REG_FIELD(VBUS_UCD_STATUS, 3, 3),
[F_VBUS_VBINOP] = REG_FIELD(VBUS_IDD_STATUS, 6, 6),
[F_VBUS_EXTID] = REG_FIELD(VBUS_IDD_STATUS, 5, 5),
[F_VBUS_IDRDET] = REG_FIELD(VBUS_IDD_STATUS, 4, 4),
[F_VBUS_INDO] = REG_FIELD(VBUS_IDD_STATUS, 0, 3),
[F_VBUS_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10),
[F_VBUS_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9),
[F_VBUS_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8),
[F_VBUS_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7),
[F_VBUS_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6),
[F_VBUS_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5),
[F_VBUS_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4),
[F_VBUS_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3),
[F_VBUS_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2),
[F_VBUS_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1),
[F_VBUS_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0),
[F_VBUS_EXTCLKENBL] = REG_FIELD(VBUS_UCD_FCTRL_EN, 15, 15),
[F_VBUS_PLSTESTEN] = REG_FIELD(VBUS_UCD_FCTRL_EN, 14, 14),
[F_VBUS_UCDSWEN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 10, 10),
[F_VBUS_RREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 9, 9),
[F_VBUS_DPPU_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 8, 8),
[F_VBUS_DPREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 7, 7),
[F_VBUS_DMREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 6, 6),
[F_VBUS_DPDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 5, 5),
[F_VBUS_DMDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 4, 4),
[F_VBUS_DPSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 3, 3),
[F_VBUS_DMSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 2, 2),
[F_VBUS_DP_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 1, 1),
[F_VBUS_DM_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 0, 0),
[F_CHIP_ID] = REG_FIELD(CHIP_ID, 0, 15),
[F_CHIP_REV] = REG_FIELD(CHIP_REV, 0, 15),
[F_ONE_CELL_MODE] = REG_FIELD(IC_SET1, 11, 11),
[F_cell] = REG_FIELD(IC_SET1, 1, 1),
[F_VACP_AUTO_DISCHG] = REG_FIELD(IC_SET1, 9, 9),
[F_VACP_LOAD] = REG_FIELD(IC_SET1, 8, 8),
[F_ACOK_POL] = REG_FIELD(IC_SET1, 1, 1),
[F_ACOK_DISEN] = REG_FIELD(IC_SET1, 0, 0),
[F_DEBUG_SET1] = REG_FIELD(IC_SET2, 4, 8),
[F_DEBUG_SET0] = REG_FIELD(IC_SET2, 0, 0),
[F_MONRST_STATE] = REG_FIELD(SYSTEM_STATUS, 6, 6),
[F_ALMRST_STATE] = REG_FIELD(SYSTEM_STATUS, 5, 5),
[F_CHGRST_STATE] = REG_FIELD(SYSTEM_STATUS, 4, 4),
[F_OTPLD_STATE] = REG_FIELD(SYSTEM_STATUS, 1, 1),
[F_ALLRST_STATE] = REG_FIELD(SYSTEM_STATUS, 0, 0),
[F_PROTECT_SET] = REG_FIELD(PROTECT_SET, 0, 15),
[F_MAP_SET] = REG_FIELD(MAP_SET, 0, 15),
[F_ADCINTERVAL] = REG_FIELD(VM_CTRL_SET, 14, 15),
[F_ADCMOD] = REG_FIELD(VM_CTRL_SET, 12, 13),
[F_ADCTMOD] = REG_FIELD(VM_CTRL_SET, 10, 11),
[F_EXTIADPEN] = REG_FIELD(VM_CTRL_SET, 9, 9),
[F_VSYSENB] = REG_FIELD(VM_CTRL_SET, 8, 8),
[F_VCCENB] = REG_FIELD(VM_CTRL_SET, 7, 7),
[F_VBUSENB] = REG_FIELD(VM_CTRL_SET, 6, 6),
[F_VACPENB] = REG_FIELD(VM_CTRL_SET, 5, 5),
[F_IACPENB] = REG_FIELD(VM_CTRL_SET, 4, 4),
[F_THERMENB] = REG_FIELD(VM_CTRL_SET, 3, 3),
[F_VBATENB] = REG_FIELD(VM_CTRL_SET, 2, 2),
[F_IBATMENB] = REG_FIELD(VM_CTRL_SET, 1, 1),
[F_IBATPENB] = REG_FIELD(VM_CTRL_SET, 0, 0),
[F_TMPTHR1B] = REG_FIELD(THERM_WINDOW_SET1, 8, 15),
[F_TMPTHR1A] = REG_FIELD(THERM_WINDOW_SET1, 0, 7),
[F_TMPTHR2B] = REG_FIELD(THERM_WINDOW_SET2, 8, 15),
[F_TMPTHR2A] = REG_FIELD(THERM_WINDOW_SET2, 0, 7),
[F_TMPTHR3B] = REG_FIELD(THERM_WINDOW_SET3, 8, 15),
[F_TMPTHR3A] = REG_FIELD(THERM_WINDOW_SET3, 0, 7),
[F_TMPTHR4B] = REG_FIELD(THERM_WINDOW_SET4, 8, 15),
[F_TMPTHR4A] = REG_FIELD(THERM_WINDOW_SET4, 0, 7),
[F_TMPTHR5B] = REG_FIELD(THERM_WINDOW_SET5, 8, 15),
[F_TMPTHR5A] = REG_FIELD(THERM_WINDOW_SET5, 0, 7),
[F_IBATP_TH_SET] = REG_FIELD(IBATP_TH_SET, 0, 14),
[F_IBATM_TH_SET] = REG_FIELD(IBATM_TH_SET, 0, 14),
[F_VBAT_TH_SET] = REG_FIELD(VBAT_TH_SET, 0, 14),
[F_THERM_TH_SET] = REG_FIELD(THERM_TH_SET, 0, 7),
[F_IACP_TH_SET] = REG_FIELD(IACP_TH_SET, 0, 14),
[F_VACP_TH_SET] = REG_FIELD(VACP_TH_SET, 0, 14),
[F_VBUS_TH_SET] = REG_FIELD(VBUS_TH_SET, 0, 14),
[F_VCC_TH_SET] = REG_FIELD(VCC_TH_SET, 0, 14),
[F_VSYS_TH_SET] = REG_FIELD(VSYS_TH_SET, 0, 14),
[F_EXTIADP_TH_SET] = REG_FIELD(EXTIADP_TH_SET, 0, 11),
[F_IBATP_VAL] = REG_FIELD(IBATP_VAL, 0, 14),
[F_IBATP_AVE_VAL] = REG_FIELD(IBATP_AVE_VAL, 0, 14),
[F_IBATM_VAL] = REG_FIELD(IBATM_VAL, 0, 14),
[F_IBATM_AVE_VAL] = REG_FIELD(IBATM_AVE_VAL, 0, 14),
[F_VBAT_VAL] = REG_FIELD(VBAT_VAL, 0, 14),
[F_VBAT_AVE_VAL] = REG_FIELD(VBAT_AVE_VAL, 0, 14),
[F_THERM_VAL] = REG_FIELD(THERM_VAL, 0, 7),
[F_VTH_VAL] = REG_FIELD(VTH_VAL, 0, 11),
[F_IACP_VAL] = REG_FIELD(IACP_VAL, 0, 14),
[F_IACP_AVE_VAL] = REG_FIELD(IACP_AVE_VAL, 0, 14),
[F_VACP_VAL] = REG_FIELD(VACP_VAL, 0, 14),
[F_VACP_AVE_VAL] = REG_FIELD(VACP_AVE_VAL, 0, 14),
[F_VBUS_VAL] = REG_FIELD(VBUS_VAL, 0, 14),
[F_VBUS_AVE_VAL] = REG_FIELD(VBUS_AVE_VAL, 0, 14),
[F_VCC_VAL] = REG_FIELD(VCC_VAL, 0, 14),
[F_VCC_AVE_VAL] = REG_FIELD(VCC_AVE_VAL, 0, 14),
[F_VSYS_VAL] = REG_FIELD(VSYS_VAL, 0, 14),
[F_VSYS_AVE_VAL] = REG_FIELD(VSYS_AVE_VAL, 0, 14),
[F_EXTIADP_VAL] = REG_FIELD(EXTIADP_VAL, 0, 11),
[F_EXTIADP_AVE_VAL] = REG_FIELD(EXTIADP_AVE_VAL, 0, 11),
[F_VACPCLPS_TH_SET] = REG_FIELD(VACPCLPS_TH_SET, 7, 14),
[F_INT7_SET] = REG_FIELD(INT7_SET, 0, 15),
[F_INT6_SET] = REG_FIELD(INT6_SET, 0, 13),
[F_INT5_SET] = REG_FIELD(INT5_SET, 0, 13),
[F_INT4_SET] = REG_FIELD(INT4_SET, 0, 9),
[F_INT3_SET] = REG_FIELD(INT3_SET, 0, 15),
[F_INT2_SET] = REG_FIELD(INT2_SET, 0, 15),
[F_INT1_SET] = REG_FIELD(INT1_SET, 0, 15),
[F_INT0_SET] = REG_FIELD(INT0_SET, 0, 7),
[F_VBUS_RBUV_DET] = REG_FIELD(INT1_SET, 15, 15),
[F_VBUS_RBUV_RES] = REG_FIELD(INT1_SET, 14, 14),
[F_VBUS_TH_DET] = REG_FIELD(INT1_SET, 9, 9),
[F_VBUS_TH_RES] = REG_FIELD(INT1_SET, 8, 8),
[F_VBUS_IIN_MOD] = REG_FIELD(INT1_SET, 6, 6),
[F_VBUS_OV_DET] = REG_FIELD(INT1_SET, 5, 5),
[F_VBUS_OV_RES] = REG_FIELD(INT1_SET, 4, 4),
[F_VBUS_CLPS_DET] = REG_FIELD(INT1_SET, 3, 3),
[F_VBUS_CLPS] = REG_FIELD(INT1_SET, 2, 2),
[F_VBUS_DET] = REG_FIELD(INT1_SET, 1, 1),
[F_VBUS_RES] = REG_FIELD(INT1_SET, 0, 0),
[F_VCC_RBUV_DET] = REG_FIELD(INT2_SET, 15, 15),
[F_VCC_RBUV_RES] = REG_FIELD(INT2_SET, 14, 14),
[F_VCC_TH_DET] = REG_FIELD(INT2_SET, 9, 9),
[F_VCC_TH_RES] = REG_FIELD(INT2_SET, 8, 8),
[F_VCC_IIN_MOD] = REG_FIELD(INT2_SET, 6, 6),
[F_VCC_OVP_DET] = REG_FIELD(INT2_SET, 5, 5),
[F_VCC_OVP_RES] = REG_FIELD(INT2_SET, 4, 4),
[F_VCC_CLPS_DET] = REG_FIELD(INT2_SET, 3, 3),
[F_VCC_CLPS_RES] = REG_FIELD(INT2_SET, 2, 2),
[F_VCC_DET] = REG_FIELD(INT2_SET, 1, 1),
[F_VCC_RES] = REG_FIELD(INT2_SET, 0, 0),
[F_TH_DET] = REG_FIELD(INT3_SET, 15, 15),
[F_TH_RMV] = REG_FIELD(INT3_SET, 14, 14),
[F_TMP_OUT_DET] = REG_FIELD(INT3_SET, 11, 11),
[F_TMP_OUT_RES] = REG_FIELD(INT3_SET, 10, 10),
[F_VBAT_TH_DET] = REG_FIELD(INT3_SET, 9, 9),
[F_VBAT_TH_RES] = REG_FIELD(INT3_SET, 8, 8),
[F_IBAT_SHORT_DET] = REG_FIELD(INT3_SET, 7, 7),
[F_IBAT_SHORT_RES] = REG_FIELD(INT3_SET, 6, 6),
[F_VBAT_OV_DET] = REG_FIELD(INT3_SET, 5, 5),
[F_VBAT_OV_RES] = REG_FIELD(INT3_SET, 4, 4),
[F_BAT_ASSIST_DET] = REG_FIELD(INT3_SET, 3, 3),
[F_BAT_ASSIST_RES] = REG_FIELD(INT3_SET, 2, 2),
[F_VSYS_TH_DET] = REG_FIELD(INT4_SET, 9, 9),
[F_VSYS_TH_RES] = REG_FIELD(INT4_SET, 8, 8),
[F_VSYS_OV_DET] = REG_FIELD(INT4_SET, 5, 5),
[F_VSYS_OV_RES] = REG_FIELD(INT4_SET, 4, 4),
[F_VSYS_SHT_DET] = REG_FIELD(INT4_SET, 3, 3),
[F_VSYS_SHT_RES] = REG_FIELD(INT4_SET, 2, 2),
[F_VSYS_UV_DET] = REG_FIELD(INT4_SET, 1, 1),
[F_VSYS_UV_RES] = REG_FIELD(INT4_SET, 0, 0),
[F_OTP_LOAD_DONE] = REG_FIELD(INT5_SET, 13, 13),
[F_PWR_ON] = REG_FIELD(INT5_SET, 12, 12),
[F_EXTIADP_TRNS] = REG_FIELD(INT5_SET, 11, 11),
[F_EXTIADP_TH_DET] = REG_FIELD(INT5_SET, 9, 9),
[F_EXIADP_TH_RES] = REG_FIELD(INT5_SET, 8, 8),
[F_BAT_MNT_DET] = REG_FIELD(INT5_SET, 7, 7),
[F_BAT_MNT_RES] = REG_FIELD(INT5_SET, 6, 6),
[F_TSD_DET] = REG_FIELD(INT5_SET, 5, 5),
[F_TSD_RES] = REG_FIELD(INT5_SET, 4, 4),
[F_CHGWDT_EXP] = REG_FIELD(INT5_SET, 3, 3),
[F_THERMWDT_EXP] = REG_FIELD(INT5_SET, 2, 2),
[F_TMP_TRNS] = REG_FIELD(INT5_SET, 1, 1),
[F_CHG_TRNS] = REG_FIELD(INT5_SET, 0, 0),
[F_VBUS_UCD_PORT_DET] = REG_FIELD(INT6_SET, 13, 13),
[F_VBUS_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 12, 12),
[F_VBUS_UCD_URID_RMV] = REG_FIELD(INT6_SET, 11, 11),
[F_VBUS_UCD_OTG_DET] = REG_FIELD(INT6_SET, 10, 10),
[F_VBUS_UCD_URID_MOD] = REG_FIELD(INT6_SET, 8, 8),
[F_VCC_UCD_PORT_DET] = REG_FIELD(INT6_SET, 5, 5),
[F_VCC_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 4, 4),
[F_VCC_UCD_URID_RMV] = REG_FIELD(INT6_SET, 3, 3),
[F_VCC_UCD_OTG_DET] = REG_FIELD(INT6_SET, 2, 2),
[F_VCC_UCD_URID_MOD] = REG_FIELD(INT6_SET, 0, 0),
[F_PROCHOT_DET] = REG_FIELD(INT7_SET, 15, 15),
[F_PROCHOT_RES] = REG_FIELD(INT7_SET, 14, 14),
[F_VACP_DET] = REG_FIELD(INT7_SET, 11, 11),
[F_VACP_RES] = REG_FIELD(INT7_SET, 10, 10),
[F_VACP_TH_DET] = REG_FIELD(INT7_SET, 9, 9),
[F_VACP_TH_RES] = REG_FIELD(INT7_SET, 8, 8),
[F_IACP_TH_DET] = REG_FIELD(INT7_SET, 7, 7),
[F_IACP_THE_RES] = REG_FIELD(INT7_SET, 6, 6),
[F_THERM_TH_DET] = REG_FIELD(INT7_SET, 5, 5),
[F_THERM_TH_RES] = REG_FIELD(INT7_SET, 4, 4),
[F_IBATM_TH_DET] = REG_FIELD(INT7_SET, 3, 3),
[F_IBATM_TH_RES] = REG_FIELD(INT7_SET, 2, 2),
[F_IBATP_TH_DET] = REG_FIELD(INT7_SET, 1, 1),
[F_IBATP_TH_RES] = REG_FIELD(INT7_SET, 0, 0),
[F_INT7_STATUS] = REG_FIELD(INT7_STATUS, 0, 15),
[F_INT6_STATUS] = REG_FIELD(INT6_STATUS, 0, 13),
[F_INT5_STATUS] = REG_FIELD(INT5_STATUS, 0, 13),
[F_INT4_STATUS] = REG_FIELD(INT4_STATUS, 0, 9),
[F_INT3_STATUS] = REG_FIELD(INT3_STATUS, 0, 15),
[F_INT2_STATUS] = REG_FIELD(INT2_STATUS, 0, 15),
[F_INT1_STATUS] = REG_FIELD(INT1_STATUS, 0, 15),
[F_INT0_STATUS] = REG_FIELD(INT0_STATUS, 0, 7),
[F_ILIM_DECREASE] = REG_FIELD(OTPREG0, 0, 15),
[F_RESERVE_OTPREG1] = REG_FIELD(OTPREG1, 0, 15),
[F_POWER_SAVE_MODE] = REG_FIELD(SMBREG, 0, 15),
[F_DEBUG_MODE_SET] = REG_FIELD(DEBUG_MODE_SET, 0, 15),
[F_DEBUG0x14] = REG_FIELD(DEBUG0x14, 0, 15),
[F_DEBUG0x1A] = REG_FIELD(DEBUG0x1A, 0, 15),
};
/* CHGSTM_STATEs */
#define CHGSTM_SUSPEND 0x00
#define CHGSTM_TRICKLE_CHARGE 0x01
#define CHGSTM_PRE_CHARGE 0x02
#define CHGSTM_FAST_CHARGE 0x03
#define CHGSTM_TOP_OFF 0x04
#define CHGSTM_DONE 0x05
#define CHGSTM_OTG 0x08
#define CHGSTM_OTG_DONE 0x09
#define CHGSTM_TEMPERATURE_ERROR_1 0x10
#define CHGSTM_TEMPERATURE_ERROR_2 0x11
#define CHGSTM_TEMPERATURE_ERROR_3 0x12
#define CHGSTM_TEMPERATURE_ERROR_4 0x13
#define CHGSTM_TEMPERATURE_ERROR_5 0x14
#define CHGSTM_TEMPERATURE_ERROR_6 0x15
#define CHGSTM_TEMPERATURE_ERROR_7 0x18
#define CHGSTM_THERMAL_SHUT_DOWN_1 0x20
#define CHGSTM_THERMAL_SHUT_DOWN_2 0x21
#define CHGSTM_THERMAL_SHUT_DOWN_3 0x22
#define CHGSTM_THERMAL_SHUT_DOWN_4 0x23
#define CHGSTM_THERMAL_SHUT_DOWN_5 0x24
#define CHGSTM_THERMAL_SHUT_DOWN_6 0x25
#define CHGSTM_THERMAL_SHUT_DOWN_7 0x28
#define CHGSTM_BATTERY_ERROR 0x40
/* VBAT_VSYS_STATUS */
#define STATUS_VSYS_OV BIT(15)
#define STATUS_VSYS_SSD BIT(14)
#define STATUS_VSYS_SCP BIT(13)
#define STATUS_VSYS_UVN BIT(12)
#define STATUS_IBAT_SHORT BIT(6)
#define STATUS_VBAT_OV BIT(3)
#define STATUS_DEAD_BAT BIT(0)
/* VBUS_VCC_STATUS */
#define STATUS_VACP_DET BIT(12)
#define STATUS_VCC_OVP BIT(11)
#define STATUS_ILIM_VCC_MOD BIT(10)
#define STATUS_VCC_CLPS BIT(9)
#define STATUS_VCC_DET BIT(8)
#define STATUS_VBUS_OVP BIT(3)
#define STATUS_ILIM_VBUS_MOD BIT(2)
#define STATUS_VBUS_CLPS BIT(1)
#define STATUS_VBUS_DET BIT(0)
/* Interrupt set/status definitions */
/* INT 0 */
#define INT0_INT7_STATUS BIT(7)
#define INT0_INT6_STATUS BIT(6)
#define INT0_INT5_STATUS BIT(5)
#define INT0_INT4_STATUS BIT(4)
#define INT0_INT3_STATUS BIT(3)
#define INT0_INT2_STATUS BIT(2)
#define INT0_INT1_STATUS BIT(1)
#define INT0_INT0_STATUS BIT(0)
#define INT0_ALL 0xff
/* INT 1 */
#define VBUS_RBUV_DET BIT(15)
#define VBUS_RBUV_RES BIT(14)
#define VBUS_TH_DET BIT(9)
#define VBUS_TH_RES BIT(8)
#define VBUS_IIN_MOD BIT(6)
#define VBUS_OV_DET BIT(5)
#define VBUS_OV_RES BIT(4)
#define VBUS_CLPS_DET BIT(3)
#define VBUS_CLPS BIT(2)
#define VBUS_DET BIT(1)
#define VBUS_RES BIT(0)
#define INT1_ALL (VBUS_RBUV_DET|\
VBUS_RBUV_RES|\
VBUS_TH_DET |\
VBUS_TH_RES |\
VBUS_IIN_MOD|\
VBUS_OV_DET |\
VBUS_OV_RES |\
VBUS_CLPS_DET |\
VBUS_CLPS |\
VBUS_DET |\
VBUS_RES)
/* INT 2 */
#define VCC_RBUV_DET BIT(15)
#define VCC_RBUV_RES BIT(14)
#define VCC_TH_DET BIT(9)
#define VCC_TH_RES BIT(8)
#define VCC_IIN_MOD BIT(6)
#define VCC_OVP_DET BIT(5)
#define VCC_OVP_RES BIT(4)
#define VCC_CLPS_DET BIT(3)
#define VCC_CLPS_RES BIT(2)
#define VCC_DET BIT(1)
#define VCC_RES BIT(0)
#define INT2_ALL (VCC_RBUV_DET |\
VCC_RBUV_RES |\
VCC_TH_DET |\
VCC_TH_RES |\
VCC_IIN_MOD |\
VCC_OVP_DET |\
VCC_OVP_RES |\
VCC_CLPS_DET |\
VCC_CLPS_RES |\
VCC_DET |\
VCC_RES)
/* INT 3 */
#define TH_DET BIT(15)
#define TH_RMV BIT(14)
#define TMP_OUT_DET BIT(11)
#define TMP_OUT_RES BIT(10)
#define VBAT_TH_DET BIT(9)
#define VBAT_TH_RES BIT(8)
#define IBAT_SHORT_DET BIT(7)
#define IBAT_SHORT_RES BIT(6)
#define VBAT_OV_DET BIT(5)
#define VBAT_OV_RES BIT(4)
#define BAT_ASSIST_DET BIT(3)
#define BAT_ASSIST_RES BIT(2)
#define INT3_ALL (TH_DET |\
TH_RMV |\
TMP_OUT_DET |\
TMP_OUT_RES |\
VBAT_TH_DET |\
VBAT_TH_RES |\
IBAT_SHORT_DET |\
IBAT_SHORT_RES |\
VBAT_OV_DET |\
VBAT_OV_RES |\
BAT_ASSIST_DET |\
BAT_ASSIST_RES)
/* INT 4 */
#define VSYS_TH_DET BIT(9)
#define VSYS_TH_RES BIT(8)
#define VSYS_OV_DET BIT(5)
#define VSYS_OV_RES BIT(4)
#define VSYS_SHT_DET BIT(3)
#define VSYS_SHT_RES BIT(2)
#define VSYS_UV_DET BIT(1)
#define VSYS_UV_RES BIT(0)
#define INT4_ALL (VSYS_TH_DET |\
VSYS_TH_RES |\
VSYS_OV_DET |\
VSYS_OV_RES |\
VSYS_SHT_DET |\
VSYS_SHT_RES |\
VSYS_UV_DET |\
VSYS_UV_RES)
/* INT 5*/
#define OTP_LOAD_DONE BIT(13)
#define PWR_ON BIT(12)
#define EXTIADP_TRNS BIT(11)
#define EXTIADP_TH_DET BIT(9)
#define EXIADP_TH_RES BIT(8)
#define BAT_MNT_DET BIT(7)
#define BAT_MNT_RES BIT(6)
#define TSD_DET BIT(5)
#define TSD_RES BIT(4)
#define CHGWDT_EXP BIT(3)
#define THERMWDT_EXP BIT(2)
#define TMP_TRNS BIT(1)
#define CHG_TRNS BIT(0)
#define INT5_ALL (OTP_LOAD_DONE |\
PWR_ON |\
EXTIADP_TRNS |\
EXTIADP_TH_DET |\
EXIADP_TH_RES |\
BAT_MNT_DET |\
BAT_MNT_RES |\
TSD_DET |\
TSD_RES |\
CHGWDT_EXP |\
THERMWDT_EXP |\
TMP_TRNS |\
CHG_TRNS)
/* INT 6*/
#define VBUS_UCD_PORT_DET BIT(13)
#define VBUS_UCD_UCHG_DET BIT(12)
#define VBUS_UCD_URID_RMV BIT(11)
#define VBUS_UCD_OTG_DET BIT(10)
#define VBUS_UCD_URID_MOD BIT(8)
#define VCC_UCD_PORT_DET BIT(5)
#define VCC_UCD_UCHG_DET BIT(4)
#define VCC_UCD_URID_RMV BIT(3)
#define VCC_UCD_OTG_DET BIT(2)
#define VCC_UCD_URID_MOD BIT(0)
#define INT6_ALL (VBUS_UCD_PORT_DET |\
VBUS_UCD_UCHG_DET |\
VBUS_UCD_URID_RMV |\
VBUS_UCD_OTG_DET |\
VBUS_UCD_URID_MOD |\
VCC_UCD_PORT_DET |\
VCC_UCD_UCHG_DET |\
VCC_UCD_URID_RMV |\
VCC_UCD_OTG_DET |\
VCC_UCD_URID_MOD)
/* INT 7 */
#define PROCHOT_DET BIT(15)
#define PROCHOT_RES BIT(14)
#define VACP_DET BIT(11)
#define VACP_RES BIT(10)
#define VACP_TH_DET BIT(9)
#define VACP_TH_RES BIT(8)
#define IACP_TH_DET BIT(7)
#define IACP_THE_RES BIT(6)
#define THERM_TH_DET BIT(5)
#define THERM_TH_RES BIT(4)
#define IBATM_TH_DET BIT(3)
#define IBATM_TH_RES BIT(2)
#define IBATP_TH_DET BIT(1)
#define IBATP_TH_RES BIT(0)
#define INT7_ALL (PROCHOT_DET |\
PROCHOT_RES |\
VACP_DET |\
VACP_RES |\
VACP_TH_DET |\
VACP_TH_RES |\
IACP_TH_DET |\
IACP_THE_RES |\
THERM_TH_DET |\
THERM_TH_RES |\
IBATM_TH_DET |\
IBATM_TH_RES |\
IBATP_TH_DET |\
IBATP_TH_RES)
/* SYSTEM_CTRL_SET*/
#define MONRST BIT(6)
#define ALMRST BIT(5)
#define CHGRST BIT(4)
#define OTPLD BIT(1)
#define ALLRST BIT(0)
/* F_BATTEMP */
#define ROOM 0x0
#define HOT1 0x1
#define HOT2 0x2
#define HOT3 0x3
#define COLD1 0x4
#define COLD2 0x5
#define TEMP_DIS 0x6
#define BATT_OPEN 0x7
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment