fuel_gauge: sbs_gauge: Enable MFR ACC write
Update the SBS Gauge driver that implements the fuel_gauge API to implement a set_property function allowing the writing of an SBS word to the manufacturer access register per the SBS spec. Includes an update to the SBS Gauge emulator and SBS fuel gauge tests to weakly verify the code runs. Signed-off-by: Aaron Massey <aaronmassey@google.com>
This commit is contained in:
parent
48d5b6c1f1
commit
c4be38dec1
|
@ -35,6 +35,16 @@ static int sbs_cmd_reg_read(const struct device *dev, uint8_t reg_addr, uint16_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sbs_cmd_reg_write(const struct device *dev, uint8_t reg_addr, uint16_t val)
|
||||
{
|
||||
const struct sbs_gauge_config *config = dev->config;
|
||||
uint8_t buf[2];
|
||||
|
||||
sys_put_le16(val, buf);
|
||||
|
||||
return i2c_burst_write_dt(&config->i2c, reg_addr, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_get_property *prop)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -94,6 +104,27 @@ static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_get_pr
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_property *prop)
|
||||
{
|
||||
int rc = 0;
|
||||
uint16_t val = 0;
|
||||
|
||||
switch (prop->property_type) {
|
||||
|
||||
case FUEL_GAUGE_SBS_MFR_ACCESS:
|
||||
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS,
|
||||
prop->value.sbs_mfr_access_word);
|
||||
prop->value.sbs_mfr_access_word = val;
|
||||
break;
|
||||
default:
|
||||
rc = -ENOTSUP;
|
||||
}
|
||||
|
||||
prop->status = rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_get_property *props,
|
||||
size_t len)
|
||||
{
|
||||
|
@ -110,6 +141,22 @@ static int sbs_gauge_get_props(const struct device *dev, struct fuel_gauge_get_p
|
|||
return err_count;
|
||||
}
|
||||
|
||||
static int sbs_gauge_set_props(const struct device *dev, struct fuel_gauge_set_property *props,
|
||||
size_t len)
|
||||
{
|
||||
int err_count = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
int ret = sbs_gauge_set_prop(dev, props + i);
|
||||
|
||||
err_count += ret ? 1 : 0;
|
||||
}
|
||||
|
||||
err_count = (err_count == len) ? -1 : err_count;
|
||||
|
||||
return err_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialize the fuel gauge
|
||||
*
|
||||
|
@ -131,6 +178,7 @@ static int sbs_gauge_init(const struct device *dev)
|
|||
|
||||
static const struct battery_driver_api sbs_gauge_driver_api = {
|
||||
.get_property = &sbs_gauge_get_props,
|
||||
.set_property = &sbs_gauge_set_props,
|
||||
};
|
||||
|
||||
/* FIXME: fix init priority */
|
||||
|
|
|
@ -25,7 +25,7 @@ LOG_MODULE_REGISTER(sbs_sbs_gauge);
|
|||
|
||||
/** Run-time data used by the emulator */
|
||||
struct sbs_gauge_emul_data {
|
||||
/* Stub */
|
||||
uint16_t mfr_acc;
|
||||
};
|
||||
|
||||
/** Static configuration for the emulator */
|
||||
|
@ -36,10 +36,13 @@ struct sbs_gauge_emul_cfg {
|
|||
|
||||
static int emul_sbs_gauge_reg_write(const struct emul *target, int reg, int val)
|
||||
{
|
||||
ARG_UNUSED(target);
|
||||
struct sbs_gauge_emul_data *data = target->data;
|
||||
|
||||
LOG_INF("write %x = %x", reg, val);
|
||||
switch (reg) {
|
||||
case SBS_GAUGE_CMD_MANUFACTURER_ACCESS:
|
||||
data->mfr_acc = val;
|
||||
break;
|
||||
default:
|
||||
LOG_INF("Unknown write %x", reg);
|
||||
return -EIO;
|
||||
|
@ -50,10 +53,12 @@ static int emul_sbs_gauge_reg_write(const struct emul *target, int reg, int val)
|
|||
|
||||
static int emul_sbs_gauge_reg_read(const struct emul *target, int reg, int *val)
|
||||
{
|
||||
ARG_UNUSED(target);
|
||||
struct sbs_gauge_emul_data *data = target->data;
|
||||
|
||||
switch (reg) {
|
||||
case SBS_GAUGE_CMD_MANUFACTURER_ACCESS:
|
||||
*val = data->mfr_acc;
|
||||
break;
|
||||
case SBS_GAUGE_CMD_VOLTAGE:
|
||||
case SBS_GAUGE_CMD_AVG_CURRENT:
|
||||
case SBS_GAUGE_CMD_TEMP:
|
||||
|
|
|
@ -88,6 +88,79 @@ ZTEST_F(sbs_gauge_new_api, test_get_some_props_failed_returns_failed_prop_count)
|
|||
zassert_equal(ret, 2);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_set_all_props_failed_returns_negative)
|
||||
{
|
||||
struct fuel_gauge_set_property props[] = {
|
||||
{
|
||||
/* Invalid property */
|
||||
.property_type = FUEL_GAUGE_PROP_MAX,
|
||||
},
|
||||
};
|
||||
|
||||
int ret = fixture->api->set_property(fixture->dev, props, ARRAY_SIZE(props));
|
||||
|
||||
zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.",
|
||||
props[0].property_type);
|
||||
|
||||
zassert_true(ret < 0);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_set_some_props_failed_returns_failed_prop_count)
|
||||
{
|
||||
struct fuel_gauge_set_property props[] = {
|
||||
{
|
||||
/* First invalid property */
|
||||
.property_type = FUEL_GAUGE_PROP_MAX,
|
||||
},
|
||||
{
|
||||
/* Second invalid property */
|
||||
.property_type = FUEL_GAUGE_PROP_MAX,
|
||||
},
|
||||
{
|
||||
/* Valid property */
|
||||
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
|
||||
/* Set Manufacturer's Access to arbitrary word */
|
||||
.value.sbs_mfr_access_word = 1,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
int ret = fixture->api->set_property(fixture->dev, props, ARRAY_SIZE(props));
|
||||
|
||||
zassert_equal(props[0].status, -ENOTSUP, "Setting bad property %d has a good status.",
|
||||
props[0].property_type);
|
||||
|
||||
zassert_equal(props[1].status, -ENOTSUP, "Setting bad property %d has a good status.",
|
||||
props[1].property_type);
|
||||
|
||||
zassert_ok(props[2].status, "Property %d setting %d has a bad status.", 2,
|
||||
props[2].property_type);
|
||||
|
||||
zassert_equal(ret, 2);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_set_prop_can_be_get)
|
||||
{
|
||||
uint16_t word = BIT(15) | BIT(0);
|
||||
struct fuel_gauge_set_property set_prop = {
|
||||
/* Valid property */
|
||||
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
|
||||
/* Set Manufacturer's Access to 16 bit word*/
|
||||
.value.sbs_mfr_access_word = word,
|
||||
};
|
||||
|
||||
zassert_ok(fixture->api->set_property(fixture->dev, &set_prop, 1));
|
||||
zassert_ok(set_prop.status);
|
||||
|
||||
struct fuel_gauge_get_property get_prop = {
|
||||
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
|
||||
};
|
||||
|
||||
zassert_ok(fixture->api->get_property(fixture->dev, &get_prop, 1));
|
||||
zassert_ok(get_prop.status);
|
||||
zassert_equal(get_prop.value.sbs_mfr_access_word, word);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_get_props__returns_ok)
|
||||
{
|
||||
/* Validate what props are supported by the driver */
|
||||
|
@ -138,4 +211,24 @@ ZTEST_F(sbs_gauge_new_api, test_get_props__returns_ok)
|
|||
zassert_ok(ret);
|
||||
}
|
||||
|
||||
ZTEST_F(sbs_gauge_new_api, test_set_props__returns_ok)
|
||||
{
|
||||
/* Validate what props are supported by the driver */
|
||||
|
||||
struct fuel_gauge_set_property props[] = {
|
||||
{
|
||||
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
|
||||
},
|
||||
};
|
||||
|
||||
int ret = fixture->api->set_property(fixture->dev, props, ARRAY_SIZE(props));
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(props); i++) {
|
||||
zassert_ok(props[i].status, "Property %d writing %d has a bad status.", i,
|
||||
props[i].property_type);
|
||||
}
|
||||
|
||||
zassert_ok(ret);
|
||||
}
|
||||
|
||||
ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL);
|
||||
|
|
Loading…
Reference in a new issue