Skip to content

Commit

Permalink
sensor: bq274xx: add support for bq27427
Browse files Browse the repository at this point in the history
The current ID for BQ274XX_DEVICE_ID is actually the one for the
BQ27421. The driver seems to work with the BQ27427 as well, at least the
common and extended commands are the same, so add that variant as well,
rename the existing one and print the currently read ID when the ID
check fails.

The configuration registers have a different offset though, so add a
register offset table and make the device rcognize the right one un
runtime based on the device ID.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
  • Loading branch information
fabiobaltieri committed Jul 9, 2023
1 parent 687c3bb commit 542a931
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 22 deletions.
51 changes: 39 additions & 12 deletions drivers/sensor/bq274xx/bq274xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ LOG_MODULE_REGISTER(bq274xx, CONFIG_SENSOR_LOG_LEVEL);
/* Config update mode flag */
#define BQ27XXX_FLAG_CFGUP BIT(4)

static struct bq274xx_regs bq27421_regs = {
.dm_design_capacity = 10,
.dm_design_energy = 12,
.dm_terminate_voltage = 16,
.dm_taper_rate = 27,
};

static struct bq274xx_regs bq27427_regs = {
.dm_design_capacity = 6,
.dm_design_energy = 8,
.dm_terminate_voltage = 10,
.dm_taper_rate = 21,
};

static int bq274xx_cmd_reg_read(const struct device *dev, uint8_t reg_addr,
int16_t *val)
{
Expand Down Expand Up @@ -119,7 +133,6 @@ static int bq274xx_get_device_type(const struct device *dev, uint16_t *val)
}

ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_CONTROL_LOW, val);

if (ret < 0) {
LOG_ERR("Unable to read register");
return -EIO;
Expand All @@ -132,7 +145,7 @@ static int bq274xx_gauge_configure(const struct device *dev)
{
const struct bq274xx_config *const config = dev->config;
struct bq274xx_data *data = dev->data;

struct bq274xx_regs *regs = data->regs;
int ret;
uint8_t tmp_checksum, checksum_old, checksum_new;
uint16_t flags, designenergy_mwh, taperrate;
Expand Down Expand Up @@ -231,56 +244,65 @@ static int bq274xx_gauge_configure(const struct device *dev)
taperrate_msb = taperrate >> 8;
taperrate_lsb = taperrate & 0x00FF;

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_DESIGN_CAP_HIGH,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_HIGH(regs->dm_design_capacity),
designcap_msb);
if (ret < 0) {
LOG_ERR("Failed to write designCAP MSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_DESIGN_CAP_LOW,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_LOW(regs->dm_design_capacity),
designcap_lsb);
if (ret < 0) {
LOG_ERR("Failed to write designCAP LSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_DESIGN_ENR_HIGH,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_HIGH(regs->dm_design_energy),
designenergy_msb);
if (ret < 0) {
LOG_ERR("Failed to write designEnergy MSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_DESIGN_ENR_LOW,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_LOW(regs->dm_design_energy),
designenergy_lsb);
if (ret < 0) {
LOG_ERR("Failed to write designEnergy LSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_TERMINATE_VOLT_HIGH,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_HIGH(regs->dm_terminate_voltage),
terminatevolt_msb);
if (ret < 0) {
LOG_ERR("Failed to write terminateVolt MSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_TERMINATE_VOLT_LOW,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_LOW(regs->dm_terminate_voltage),
terminatevolt_lsb);
if (ret < 0) {
LOG_ERR("Failed to write terminateVolt LSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_TAPERRATE_HIGH,
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_HIGH(regs->dm_taper_rate),
taperrate_msb);
if (ret < 0) {
LOG_ERR("Failed to write taperRate MSB");
return -EIO;
}

ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_BLKDAT_TAPERRATE_LOW, taperrate_lsb);
ret = i2c_reg_write_byte_dt(&config->i2c,
BQ274XX_EXT_BLKDAT_LOW(regs->dm_taper_rate),
taperrate_lsb);
if (ret < 0) {
LOG_ERR("Failed to write taperRate LSB");
return -EIO;
Expand Down Expand Up @@ -570,6 +592,7 @@ static int bq274xx_sample_fetch(const struct device *dev, enum sensor_channel ch
static int bq274xx_gauge_init(const struct device *dev)
{
const struct bq274xx_config *const config = dev->config;
struct bq274xx_data *data = dev->data;
int ret;
uint16_t id;

Expand All @@ -591,8 +614,12 @@ static int bq274xx_gauge_init(const struct device *dev)
return -EIO;
}

if (id != BQ274XX_DEVICE_ID) {
LOG_ERR("Invalid Device");
if (id == BQ27421_DEVICE_ID) {
data->regs = &bq27421_regs;
} else if (id == BQ27427_DEVICE_ID) {
data->regs = &bq27427_regs;
} else {
LOG_ERR("Invalid Device ID: 0x%x", id);
return -EINVAL;
}

Expand Down
22 changes: 12 additions & 10 deletions drivers/sensor/bq274xx/bq274xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
/*** General Constant ***/
#define BQ274XX_UNSEAL_KEY_A 0x8000 /* Unseal code one on BQ27441-G1A and similar */
#define BQ274XX_UNSEAL_KEY_B 0x8000 /* Unseal code two on BQ27441-G1A and similar */
#define BQ274XX_DEVICE_ID 0x0421 /* Default device ID */
#define BQ27421_DEVICE_ID 0x0421
#define BQ27427_DEVICE_ID 0x0427

/*** Standard Commands ***/
#define BQ274XX_CMD_CONTROL_LOW 0x00 /* Control() low register */
Expand Down Expand Up @@ -68,18 +69,19 @@
#define BQ274XX_EXT_BLKDAT_END 0x5F /* BlockData_end() */
#define BQ274XX_EXT_CHECKSUM 0x60 /* BlockDataCheckSum() */
#define BQ274XX_EXT_DATA_CONTROL 0x61 /* BlockDataControl() */
#define BQ274XX_EXT_BLKDAT_DESIGN_CAP_HIGH 0x4A /* BlockData */
#define BQ274XX_EXT_BLKDAT_DESIGN_CAP_LOW 0x4B
#define BQ274XX_EXT_BLKDAT_DESIGN_ENR_HIGH 0x4C
#define BQ274XX_EXT_BLKDAT_DESIGN_ENR_LOW 0x4D
#define BQ274XX_EXT_BLKDAT_TERMINATE_VOLT_HIGH 0x50
#define BQ274XX_EXT_BLKDAT_TERMINATE_VOLT_LOW 0x51
#define BQ274XX_EXT_BLKDAT_TAPERRATE_HIGH 0x5B
#define BQ274XX_EXT_BLKDAT_TAPERRATE_LOW 0x5C
#define BQ274XX_EXT_BLKDAT_HIGH(off) (BQ274XX_EXT_BLKDAT_START + off)
#define BQ274XX_EXT_BLKDAT_LOW(off) (BQ274XX_EXT_BLKDAT_START + off + 1)

#define BQ274XX_DELAY 1000
/* Hold the register offset for a device variant. */
struct bq274xx_regs {
uint8_t dm_design_capacity;
uint8_t dm_design_energy;
uint8_t dm_terminate_voltage;
uint8_t dm_taper_rate;
};

struct bq274xx_data {
struct bq274xx_regs *regs;
bool configured;
uint16_t voltage;
int16_t avg_current;
Expand Down

0 comments on commit 542a931

Please sign in to comment.