Skip to content

Commit 2380710

Browse files
maxpowelnashif
authored andcommitted
drivers: Added fuel gauge max17048
Added support for fuel gauge max17048 Signed-off-by: Alvaro Garcia <maxpowel@gmail.com>
1 parent 8fb4a18 commit 2380710

File tree

22 files changed

+873
-0
lines changed

22 files changed

+873
-0
lines changed

drivers/fuel_gauge/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
add_subdirectory_ifdef(CONFIG_SBS_GAUGE_NEW_API sbs_gauge)
4+
add_subdirectory_ifdef(CONFIG_MAX17048 max17048)
45

56
zephyr_library_sources_ifdef(CONFIG_USERSPACE fuel_gauge_syscall_handlers.c)

drivers/fuel_gauge/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ config FUEL_GAUGE_INIT_PRIORITY
1919
help
2020
Battery fuel gauge initialization priority.
2121

22+
source "drivers/fuel_gauge/max17048/Kconfig"
23+
2224
source "drivers/fuel_gauge/sbs_gauge/Kconfig"
2325

2426
endif # FUEL_GAUGE
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources(max17048.c)
6+
7+
zephyr_include_directories_ifdef(CONFIG_EMUL_MAX17048 .)
8+
zephyr_library_sources_ifdef(CONFIG_EMUL_MAX17048 ./emul_max17048.c)

drivers/fuel_gauge/max17048/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MAX17048 Li-Ion battery fuel gauge
2+
3+
# Copyright (c) 2023, Alvaro Garcia <maxpowel@gmail.com>
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
7+
config MAX17048
8+
bool "MAX17048 Li-Po fuel gauge"
9+
default y
10+
depends on DT_HAS_MAXIM_MAX17048_ENABLED
11+
select I2C
12+
help
13+
Enable driver for the MAX17048 fuel gauge device.
14+
15+
config EMUL_MAX17048
16+
bool "Emulate an MAX17048 fuel gague"
17+
depends on EMUL
18+
help
19+
It provides readings which follow a simple sequence, thus allowing
20+
test code to check that things are working as expected.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright 2023, Alvaro Garcia <maxpowel@gmail.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Emulator for max17048 fuel gauge
7+
*/
8+
9+
10+
#define DT_DRV_COMPAT maxim_max17048
11+
12+
13+
#include <zephyr/logging/log.h>
14+
LOG_MODULE_REGISTER(maxim_max17048);
15+
16+
#include <zephyr/device.h>
17+
#include <zephyr/drivers/emul.h>
18+
#include <zephyr/drivers/i2c.h>
19+
#include <zephyr/drivers/i2c_emul.h>
20+
#include <zephyr/sys/byteorder.h>
21+
22+
#include "max17048.h"
23+
24+
/** Static configuration for the emulator */
25+
struct max17048_emul_cfg {
26+
/** I2C address of emulator */
27+
uint16_t addr;
28+
};
29+
30+
static int emul_max17048_reg_write(const struct emul *target, int reg, int val)
31+
{
32+
33+
return -EIO;
34+
}
35+
36+
static int emul_max17048_reg_read(const struct emul *target, int reg, int *val)
37+
{
38+
39+
switch (reg) {
40+
case REGISTER_VERSION:
41+
*val = 0x1000;
42+
break;
43+
case REGISTER_CRATE:
44+
*val = 0x4000;
45+
break;
46+
case REGISTER_SOC:
47+
*val = 0x3525;
48+
break;
49+
case REGISTER_VCELL:
50+
*val = 0x4387;
51+
break;
52+
default:
53+
LOG_ERR("Unknown register 0x%x read", reg);
54+
return -EIO;
55+
}
56+
LOG_INF("read 0x%x = 0x%x", reg, *val);
57+
58+
return 0;
59+
}
60+
61+
static int max17048_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
62+
int num_msgs, int addr)
63+
{
64+
/* Largely copied from emul_bmi160.c */
65+
struct max17048_emul_data *data;
66+
unsigned int val;
67+
int reg;
68+
int rc;
69+
70+
data = target->data;
71+
72+
__ASSERT_NO_MSG(msgs && num_msgs);
73+
74+
i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
75+
switch (num_msgs) {
76+
case 2:
77+
if (msgs->flags & I2C_MSG_READ) {
78+
LOG_ERR("Unexpected read");
79+
return -EIO;
80+
}
81+
if (msgs->len != 1) {
82+
LOG_ERR("Unexpected msg0 length %d", msgs->len);
83+
return -EIO;
84+
}
85+
reg = msgs->buf[0];
86+
87+
/* Now process the 'read' part of the message */
88+
msgs++;
89+
if (msgs->flags & I2C_MSG_READ) {
90+
switch (msgs->len - 1) {
91+
case 1:
92+
rc = emul_max17048_reg_read(target, reg, &val);
93+
if (rc) {
94+
/* Return before writing bad value to message buffer */
95+
return rc;
96+
}
97+
98+
/* SBS uses SMBus, which sends data in little-endian format. */
99+
sys_put_le16(val, msgs->buf);
100+
break;
101+
default:
102+
LOG_ERR("Unexpected msg1 length %d", msgs->len);
103+
return -EIO;
104+
}
105+
} else {
106+
/* We write a word (2 bytes by the SBS spec) */
107+
if (msgs->len != 2) {
108+
LOG_ERR("Unexpected msg1 length %d", msgs->len);
109+
}
110+
uint16_t value = sys_get_le16(msgs->buf);
111+
112+
rc = emul_max17048_reg_write(target, reg, value);
113+
}
114+
break;
115+
default:
116+
LOG_ERR("Invalid number of messages: %d", num_msgs);
117+
return -EIO;
118+
}
119+
120+
return rc;
121+
}
122+
123+
static const struct i2c_emul_api max17048_emul_api_i2c = {
124+
.transfer = max17048_emul_transfer_i2c,
125+
};
126+
127+
/**
128+
* Set up a new emulator (I2C)
129+
*
130+
* @param emul Emulation information
131+
* @param parent Device to emulate
132+
* @return 0 indicating success (always)
133+
*/
134+
static int emul_max17048_init(const struct emul *target, const struct device *parent)
135+
{
136+
ARG_UNUSED(target);
137+
ARG_UNUSED(parent);
138+
139+
return 0;
140+
}
141+
142+
/*
143+
* Main instantiation macro.
144+
*/
145+
#define MAX17048_EMUL(n) \
146+
static const struct max17048_emul_cfg max17048_emul_cfg_##n = { \
147+
.addr = DT_INST_REG_ADDR(n), \
148+
}; \
149+
EMUL_DT_INST_DEFINE(n, emul_max17048_init, NULL, \
150+
&max17048_emul_cfg_##n, &max17048_emul_api_i2c, NULL)
151+
152+
DT_INST_FOREACH_STATUS_OKAY(MAX17048_EMUL)

0 commit comments

Comments
 (0)