Skip to content

Commit

Permalink
drivers: Added fuel gauge max17048
Browse files Browse the repository at this point in the history
Added support for fuel gauge max17048

Signed-off-by: Alvaro Garcia <maxpowel@gmail.com>
  • Loading branch information
maxpowel authored and nashif committed Mar 22, 2023
1 parent 8fb4a18 commit 2380710
Show file tree
Hide file tree
Showing 22 changed files with 873 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/fuel_gauge/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: Apache-2.0

add_subdirectory_ifdef(CONFIG_SBS_GAUGE_NEW_API sbs_gauge)
add_subdirectory_ifdef(CONFIG_MAX17048 max17048)

zephyr_library_sources_ifdef(CONFIG_USERSPACE fuel_gauge_syscall_handlers.c)
2 changes: 2 additions & 0 deletions drivers/fuel_gauge/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ config FUEL_GAUGE_INIT_PRIORITY
help
Battery fuel gauge initialization priority.

source "drivers/fuel_gauge/max17048/Kconfig"

source "drivers/fuel_gauge/sbs_gauge/Kconfig"

endif # FUEL_GAUGE
8 changes: 8 additions & 0 deletions drivers/fuel_gauge/max17048/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

zephyr_library_sources(max17048.c)

zephyr_include_directories_ifdef(CONFIG_EMUL_MAX17048 .)
zephyr_library_sources_ifdef(CONFIG_EMUL_MAX17048 ./emul_max17048.c)
20 changes: 20 additions & 0 deletions drivers/fuel_gauge/max17048/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# MAX17048 Li-Ion battery fuel gauge

# Copyright (c) 2023, Alvaro Garcia <maxpowel@gmail.com>
# SPDX-License-Identifier: Apache-2.0


config MAX17048
bool "MAX17048 Li-Po fuel gauge"
default y
depends on DT_HAS_MAXIM_MAX17048_ENABLED
select I2C
help
Enable driver for the MAX17048 fuel gauge device.

config EMUL_MAX17048
bool "Emulate an MAX17048 fuel gague"
depends on EMUL
help
It provides readings which follow a simple sequence, thus allowing
test code to check that things are working as expected.
152 changes: 152 additions & 0 deletions drivers/fuel_gauge/max17048/emul_max17048.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright 2023, Alvaro Garcia <maxpowel@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*
* Emulator for max17048 fuel gauge
*/


#define DT_DRV_COMPAT maxim_max17048


#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(maxim_max17048);

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/sys/byteorder.h>

#include "max17048.h"

/** Static configuration for the emulator */
struct max17048_emul_cfg {
/** I2C address of emulator */
uint16_t addr;
};

static int emul_max17048_reg_write(const struct emul *target, int reg, int val)
{

return -EIO;
}

static int emul_max17048_reg_read(const struct emul *target, int reg, int *val)
{

switch (reg) {
case REGISTER_VERSION:
*val = 0x1000;
break;
case REGISTER_CRATE:
*val = 0x4000;
break;
case REGISTER_SOC:
*val = 0x3525;
break;
case REGISTER_VCELL:
*val = 0x4387;
break;
default:
LOG_ERR("Unknown register 0x%x read", reg);
return -EIO;
}
LOG_INF("read 0x%x = 0x%x", reg, *val);

return 0;
}

static int max17048_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
int num_msgs, int addr)
{
/* Largely copied from emul_bmi160.c */
struct max17048_emul_data *data;
unsigned int val;
int reg;
int rc;

data = target->data;

__ASSERT_NO_MSG(msgs && num_msgs);

i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
switch (num_msgs) {
case 2:
if (msgs->flags & I2C_MSG_READ) {
LOG_ERR("Unexpected read");
return -EIO;
}
if (msgs->len != 1) {
LOG_ERR("Unexpected msg0 length %d", msgs->len);
return -EIO;
}
reg = msgs->buf[0];

/* Now process the 'read' part of the message */
msgs++;
if (msgs->flags & I2C_MSG_READ) {
switch (msgs->len - 1) {
case 1:
rc = emul_max17048_reg_read(target, reg, &val);
if (rc) {
/* Return before writing bad value to message buffer */
return rc;
}

/* SBS uses SMBus, which sends data in little-endian format. */
sys_put_le16(val, msgs->buf);
break;
default:
LOG_ERR("Unexpected msg1 length %d", msgs->len);
return -EIO;
}
} else {
/* We write a word (2 bytes by the SBS spec) */
if (msgs->len != 2) {
LOG_ERR("Unexpected msg1 length %d", msgs->len);
}
uint16_t value = sys_get_le16(msgs->buf);

rc = emul_max17048_reg_write(target, reg, value);
}
break;
default:
LOG_ERR("Invalid number of messages: %d", num_msgs);
return -EIO;
}

return rc;
}

static const struct i2c_emul_api max17048_emul_api_i2c = {
.transfer = max17048_emul_transfer_i2c,
};

/**
* Set up a new emulator (I2C)
*
* @param emul Emulation information
* @param parent Device to emulate
* @return 0 indicating success (always)
*/
static int emul_max17048_init(const struct emul *target, const struct device *parent)
{
ARG_UNUSED(target);
ARG_UNUSED(parent);

return 0;
}

/*
* Main instantiation macro.
*/
#define MAX17048_EMUL(n) \
static const struct max17048_emul_cfg max17048_emul_cfg_##n = { \
.addr = DT_INST_REG_ADDR(n), \
}; \
EMUL_DT_INST_DEFINE(n, emul_max17048_init, NULL, \
&max17048_emul_cfg_##n, &max17048_emul_api_i2c, NULL)

DT_INST_FOREACH_STATUS_OKAY(MAX17048_EMUL)
Loading

0 comments on commit 2380710

Please sign in to comment.