fuel_gauge: Repl property struct w/ union

Based on review of the similar charger driver API, it's been demonstrated
from the community that embedding a per value property type when fetching
properties. Separating off the property types from the property values
themselves also allow an array of property types to declared as static
const.

Break up fuel_gauge_property struct into a fuel_gauge_prop_val union and a
fuel_gauge_prop_t property type as inputs into fuel gauge API functions.

Signed-off-by: Aaron Massey <aaronmassey@google.com>
This commit is contained in:
Aaron Massey 2023-09-22 12:17:27 -06:00 committed by Carles Cufí
parent 329ecd1e12
commit 12cbfcf397
10 changed files with 490 additions and 679 deletions

View file

@ -20,9 +20,11 @@ Fundamentally, a property is a quantity that a fuel gauge device can measure.
Fuel gauges typically support multiple properties, such as temperature readings of the battery-pack Fuel gauges typically support multiple properties, such as temperature readings of the battery-pack
or present-time current/voltage. or present-time current/voltage.
Properties are fetched one at a time using a client allocated :c:struct:`fuel_gauge_property` or Properties are fetched by the client one at a time using :c:func:`fuel_gauge_get_prop`, or fetched
fetched all at once using a client allocated array of :c:struct:`fuel_gauge_property`. Each in a batch using :c:func:`fuel_gauge_get_props`.
:c:struct:`fuel_gauge_property` is populated by values according to its `property_type` field.
Properties are set by the client one at a time using :c:func:`fuel_gauge_set_prop`, or set in a
batch using :c:func:`fuel_gauge_set_props`.
Battery Cutoff Battery Cutoff
============== ==============

View file

@ -109,84 +109,85 @@ static int bq27z746_read_mac(const struct device *dev, uint16_t cmd, uint8_t *da
return ret; return ret;
} }
static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_property *prop) static int bq27z746_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val *val)
{ {
int rc = 0; int rc = 0;
uint16_t val = 0; uint16_t tmp_val = 0;
/* /*
* Possibly negative values must be cast from uint16 to int16 first to * Possibly negative values must be cast from uint16 to int16 first to
* then correctly end up in the wider datatypes of `prop`. * then correctly end up in the wider datatypes of `prop`.
*/ */
switch (prop->property_type) { switch (prop) {
case FUEL_GAUGE_AVG_CURRENT: case FUEL_GAUGE_AVG_CURRENT:
rc = bq27z746_read16(dev, BQ27Z746_AVERAGECURRENT, &val); rc = bq27z746_read16(dev, BQ27Z746_AVERAGECURRENT, &tmp_val);
prop->value.avg_current = (int16_t)val * 1000; val->avg_current = (int16_t)tmp_val * 1000;
break; break;
case FUEL_GAUGE_CYCLE_COUNT: case FUEL_GAUGE_CYCLE_COUNT:
rc = bq27z746_read16(dev, BQ27Z746_CYCLECOUNT, &val); rc = bq27z746_read16(dev, BQ27Z746_CYCLECOUNT, &tmp_val);
prop->value.cycle_count = val * 100; val->cycle_count = tmp_val * 100;
break; break;
case FUEL_GAUGE_CURRENT: case FUEL_GAUGE_CURRENT:
rc = bq27z746_read16(dev, BQ27Z746_CURRENT, &val); rc = bq27z746_read16(dev, BQ27Z746_CURRENT, &tmp_val);
prop->value.current = (int16_t)val * 1000; val->current = (int16_t)tmp_val * 1000;
break; break;
case FUEL_GAUGE_FULL_CHARGE_CAPACITY: case FUEL_GAUGE_FULL_CHARGE_CAPACITY:
rc = bq27z746_read16(dev, BQ27Z746_FULLCHARGECAPACITY, &val); rc = bq27z746_read16(dev, BQ27Z746_FULLCHARGECAPACITY, &tmp_val);
prop->value.full_charge_capacity = val * 1000; val->full_charge_capacity = tmp_val * 1000;
break; break;
case FUEL_GAUGE_REMAINING_CAPACITY: case FUEL_GAUGE_REMAINING_CAPACITY:
rc = bq27z746_read16(dev, BQ27Z746_REMAININGCAPACITY, &val); rc = bq27z746_read16(dev, BQ27Z746_REMAININGCAPACITY, &tmp_val);
prop->value.remaining_capacity = val * 1000; val->remaining_capacity = tmp_val * 1000;
break; break;
case FUEL_GAUGE_RUNTIME_TO_EMPTY: case FUEL_GAUGE_RUNTIME_TO_EMPTY:
rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOEMPTY, &val); rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOEMPTY, &tmp_val);
prop->value.runtime_to_empty = val; val->runtime_to_empty = tmp_val;
break; break;
case FUEL_GAUGE_RUNTIME_TO_FULL: case FUEL_GAUGE_RUNTIME_TO_FULL:
rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOFULL, &val); rc = bq27z746_read16(dev, BQ27Z746_AVERAGETIMETOFULL, &tmp_val);
prop->value.runtime_to_full = val; val->runtime_to_full = tmp_val;
break; break;
case FUEL_GAUGE_SBS_MFR_ACCESS: case FUEL_GAUGE_SBS_MFR_ACCESS:
rc = bq27z746_read16(dev, BQ27Z746_MANUFACTURERACCESS, &val); rc = bq27z746_read16(dev, BQ27Z746_MANUFACTURERACCESS, &tmp_val);
prop->value.sbs_mfr_access_word = val; val->sbs_mfr_access_word = tmp_val;
break; break;
case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE:
rc = bq27z746_read16(dev, BQ27Z746_RELATIVESTATEOFCHARGE, &val); rc = bq27z746_read16(dev, BQ27Z746_RELATIVESTATEOFCHARGE, &tmp_val);
prop->value.relative_state_of_charge = val; val->relative_state_of_charge = tmp_val;
break; break;
case FUEL_GAUGE_TEMPERATURE: case FUEL_GAUGE_TEMPERATURE:
rc = bq27z746_read16(dev, BQ27Z746_TEMPERATURE, &val); rc = bq27z746_read16(dev, BQ27Z746_TEMPERATURE, &tmp_val);
prop->value.temperature = val; val->temperature = tmp_val;
break; break;
case FUEL_GAUGE_VOLTAGE: case FUEL_GAUGE_VOLTAGE:
rc = bq27z746_read16(dev, BQ27Z746_VOLTAGE, &val); rc = bq27z746_read16(dev, BQ27Z746_VOLTAGE, &tmp_val);
prop->value.voltage = val * 1000; val->voltage = tmp_val * 1000;
break; break;
case FUEL_GAUGE_SBS_ATRATE: case FUEL_GAUGE_SBS_ATRATE:
rc = bq27z746_read16(dev, BQ27Z746_ATRATE, &val); rc = bq27z746_read16(dev, BQ27Z746_ATRATE, &tmp_val);
prop->value.sbs_at_rate = (int16_t)val; val->sbs_at_rate = (int16_t)tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY: case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY:
rc = bq27z746_read16(dev, BQ27Z746_ATRATETIMETOEMPTY, &val); rc = bq27z746_read16(dev, BQ27Z746_ATRATETIMETOEMPTY, &tmp_val);
prop->value.sbs_at_rate_time_to_empty = val; val->sbs_at_rate_time_to_empty = tmp_val;
break; break;
case FUEL_GAUGE_CHARGE_VOLTAGE: case FUEL_GAUGE_CHARGE_VOLTAGE:
rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &val); rc = bq27z746_read16(dev, BQ27Z746_CHARGINGVOLTAGE, &tmp_val);
prop->value.chg_voltage = val; val->chg_voltage = tmp_val;
break; break;
case FUEL_GAUGE_CHARGE_CURRENT: case FUEL_GAUGE_CHARGE_CURRENT:
rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &val); rc = bq27z746_read16(dev, BQ27Z746_CHARGINGCURRENT, &tmp_val);
prop->value.chg_current = val; val->chg_current = tmp_val;
break; break;
case FUEL_GAUGE_STATUS: case FUEL_GAUGE_STATUS:
rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &val); rc = bq27z746_read16(dev, BQ27Z746_BATTERYSTATUS, &tmp_val);
prop->value.fg_status = val; val->fg_status = tmp_val;
break; break;
case FUEL_GAUGE_DESIGN_CAPACITY: case FUEL_GAUGE_DESIGN_CAPACITY:
rc = bq27z746_read16(dev, BQ27Z746_DESIGNCAPACITY, &val); rc = bq27z746_read16(dev, BQ27Z746_DESIGNCAPACITY, &tmp_val);
prop->value.design_cap = val; val->design_cap = tmp_val;
break; break;
default: default:
rc = -ENOTSUP; rc = -ENOTSUP;
@ -196,12 +197,12 @@ static int bq27z746_get_prop(const struct device *dev, struct fuel_gauge_propert
} }
static int bq27z746_get_buffer_prop(const struct device *dev, static int bq27z746_get_buffer_prop(const struct device *dev,
struct fuel_gauge_buffer_property *prop, void *dst, fuel_gauge_prop_t property_type, void *dst,
size_t dst_len) size_t dst_len)
{ {
int rc = 0; int rc = 0;
switch (prop->property_type) { switch (property_type) {
case FUEL_GAUGE_MANUFACTURER_NAME: case FUEL_GAUGE_MANUFACTURER_NAME:
if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) { if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) {
rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_MANUFACTURER_NAME, rc = bq27z746_read_mac(dev, BQ27Z746_MAC_CMD_MANUFACTURER_NAME,
@ -233,20 +234,20 @@ static int bq27z746_get_buffer_prop(const struct device *dev,
return rc; return rc;
} }
static int bq27z746_set_prop(const struct device *dev, struct fuel_gauge_property *prop) static int bq27z746_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val val)
{ {
int rc = 0; int rc = 0;
uint16_t val = 0; uint16_t tmp_val = 0;
switch (prop->property_type) { switch (prop) {
case FUEL_GAUGE_SBS_MFR_ACCESS: case FUEL_GAUGE_SBS_MFR_ACCESS:
rc = bq27z746_write16(dev, BQ27Z746_MANUFACTURERACCESS, rc = bq27z746_write16(dev, BQ27Z746_MANUFACTURERACCESS, val.sbs_mfr_access_word);
prop->value.sbs_mfr_access_word); val.sbs_mfr_access_word = tmp_val;
prop->value.sbs_mfr_access_word = val;
break; break;
case FUEL_GAUGE_SBS_ATRATE: case FUEL_GAUGE_SBS_ATRATE:
rc = bq27z746_write16(dev, BQ27Z746_ATRATE, prop->value.sbs_at_rate); rc = bq27z746_write16(dev, BQ27Z746_ATRATE, val.sbs_at_rate);
prop->value.sbs_at_rate = val; val.sbs_at_rate = tmp_val;
break; break;
default: default:
rc = -ENOTSUP; rc = -ENOTSUP;

View file

@ -8,72 +8,71 @@
#include <zephyr/syscall_handler.h> #include <zephyr/syscall_handler.h>
#include <zephyr/drivers/fuel_gauge.h> #include <zephyr/drivers/fuel_gauge.h>
static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop) union fuel_gauge_prop_val *val)
{ {
struct fuel_gauge_property k_prop; union fuel_gauge_prop_val k_val;
Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property));
Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); Z_OOPS(z_user_from_copy(&k_val, val, sizeof(union fuel_gauge_prop_val)));
int ret = z_impl_fuel_gauge_get_prop(dev, &k_prop); int ret = z_impl_fuel_gauge_get_prop(dev, prop, &k_val);
Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property))); Z_OOPS(z_user_to_copy(val, &k_val, sizeof(union fuel_gauge_prop_val)));
return ret; return ret;
} }
#include <syscalls/fuel_gauge_get_prop_mrsh.c> #include <syscalls/fuel_gauge_get_prop_mrsh.c>
static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props,
struct fuel_gauge_property *props, size_t props_len) union fuel_gauge_prop_val *vals, size_t len)
{ {
struct fuel_gauge_property k_props[props_len]; union fuel_gauge_prop_val k_vals[len];
fuel_gauge_prop_t k_props[len];
Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property)); Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_property));
Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val)));
Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t)));
int ret = z_impl_fuel_gauge_get_props(dev, k_props, props_len); int ret = z_impl_fuel_gauge_get_props(dev, k_props, k_vals, len);
Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val)));
return ret; return ret;
} }
#include <syscalls/fuel_gauge_get_props_mrsh.c> #include <syscalls/fuel_gauge_get_props_mrsh.c>
static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop) union fuel_gauge_prop_val val)
{ {
struct fuel_gauge_property k_prop;
Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property));
Z_OOPS(z_user_from_copy(&k_prop, prop, sizeof(struct fuel_gauge_property))); int ret = z_impl_fuel_gauge_set_prop(dev, prop, val);
int ret = z_impl_fuel_gauge_set_prop(dev, &k_prop);
Z_OOPS(z_user_to_copy(prop, &k_prop, sizeof(struct fuel_gauge_property)));
return ret; return ret;
} }
#include <syscalls/fuel_gauge_set_prop_mrsh.c> #include <syscalls/fuel_gauge_set_prop_mrsh.c>
static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props,
struct fuel_gauge_property *props, size_t props_len) union fuel_gauge_prop_val *vals, size_t len)
{ {
struct fuel_gauge_property k_props[props_len]; union fuel_gauge_prop_val k_vals[len];
fuel_gauge_prop_t k_props[len];
Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property)); Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, set_property));
Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct fuel_gauge_property))); Z_OOPS(z_user_from_copy(k_vals, vals, len * sizeof(union fuel_gauge_prop_val)));
Z_OOPS(z_user_from_copy(k_props, props, len * sizeof(fuel_gauge_prop_t)));
int ret = z_impl_fuel_gauge_set_props(dev, k_props, props_len); int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len);
Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct fuel_gauge_property))); /* We only copy back vals because props will never be modified */
Z_OOPS(z_user_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val)));
return ret; return ret;
} }
@ -81,22 +80,14 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev,
#include <syscalls/fuel_gauge_set_props_mrsh.c> #include <syscalls/fuel_gauge_set_props_mrsh.c>
static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev,
struct fuel_gauge_buffer_property *prop, fuel_gauge_prop_t prop, void *dst,
void *dst, size_t dst_len) size_t dst_len)
{ {
struct fuel_gauge_buffer_property k_prop;
Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property)); Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, get_buffer_property));
Z_OOPS(z_user_from_copy(&k_prop, prop,
sizeof(struct fuel_gauge_buffer_property)));
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, dst_len)); Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, dst_len));
int ret = z_impl_fuel_gauge_get_buffer_prop(dev, &k_prop, dst, dst_len); int ret = z_impl_fuel_gauge_get_buffer_prop(dev, prop, dst, dst_len);
Z_OOPS(z_user_to_copy(prop, &k_prop,
sizeof(struct fuel_gauge_buffer_property)));
return ret; return ret;
} }

View file

@ -175,23 +175,24 @@ static int max17048_init(const struct device *dev)
/** /**
* Get a single property from the fuel gauge * Get a single property from the fuel gauge
*/ */
static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_gauge_property *prop) static int max17048_get_single_prop_impl(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val *val)
{ {
struct max17048_data *data = dev->data; struct max17048_data *data = dev->data;
int rc = 0; int rc = 0;
switch (prop->property_type) { switch (prop) {
case FUEL_GAUGE_RUNTIME_TO_EMPTY: case FUEL_GAUGE_RUNTIME_TO_EMPTY:
prop->value.runtime_to_empty = data->time_to_empty; val->runtime_to_empty = data->time_to_empty;
break; break;
case FUEL_GAUGE_RUNTIME_TO_FULL: case FUEL_GAUGE_RUNTIME_TO_FULL:
prop->value.runtime_to_full = data->time_to_full; val->runtime_to_full = data->time_to_full;
break; break;
case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE:
prop->value.relative_state_of_charge = data->charge; val->relative_state_of_charge = data->charge;
break; break;
case FUEL_GAUGE_VOLTAGE: case FUEL_GAUGE_VOLTAGE:
prop->value.voltage = data->voltage; val->voltage = data->voltage;
break; break;
default: default:
rc = -ENOTSUP; rc = -ENOTSUP;
@ -203,7 +204,8 @@ static int max17048_get_single_prop_impl(const struct device *dev, struct fuel_g
/** /**
* Get properties from the fuel gauge * Get properties from the fuel gauge
*/ */
static int max17048_get_prop(const struct device *dev, struct fuel_gauge_property *prop) static int max17048_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val *val)
{ {
struct max17048_data *data = dev->data; struct max17048_data *data = dev->data;
int rc = max17048_percent(dev, &data->charge); int rc = max17048_percent(dev, &data->charge);
@ -273,7 +275,7 @@ static int max17048_get_prop(const struct device *dev, struct fuel_gauge_propert
data->time_to_empty = 0; data->time_to_empty = 0;
} }
ret = max17048_get_single_prop_impl(dev, prop); ret = max17048_get_single_prop_impl(dev, prop, val);
return ret; return ret;
} }

View file

@ -66,107 +66,108 @@ static int sbs_cmd_buffer_read(const struct device *dev, uint8_t reg_addr, char
return 0; return 0;
} }
static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop) static int sbs_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val *val)
{ {
int rc = 0; int rc = 0;
uint16_t val = 0; uint16_t tmp_val = 0;
switch (prop->property_type) { switch (prop) {
case FUEL_GAUGE_AVG_CURRENT: case FUEL_GAUGE_AVG_CURRENT:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_CURRENT, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_CURRENT, &tmp_val);
prop->value.avg_current = val * 1000; val->avg_current = tmp_val * 1000;
break; break;
case FUEL_GAUGE_CYCLE_COUNT: case FUEL_GAUGE_CYCLE_COUNT:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CYCLE_COUNT, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CYCLE_COUNT, &tmp_val);
prop->value.cycle_count = val; val->cycle_count = tmp_val;
break; break;
case FUEL_GAUGE_CURRENT: case FUEL_GAUGE_CURRENT:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CURRENT, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CURRENT, &tmp_val);
prop->value.current = val * 1000; val->current = tmp_val * 1000;
break; break;
case FUEL_GAUGE_FULL_CHARGE_CAPACITY: case FUEL_GAUGE_FULL_CHARGE_CAPACITY:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FULL_CAPACITY, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FULL_CAPACITY, &tmp_val);
prop->value.full_charge_capacity = val * 1000; val->full_charge_capacity = tmp_val * 1000;
break; break;
case FUEL_GAUGE_REMAINING_CAPACITY: case FUEL_GAUGE_REMAINING_CAPACITY:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY, &tmp_val);
prop->value.remaining_capacity = val * 1000; val->remaining_capacity = tmp_val * 1000;
break; break;
case FUEL_GAUGE_RUNTIME_TO_EMPTY: case FUEL_GAUGE_RUNTIME_TO_EMPTY:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RUNTIME2EMPTY, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RUNTIME2EMPTY, &tmp_val);
prop->value.runtime_to_empty = val; val->runtime_to_empty = tmp_val;
break; break;
case FUEL_GAUGE_RUNTIME_TO_FULL: case FUEL_GAUGE_RUNTIME_TO_FULL:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_TIME2FULL, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AVG_TIME2FULL, &tmp_val);
prop->value.runtime_to_full = val; val->runtime_to_full = tmp_val;
break; break;
case FUEL_GAUGE_SBS_MFR_ACCESS: case FUEL_GAUGE_SBS_MFR_ACCESS:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, &tmp_val);
prop->value.sbs_mfr_access_word = val; val->sbs_mfr_access_word = tmp_val;
break; break;
case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE: case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ASOC, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ASOC, &tmp_val);
prop->value.absolute_state_of_charge = val; val->absolute_state_of_charge = tmp_val;
break; break;
case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE: case FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RSOC, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_RSOC, &tmp_val);
prop->value.relative_state_of_charge = val; val->relative_state_of_charge = tmp_val;
break; break;
case FUEL_GAUGE_TEMPERATURE: case FUEL_GAUGE_TEMPERATURE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_TEMP, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_TEMP, &tmp_val);
prop->value.temperature = val; val->temperature = tmp_val;
break; break;
case FUEL_GAUGE_VOLTAGE: case FUEL_GAUGE_VOLTAGE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_VOLTAGE, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_VOLTAGE, &tmp_val);
prop->value.voltage = val * 1000; val->voltage = tmp_val * 1000;
break; break;
case FUEL_GAUGE_SBS_MODE: case FUEL_GAUGE_SBS_MODE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_BATTERY_MODE, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_BATTERY_MODE, &tmp_val);
prop->value.sbs_mode = val; val->sbs_mode = tmp_val;
break; break;
case FUEL_GAUGE_CHARGE_CURRENT: case FUEL_GAUGE_CHARGE_CURRENT:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_CURRENT, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_CURRENT, &tmp_val);
prop->value.chg_current = val; val->chg_current = tmp_val;
break; break;
case FUEL_GAUGE_CHARGE_VOLTAGE: case FUEL_GAUGE_CHARGE_VOLTAGE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_VOLTAGE, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_CHG_VOLTAGE, &tmp_val);
prop->value.chg_voltage = val; val->chg_voltage = tmp_val;
break; break;
case FUEL_GAUGE_STATUS: case FUEL_GAUGE_STATUS:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FLAGS, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_FLAGS, &tmp_val);
prop->value.fg_status = val; val->fg_status = tmp_val;
break; break;
case FUEL_GAUGE_DESIGN_CAPACITY: case FUEL_GAUGE_DESIGN_CAPACITY:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_NOM_CAPACITY, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_NOM_CAPACITY, &tmp_val);
prop->value.design_cap = val; val->design_cap = tmp_val;
break; break;
case FUEL_GAUGE_DESIGN_VOLTAGE: case FUEL_GAUGE_DESIGN_VOLTAGE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_DESIGN_VOLTAGE, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_DESIGN_VOLTAGE, &tmp_val);
prop->value.design_volt = val; val->design_volt = tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE: case FUEL_GAUGE_SBS_ATRATE:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AR, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AR, &tmp_val);
prop->value.sbs_at_rate = val; val->sbs_at_rate = tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL: case FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTF, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTF, &tmp_val);
prop->value.sbs_at_rate_time_to_full = val; val->sbs_at_rate_time_to_full = tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY: case FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTE, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_ARTTE, &tmp_val);
prop->value.sbs_at_rate_time_to_empty = val; val->sbs_at_rate_time_to_empty = tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE_OK: case FUEL_GAUGE_SBS_ATRATE_OK:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AROK, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_AROK, &tmp_val);
prop->value.sbs_at_rate_ok = val; val->sbs_at_rate_ok = tmp_val;
break; break;
case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM: case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, &tmp_val);
prop->value.sbs_remaining_capacity_alarm = val; val->sbs_remaining_capacity_alarm = tmp_val;
break; break;
case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM: case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM:
rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, &val); rc = sbs_cmd_reg_read(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, &tmp_val);
prop->value.sbs_remaining_time_alarm = val; val->sbs_remaining_time_alarm = tmp_val;
break; break;
default: default:
rc = -ENOTSUP; rc = -ENOTSUP;
@ -194,35 +195,36 @@ static int sbs_gauge_do_battery_cutoff(const struct device *dev)
return rc; return rc;
} }
static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop) static int sbs_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val val)
{ {
int rc = 0; int rc = 0;
uint16_t val = 0; uint16_t tmp_val = 0;
switch (prop->property_type) { switch (prop) {
case FUEL_GAUGE_SBS_MFR_ACCESS: case FUEL_GAUGE_SBS_MFR_ACCESS:
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS, rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_MANUFACTURER_ACCESS,
prop->value.sbs_mfr_access_word); val.sbs_mfr_access_word);
prop->value.sbs_mfr_access_word = val; val.sbs_mfr_access_word = tmp_val;
break; break;
case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM: case FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM:
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM, rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_CAPACITY_ALARM,
prop->value.sbs_remaining_capacity_alarm); val.sbs_remaining_capacity_alarm);
prop->value.sbs_remaining_capacity_alarm = val; val.sbs_remaining_capacity_alarm = tmp_val;
break; break;
case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM: case FUEL_GAUGE_SBS_REMAINING_TIME_ALARM:
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_TIME_ALARM, rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_REM_TIME_ALARM,
prop->value.sbs_remaining_time_alarm); val.sbs_remaining_time_alarm);
prop->value.sbs_remaining_time_alarm = val; val.sbs_remaining_time_alarm = tmp_val;
break; break;
case FUEL_GAUGE_SBS_MODE: case FUEL_GAUGE_SBS_MODE:
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_BATTERY_MODE, prop->value.sbs_mode); rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_BATTERY_MODE, val.sbs_mode);
prop->value.sbs_mode = val; val.sbs_mode = tmp_val;
break; break;
case FUEL_GAUGE_SBS_ATRATE: case FUEL_GAUGE_SBS_ATRATE:
rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_AR, prop->value.sbs_at_rate); rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_AR, val.sbs_at_rate);
prop->value.sbs_at_rate = val; val.sbs_at_rate = tmp_val;
break; break;
default: default:
rc = -ENOTSUP; rc = -ENOTSUP;
@ -232,12 +234,12 @@ static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_proper
} }
static int sbs_gauge_get_buffer_prop(const struct device *dev, static int sbs_gauge_get_buffer_prop(const struct device *dev,
struct fuel_gauge_buffer_property *prop, void *dst, fuel_gauge_prop_t prop_type, void *dst,
size_t dst_len) size_t dst_len)
{ {
int rc = 0; int rc = 0;
switch (prop->property_type) { switch (prop_type) {
case FUEL_GAUGE_MANUFACTURER_NAME: case FUEL_GAUGE_MANUFACTURER_NAME:
if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) { if (dst_len == sizeof(struct sbs_gauge_manufacturer_name)) {
rc = sbs_cmd_buffer_read(dev, SBS_GAUGE_CMD_MANUFACTURER_NAME, (char *)dst, rc = sbs_cmd_buffer_read(dev, SBS_GAUGE_CMD_MANUFACTURER_NAME, (char *)dst,

View file

@ -115,76 +115,65 @@ enum fuel_gauge_prop_type {
typedef uint16_t fuel_gauge_prop_t; typedef uint16_t fuel_gauge_prop_t;
struct fuel_gauge_property { /** Property field to value/type union */
/** Battery fuel gauge property to get */ union fuel_gauge_prop_val {
fuel_gauge_prop_t property_type; /* Fields have the format: */
/* FUEL_GAUGE_PROPERTY_FIELD */
/* type property_field; */
/** Property field for getting */ /* Dynamic Battery Info */
union { /** FUEL_GAUGE_AVG_CURRENT */
/* Fields have the format: */ int avg_current;
/* FUEL_GAUGE_PROPERTY_FIELD */ /** FUEL_GAUGE_CHARGE_CUTOFF */
/* type property_field; */ bool cutoff;
/** FUEL_GAUGE_CURRENT */
/* Dynamic Battery Info */ int current;
/** FUEL_GAUGE_AVG_CURRENT */ /** FUEL_GAUGE_CYCLE_COUNT */
int avg_current; uint32_t cycle_count;
/** FUEL_GAUGE_CHARGE_CUTOFF */ /** FUEL_GAUGE_FLAGS */
bool cutoff; uint32_t flags;
/** FUEL_GAUGE_CURRENT */ /** FUEL_GAUGE_FULL_CHARGE_CAPACITY */
int current; uint32_t full_charge_capacity;
/** FUEL_GAUGE_CYCLE_COUNT */ /** FUEL_GAUGE_REMAINING_CAPACITY */
uint32_t cycle_count; uint32_t remaining_capacity;
/** FUEL_GAUGE_FLAGS */ /** FUEL_GAUGE_RUNTIME_TO_EMPTY */
uint32_t flags; uint32_t runtime_to_empty;
/** FUEL_GAUGE_FULL_CHARGE_CAPACITY */ /** FUEL_GAUGE_RUNTIME_TO_FULL */
uint32_t full_charge_capacity; uint32_t runtime_to_full;
/** FUEL_GAUGE_REMAINING_CAPACITY */ /** FUEL_GAUGE_SBS_MFR_ACCESS */
uint32_t remaining_capacity; uint16_t sbs_mfr_access_word;
/** FUEL_GAUGE_RUNTIME_TO_EMPTY */ /** FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE */
uint32_t runtime_to_empty; uint8_t absolute_state_of_charge;
/** FUEL_GAUGE_RUNTIME_TO_FULL */ /** FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE */
uint32_t runtime_to_full; uint8_t relative_state_of_charge;
/** FUEL_GAUGE_SBS_MFR_ACCESS */ /** FUEL_GAUGE_TEMPERATURE */
uint16_t sbs_mfr_access_word; uint16_t temperature;
/** FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE */ /** FUEL_GAUGE_VOLTAGE */
uint8_t absolute_state_of_charge; int voltage;
/** FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE */ /** FUEL_GAUGE_SBS_MODE */
uint8_t relative_state_of_charge; uint16_t sbs_mode;
/** FUEL_GAUGE_TEMPERATURE */ /** FUEL_GAUGE_CHARGE_CURRENT */
uint16_t temperature; uint16_t chg_current;
/** FUEL_GAUGE_VOLTAGE */ /** FUEL_GAUGE_CHARGE_VOLTAGE */
int voltage; uint16_t chg_voltage;
/** FUEL_GAUGE_SBS_MODE */ /** FUEL_GAUGE_STATUS */
uint16_t sbs_mode; uint16_t fg_status;
/** FUEL_GAUGE_CHARGE_CURRENT */ /** FUEL_GAUGE_DESIGN_CAPACITY */
uint16_t chg_current; uint16_t design_cap;
/** FUEL_GAUGE_CHARGE_VOLTAGE */ /** FUEL_GAUGE_DESIGN_VOLTAGE */
uint16_t chg_voltage; uint16_t design_volt;
/** FUEL_GAUGE_STATUS */ /** FUEL_GAUGE_SBS_ATRATE */
uint16_t fg_status; int16_t sbs_at_rate;
/** FUEL_GAUGE_DESIGN_CAPACITY */ /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL */
uint16_t design_cap; uint16_t sbs_at_rate_time_to_full;
/** FUEL_GAUGE_DESIGN_VOLTAGE */ /** FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY */
uint16_t design_volt; uint16_t sbs_at_rate_time_to_empty;
/** FUEL_GAUGE_SBS_ATRATE */ /** FUEL_GAUGE_SBS_ATRATE_OK */
int16_t sbs_at_rate; bool sbs_at_rate_ok;
/** FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL */ /** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */
uint16_t sbs_at_rate_time_to_full; uint16_t sbs_remaining_capacity_alarm;
/** FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY */ /** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */
uint16_t sbs_at_rate_time_to_empty; uint16_t sbs_remaining_time_alarm;
/** FUEL_GAUGE_SBS_ATRATE_OK */
bool sbs_at_rate_ok;
/** FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM */
uint16_t sbs_remaining_capacity_alarm;
/** FUEL_GAUGE_SBS_REMAINING_TIME_ALARM */
uint16_t sbs_remaining_time_alarm;
} value;
};
/** Buffer properties are separated due to size */
struct fuel_gauge_buffer_property {
/** Battery fuel gauge property to get */
fuel_gauge_prop_t property_type;
}; };
/** /**
@ -215,8 +204,8 @@ struct sbs_gauge_device_chemistry {
* *
* See fuel_gauge_get_property() for argument description * See fuel_gauge_get_property() for argument description
*/ */
typedef int (*fuel_gauge_get_property_t)(const struct device *dev, typedef int (*fuel_gauge_get_property_t)(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop); union fuel_gauge_prop_val *val);
/** /**
* @typedef fuel_gauge_set_property_t * @typedef fuel_gauge_set_property_t
@ -224,8 +213,8 @@ typedef int (*fuel_gauge_get_property_t)(const struct device *dev,
* *
* See fuel_gauge_set_property() for argument description * See fuel_gauge_set_property() for argument description
*/ */
typedef int (*fuel_gauge_set_property_t)(const struct device *dev, typedef int (*fuel_gauge_set_property_t)(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop); union fuel_gauge_prop_val val);
/** /**
* @typedef fuel_gauge_get_buffer_property_t * @typedef fuel_gauge_get_buffer_property_t
@ -234,7 +223,7 @@ typedef int (*fuel_gauge_set_property_t)(const struct device *dev,
* See fuel_gauge_get_buffer_property() for argument description * See fuel_gauge_get_buffer_property() for argument description
*/ */
typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev, typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev,
struct fuel_gauge_buffer_property *prop, fuel_gauge_prop_t prop_type,
void *dst, size_t dst_len); void *dst, size_t dst_len);
/** /**
@ -264,17 +253,16 @@ __subsystem struct fuel_gauge_driver_api {
* @brief Fetch a battery fuel-gauge property * @brief Fetch a battery fuel-gauge property
* *
* @param dev Pointer to the battery fuel-gauge device * @param dev Pointer to the battery fuel-gauge device
* @param prop pointer to a fuel_gauge_property struct where the property struct * @param prop Type of property to be fetched from device
* field is set by the caller to determine what property is read from the * @param val pointer to a union fuel_gauge_prop_val where the property is read into from the
* fuel gauge device into the fuel_gauge_property struct's value field. The props array * fuel gauge device.
* maintains the same order of properties as it was given.
*
* @return 0 if successful, negative errno code if failure. * @return 0 if successful, negative errno code if failure.
*/ */
__syscall int fuel_gauge_get_prop(const struct device *dev, struct fuel_gauge_property *prop); __syscall int fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val *val);
static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop) union fuel_gauge_prop_val *val)
{ {
const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api;
@ -282,7 +270,7 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev,
return -ENOSYS; return -ENOSYS;
} }
return api->get_property(dev, prop); return api->get_property(dev, prop, val);
} }
/** /**
@ -291,23 +279,25 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev,
* of the fuel gauge driver APIs struct to override this implementation. * of the fuel gauge driver APIs struct to override this implementation.
* *
* @param dev Pointer to the battery fuel-gauge device * @param dev Pointer to the battery fuel-gauge device
* @param props pointer to array of fuel_gauge_property struct where the property struct * @param props Array of the type of property to be fetched from device, each index corresponds
* field is set by the caller to determine what property is read from the * to the same index of the vals input array.
* fuel gauge device into the fuel_gauge_property struct's value field. The props array * @param vals Pointer to array of union fuel_gauge_prop_val where the property is read into from
* maintains the same order of properties as it was given. * the fuel gauge device. The vals array is not permuted.
* @param len number of properties in props array * @param len number of properties in props & vals array
* *
* @return 0 if successful, negative errno code of first failing property * @return 0 if successful, negative errno code of first failing property
*/ */
__syscall int fuel_gauge_get_props(const struct device *dev, struct fuel_gauge_property *props,
size_t len); __syscall int fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props,
union fuel_gauge_prop_val *vals, size_t len);
static inline int z_impl_fuel_gauge_get_props(const struct device *dev, static inline int z_impl_fuel_gauge_get_props(const struct device *dev,
struct fuel_gauge_property *props, size_t len) fuel_gauge_prop_t *props,
union fuel_gauge_prop_val *vals, size_t len)
{ {
const struct fuel_gauge_driver_api *api = dev->api; const struct fuel_gauge_driver_api *api = dev->api;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
int ret = api->get_property(dev, props + i); int ret = api->get_property(dev, props[i], vals + i);
if (ret) { if (ret) {
return ret; return ret;
@ -321,16 +311,16 @@ static inline int z_impl_fuel_gauge_get_props(const struct device *dev,
* @brief Set a battery fuel-gauge property * @brief Set a battery fuel-gauge property
* *
* @param dev Pointer to the battery fuel-gauge device * @param dev Pointer to the battery fuel-gauge device
* @param prop pointer to fuel_gauge_property struct where the property struct * @param prop Type of property that's being set
* field is set by the caller to determine what property is written to the fuel gauge device from * @param val Value to set associated prop property.
* the fuel_gauge_property struct's value field.
* *
* @return 0 if successful, negative errno code of first failing property * @return 0 if successful, negative errno code of first failing property
*/ */
__syscall int fuel_gauge_set_prop(const struct device *dev, struct fuel_gauge_property *prop); __syscall int fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
union fuel_gauge_prop_val val);
static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop,
struct fuel_gauge_property *prop) union fuel_gauge_prop_val val)
{ {
const struct fuel_gauge_driver_api *api = dev->api; const struct fuel_gauge_driver_api *api = dev->api;
@ -338,28 +328,29 @@ static inline int z_impl_fuel_gauge_set_prop(const struct device *dev,
return -ENOSYS; return -ENOSYS;
} }
return api->set_property(dev, prop); return api->set_property(dev, prop, val);
} }
/** /**
* @brief Set a battery fuel-gauge property * @brief Set a battery fuel-gauge property
* *
* @param dev Pointer to the battery fuel-gauge device * @param dev Pointer to the battery fuel-gauge device
* @param props pointer to array of fuel_gauge_property struct where the property struct * @param props Array of the type of property to be set, each index corresponds
* field is set by the caller to determine what property is written to the fuel gauge device from * to the same index of the vals input array.
* the fuel_gauge_property struct's value field. * @param vals Pointer to array of union fuel_gauge_prop_val where the property is written
* @param props_len number of properties in props array * the fuel gauge device. The vals array is not permuted.
* @param len number of properties in props array
* *
* @return return=0 if successful. Otherwise, return array index of failing property. * @return return=0 if successful. Otherwise, return array index of failing property.
*/ */
__syscall int fuel_gauge_set_props(const struct device *dev, struct fuel_gauge_property *props, __syscall int fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props,
size_t props_len); union fuel_gauge_prop_val *vals, size_t len);
static inline int z_impl_fuel_gauge_set_props(const struct device *dev, static inline int z_impl_fuel_gauge_set_props(const struct device *dev,
struct fuel_gauge_property *props, size_t props_len) fuel_gauge_prop_t *props,
union fuel_gauge_prop_val *vals, size_t len)
{ {
for (int i = 0; i < props_len; i++) { for (int i = 0; i < len; i++) {
int ret = fuel_gauge_set_prop(dev, props + i); int ret = fuel_gauge_set_prop(dev, props[i], vals[i]);
if (ret) { if (ret) {
return ret; return ret;
@ -373,20 +364,18 @@ static inline int z_impl_fuel_gauge_set_props(const struct device *dev,
* @brief Fetch a battery fuel-gauge buffer property * @brief Fetch a battery fuel-gauge buffer property
* *
* @param dev Pointer to the battery fuel-gauge device * @param dev Pointer to the battery fuel-gauge device
* @param prop pointer to single fuel_gauge_get_buffer_property struct where the property struct * @param prop_type Type of property to be fetched from device
* field is set by the caller to determine what property is read from the
* fuel gauge device into the dst field.
* @param dst byte array or struct that will hold the buffer data that is read from the fuel gauge * @param dst byte array or struct that will hold the buffer data that is read from the fuel gauge
* @param dst_len the length of the destination array in bytes * @param dst_len the length of the destination array in bytes
* *
* @return return=0 if successful, return < 0 if getting property failed, return 0 on success * @return return=0 if successful, return < 0 if getting property failed, return 0 on success
*/ */
__syscall int fuel_gauge_get_buffer_prop(const struct device *dev,
struct fuel_gauge_buffer_property *prop, void *dst, __syscall int fuel_gauge_get_buffer_prop(const struct device *dev, fuel_gauge_prop_t prop_type,
size_t dst_len); void *dst, size_t dst_len);
static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev, static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev,
struct fuel_gauge_buffer_property *prop, fuel_gauge_prop_t prop_type,
void *dst, size_t dst_len) void *dst, size_t dst_len)
{ {
const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api;
@ -395,7 +384,7 @@ static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev,
return -ENOSYS; return -ENOSYS;
} }
return api->get_buffer_property(dev, prop, dst, dst_len); return api->get_buffer_property(dev, prop_type, dst, dst_len);
} }
/** /**

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "zephyr/sys/util.h"
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/device.h> #include <zephyr/device.h>
#include <zephyr/devicetree.h> #include <zephyr/devicetree.h>
@ -38,31 +39,26 @@ int main(void)
while (1) { while (1) {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t props[] = {
{ FUEL_GAUGE_RUNTIME_TO_EMPTY,
.property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, FUEL_GAUGE_RUNTIME_TO_FULL,
}, FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
{ FUEL_GAUGE_VOLTAGE,
.property_type = FUEL_GAUGE_RUNTIME_TO_FULL, };
},
{
.property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
},
{
.property_type = FUEL_GAUGE_VOLTAGE,
}};
ret = fuel_gauge_get_props(dev, props, ARRAY_SIZE(props)); union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
ret = fuel_gauge_get_props(dev, props, vals, ARRAY_SIZE(props));
if (ret < 0) { if (ret < 0) {
printk("Error: cannot get properties\n"); printk("Error: cannot get properties\n");
} else { } else {
printk("Time to empty %d\n", props[0].value.runtime_to_empty); printk("Time to empty %d\n", vals[0].runtime_to_empty);
printk("Time to full %d\n", props[1].value.runtime_to_full); printk("Time to full %d\n", vals[1].runtime_to_full);
printk("Charge %d%%\n", props[2].value.relative_state_of_charge); printk("Charge %d%%\n", vals[2].relative_state_of_charge);
printk("Voltage %d\n", props[3].value.voltage); printk("Voltage %d\n", vals[3].voltage);
} }
k_sleep(K_MSEC(5000)); k_sleep(K_MSEC(5000));

View file

@ -31,53 +31,32 @@ static void *bq27z746_setup(void)
return &fixture; return &fixture;
} }
ZTEST_USER_F(bq27z746, test_get_all_props_failed_returns_negative) ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_bad_status)
{ {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t props[] = {
{ /* First invalid property */
/* Invalid property */ FUEL_GAUGE_PROP_MAX,
.property_type = FUEL_GAUGE_PROP_MAX, /* Second invalid property */
}, FUEL_GAUGE_PROP_MAX,
/* Valid property */
FUEL_GAUGE_VOLTAGE,
}; };
union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); int ret = fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP); zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status.");
}
ZTEST_USER_F(bq27z746, test_get_some_props_failed_returns_failed_prop_count)
{
struct fuel_gauge_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_VOLTAGE,
},
};
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP);
} }
ZTEST_USER_F(bq27z746, test_get_buffer_prop) ZTEST_USER_F(bq27z746, test_get_buffer_prop)
{ {
struct fuel_gauge_buffer_property prop;
int ret; int ret;
{ {
struct sbs_gauge_manufacturer_name mfg_name; struct sbs_gauge_manufacturer_name mfg_name;
prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_MANUFACTURER_NAME,
ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name)); &mfg_name, sizeof(mfg_name));
zassert_ok(ret); zassert_ok(ret);
#if CONFIG_EMUL #if CONFIG_EMUL
/* Only test for fixed values in emulation since the real device might be */ /* Only test for fixed values in emulation since the real device might be */
@ -91,8 +70,8 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop)
{ {
struct sbs_gauge_device_name dev_name; struct sbs_gauge_device_name dev_name;
prop.property_type = FUEL_GAUGE_DEVICE_NAME; ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_NAME, &dev_name,
ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name)); sizeof(dev_name));
zassert_ok(ret); zassert_ok(ret);
#if CONFIG_EMUL #if CONFIG_EMUL
/* Only test for fixed values in emulation since the real device might be */ /* Only test for fixed values in emulation since the real device might be */
@ -104,9 +83,8 @@ ZTEST_USER_F(bq27z746, test_get_buffer_prop)
{ {
struct sbs_gauge_device_chemistry device_chemistry; struct sbs_gauge_device_chemistry device_chemistry;
prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; ret = fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_CHEMISTRY,
ret = fuel_gauge_get_buffer_prop(fixture->dev, &prop, &device_chemistry, &device_chemistry, sizeof(device_chemistry));
sizeof(device_chemistry));
zassert_ok(ret); zassert_ok(ret);
#if CONFIG_EMUL #if CONFIG_EMUL
/* Only test for fixed values in emulation since the real device might be */ /* Only test for fixed values in emulation since the real device might be */
@ -122,101 +100,68 @@ ZTEST_USER_F(bq27z746, test_get_props__returns_ok)
{ {
/* Validate what props are supported by the driver */ /* Validate what props are supported by the driver */
struct fuel_gauge_property props[] = { fuel_gauge_prop_t props[] = {
{ FUEL_GAUGE_AVG_CURRENT,
.property_type = FUEL_GAUGE_AVG_CURRENT, FUEL_GAUGE_CYCLE_COUNT,
}, FUEL_GAUGE_CURRENT,
{ FUEL_GAUGE_FULL_CHARGE_CAPACITY,
.property_type = FUEL_GAUGE_CYCLE_COUNT, FUEL_GAUGE_REMAINING_CAPACITY,
}, FUEL_GAUGE_RUNTIME_TO_EMPTY,
{ FUEL_GAUGE_RUNTIME_TO_FULL,
.property_type = FUEL_GAUGE_CURRENT, FUEL_GAUGE_SBS_MFR_ACCESS,
}, FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
{ FUEL_GAUGE_TEMPERATURE,
.property_type = FUEL_GAUGE_FULL_CHARGE_CAPACITY, FUEL_GAUGE_VOLTAGE,
}, FUEL_GAUGE_SBS_ATRATE,
{ FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
.property_type = FUEL_GAUGE_REMAINING_CAPACITY, FUEL_GAUGE_CHARGE_VOLTAGE,
}, FUEL_GAUGE_CHARGE_CURRENT,
{ FUEL_GAUGE_STATUS,
.property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, FUEL_GAUGE_DESIGN_CAPACITY,
},
{
.property_type = FUEL_GAUGE_RUNTIME_TO_FULL,
},
{
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
},
{
.property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
},
{
.property_type = FUEL_GAUGE_TEMPERATURE,
},
{
.property_type = FUEL_GAUGE_VOLTAGE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
},
{
.property_type = FUEL_GAUGE_CHARGE_VOLTAGE,
},
{
.property_type = FUEL_GAUGE_CHARGE_CURRENT,
},
{
.property_type = FUEL_GAUGE_STATUS,
},
{
.property_type = FUEL_GAUGE_DESIGN_CAPACITY,
},
}; };
union fuel_gauge_prop_val vals[ARRAY_SIZE(props)];
zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); zassert_ok(fuel_gauge_get_props(fixture->dev, props, vals, ARRAY_SIZE(props)));
/* Check properties for valid ranges */ /* Check properties for valid ranges */
#if CONFIG_EMUL #if CONFIG_EMUL
/* When emulating, check for the fixed values coming from the emulator */ /* When emulating, check for the fixed values coming from the emulator */
zassert_equal(props[0].value.avg_current, -2000); zassert_equal(vals[0].avg_current, -2000);
zassert_equal(props[1].value.cycle_count, 100); zassert_equal(vals[1].cycle_count, 100);
zassert_equal(props[2].value.current, -2000); zassert_equal(vals[2].current, -2000);
zassert_equal(props[3].value.full_charge_capacity, 1000); zassert_equal(vals[3].full_charge_capacity, 1000);
zassert_equal(props[4].value.remaining_capacity, 1000); zassert_equal(vals[4].remaining_capacity, 1000);
zassert_equal(props[5].value.runtime_to_empty, 1); zassert_equal(vals[5].runtime_to_empty, 1);
zassert_equal(props[6].value.runtime_to_full, 1); zassert_equal(vals[6].runtime_to_full, 1);
zassert_equal(props[7].value.sbs_mfr_access_word, 1); zassert_equal(vals[7].sbs_mfr_access_word, 1);
zassert_equal(props[8].value.relative_state_of_charge, 1); zassert_equal(vals[8].relative_state_of_charge, 1);
zassert_equal(props[9].value.temperature, 1); zassert_equal(vals[9].temperature, 1);
zassert_equal(props[10].value.voltage, 1000); zassert_equal(vals[10].voltage, 1000);
zassert_equal(props[11].value.sbs_at_rate, -2); zassert_equal(vals[11].sbs_at_rate, -2);
zassert_equal(props[12].value.sbs_at_rate_time_to_empty, 1); zassert_equal(vals[12].sbs_at_rate_time_to_empty, 1);
zassert_equal(props[13].value.chg_voltage, 1); zassert_equal(vals[13].chg_voltage, 1);
zassert_equal(props[14].value.chg_current, 1); zassert_equal(vals[14].chg_current, 1);
zassert_equal(props[15].value.fg_status, 1); zassert_equal(vals[15].fg_status, 1);
zassert_equal(props[16].value.design_cap, 1); zassert_equal(vals[16].design_cap, 1);
#else #else
/* When having a real device, check for the valid ranges */ /* When having a real device, check for the valid ranges */
zassert_between_inclusive(props[0].value.avg_current, -32768 * 1000, 32767 * 1000); zassert_between_inclusive(props[0].avg_current, -32768 * 1000, 32767 * 1000);
zassert_between_inclusive(props[1].value.cycle_count, 0, 6553500); zassert_between_inclusive(props[1].cycle_count, 0, 6553500);
zassert_between_inclusive(props[2].value.current, -32768 * 1000, 32767 * 1000); zassert_between_inclusive(props[2].current, -32768 * 1000, 32767 * 1000);
zassert_between_inclusive(props[3].value.full_charge_capacity, 0, 32767 * 1000); zassert_between_inclusive(props[3].full_charge_capacity, 0, 32767 * 1000);
zassert_between_inclusive(props[4].value.remaining_capacity, 0, 32767 * 1000); zassert_between_inclusive(props[4].remaining_capacity, 0, 32767 * 1000);
zassert_between_inclusive(props[5].value.runtime_to_empty, 0, 65535); zassert_between_inclusive(props[5].runtime_to_empty, 0, 65535);
zassert_between_inclusive(props[6].value.runtime_to_full, 0, 65535); zassert_between_inclusive(props[6].runtime_to_full, 0, 65535);
/* Not testing props[7]. This is the manufacturer access and has only status bits */ /* Not testing props[7]. This is the manufacturer access and has only status bits */
zassert_between_inclusive(props[8].value.relative_state_of_charge, 0, 100); zassert_between_inclusive(props[8].relative_state_of_charge, 0, 100);
zassert_between_inclusive(props[9].value.temperature, 0, 32767); zassert_between_inclusive(props[9].temperature, 0, 32767);
zassert_between_inclusive(props[10].value.voltage, 0, 32767 * 1000); zassert_between_inclusive(props[10].voltage, 0, 32767 * 1000);
zassert_between_inclusive(props[11].value.sbs_at_rate, -32768, 32767); zassert_between_inclusive(props[11].sbs_at_rate, -32768, 32767);
zassert_between_inclusive(props[12].value.sbs_at_rate_time_to_empty, 0, 65535); zassert_between_inclusive(props[12].sbs_at_rate_time_to_empty, 0, 65535);
zassert_between_inclusive(props[13].value.chg_voltage, 0, 32767); zassert_between_inclusive(props[13].chg_voltage, 0, 32767);
zassert_between_inclusive(props[14].value.chg_current, 0, 32767); zassert_between_inclusive(props[14].chg_current, 0, 32767);
/* Not testing props[15]. This property is the status and only has only status bits */ /* Not testing props[15]. This property is the status and only has only status bits */
zassert_between_inclusive(props[16].value.design_cap, 0, 32767); zassert_between_inclusive(props[16].design_cap, 0, 32767);
#endif #endif
} }

View file

@ -32,98 +32,63 @@ static void *max17048_setup(void)
return &fixture; return &fixture;
} }
ZTEST_USER_F(max17048, test_get_all_props_failed_returns_negative) ZTEST_USER_F(max17048, test_get_some_props_failed_returns_bad_status)
{ {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ /* First invalid property */
/* Invalid property */ FUEL_GAUGE_PROP_MAX,
.property_type = FUEL_GAUGE_PROP_MAX, /* Second invalid property */
}, FUEL_GAUGE_PROP_MAX,
/* Valid property */
FUEL_GAUGE_VOLTAGE,
}; };
union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
zassert_equal(-ENOTSUP, ret); zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status.");
} }
ZTEST_USER_F(max17048, test_get_some_props_failed_returns_errno)
{
struct fuel_gauge_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_VOLTAGE,
},
};
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP);
}
ZTEST_USER_F(max17048, test_get_props__returns_ok) ZTEST_USER_F(max17048, test_get_props__returns_ok)
{ {
/* Validate what props are supported by the driver */ /* Validate what props are supported by the driver */
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ FUEL_GAUGE_VOLTAGE,
.property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, FUEL_GAUGE_RUNTIME_TO_EMPTY,
}, FUEL_GAUGE_RUNTIME_TO_FULL,
{ FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
.property_type = FUEL_GAUGE_RUNTIME_TO_FULL,
},
{
.property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
},
{
.property_type = FUEL_GAUGE_VOLTAGE,
}
}; };
zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
zassert_ok(fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)));
} }
ZTEST_USER_F(max17048, test_current_rate_zero) ZTEST_USER_F(max17048, test_current_rate_zero)
{ {
/* Test when crate is 0, which is a special case */ /* Test when crate is 0, which is a special case */
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ FUEL_GAUGE_RUNTIME_TO_EMPTY,
.property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, FUEL_GAUGE_RUNTIME_TO_FULL,
},
{
.property_type = FUEL_GAUGE_RUNTIME_TO_FULL,
}
}; };
union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
/** Null value, not charging either discharging. If not handled correctly, /** Null value, not charging either discharging. If not handled correctly,
* it will cause a division by zero * it will cause a division by zero
*/ */
emul_max17048_set_crate_status(0); emul_max17048_set_crate_status(0);
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
zassert_equal(props[0].value.runtime_to_empty, 0, zassert_equal(props[0].runtime_to_empty, 0, "Runtime to empty is %d but it should be 0.",
"Runtime to empty is %d but it should be 0.", props[0].runtime_to_full);
props[0].value.runtime_to_full zassert_equal(props[1].runtime_to_full, 0, "Runtime to full is %d but it should be 0.",
); props[1].runtime_to_full);
zassert_equal(props[1].value.runtime_to_full, 0,
"Runtime to full is %d but it should be 0.",
props[1].value.runtime_to_full
);
zassert_ok(ret); zassert_ok(ret);
/* Return value to the original state */ /* Return value to the original state */
emul_max17048_set_crate_status(0x4000); emul_max17048_set_crate_status(0x4000);
} }
ZTEST_SUITE(max17048, NULL, max17048_setup, NULL, NULL, NULL); ZTEST_SUITE(max17048, NULL, max17048_setup, NULL, NULL, NULL);

View file

@ -34,62 +34,58 @@ static void *sbs_gauge_new_api_setup(void)
ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_bad_status) ZTEST_USER_F(sbs_gauge_new_api, test_get_some_props_failed_returns_bad_status)
{ {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ /* First invalid property */
/* First invalid property */ FUEL_GAUGE_PROP_MAX,
.property_type = FUEL_GAUGE_PROP_MAX, /* Second invalid property */
}, FUEL_GAUGE_PROP_MAX,
{ /* Valid property */
/* Second invalid property */ FUEL_GAUGE_VOLTAGE,
.property_type = FUEL_GAUGE_PROP_MAX,
},
{
/* Valid property */
.property_type = FUEL_GAUGE_VOLTAGE,
},
}; };
union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
int ret = fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props)); int ret = fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status."); zassert_equal(ret, -ENOTSUP, "Getting bad property has a good status.");
} }
ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_err) ZTEST_USER_F(sbs_gauge_new_api, test_set_all_props_failed_returns_err)
{ {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ /* Invalid property */
/* Invalid property */ FUEL_GAUGE_PROP_MAX,
.property_type = FUEL_GAUGE_PROP_MAX,
},
}; };
union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP); zassert_equal(ret, -ENOTSUP);
} }
ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err) ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err)
{ {
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ /* First invalid property */
/* First invalid property */ FUEL_GAUGE_PROP_MAX,
.property_type = FUEL_GAUGE_PROP_MAX, /* Second invalid property */
}, FUEL_GAUGE_PROP_MAX,
{ /* Valid property */
/* Second invalid property */ FUEL_GAUGE_SBS_MFR_ACCESS,
.property_type = FUEL_GAUGE_PROP_MAX, /* Set Manufacturer's Access to arbitrary word */
},
{
/* Valid property */
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
/* Set Manufacturer's Access to arbitrary word */
.value.sbs_mfr_access_word = 1,
},
}; };
int ret = fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props)); union fuel_gauge_prop_val props[] = {
/* First invalid property */
{0},
/* Second invalid property */
{0},
/* Valid property */
/* Set Manufacturer's Access to arbitrary word */
{.sbs_mfr_access_word = 1},
};
int ret = fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props));
zassert_equal(ret, -ENOTSUP); zassert_equal(ret, -ENOTSUP);
} }
@ -97,184 +93,116 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_some_props_failed_returns_err)
ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get) ZTEST_USER_F(sbs_gauge_new_api, test_set_prop_can_be_get)
{ {
uint16_t word = BIT(15) | BIT(0); uint16_t word = BIT(15) | BIT(0);
struct fuel_gauge_property set_props[] = {
fuel_gauge_prop_t prop_types[] = {
FUEL_GAUGE_SBS_MFR_ACCESS,
FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
FUEL_GAUGE_SBS_MODE,
FUEL_GAUGE_SBS_ATRATE,
};
union fuel_gauge_prop_val set_props[] = {
{ {
/* Valid property */ .sbs_mfr_access_word = word,
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
/* Set Manufacturer's Access to 16 bit word */
.value.sbs_mfr_access_word = word,
}, },
{ {
.property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, .sbs_remaining_capacity_alarm = word,
.value.sbs_remaining_capacity_alarm = word,
}, },
{ {
.property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM, .sbs_remaining_time_alarm = word,
.value.sbs_remaining_time_alarm = word,
}, },
{ {
.property_type = FUEL_GAUGE_SBS_MODE, .sbs_mode = word,
.value.sbs_mode = word,
}, },
{ {
.property_type = FUEL_GAUGE_SBS_ATRATE, .sbs_at_rate = (int16_t)word,
.value.sbs_at_rate = (int16_t)word,
}, },
}; };
struct fuel_gauge_property get_props[] = { union fuel_gauge_prop_val get_props[ARRAY_SIZE(prop_types)];
{
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
},
{
.property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
},
{
.property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
},
{
.property_type = FUEL_GAUGE_SBS_MODE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE,
},
};
zassert_ok(fuel_gauge_set_props(fixture->dev, set_props, ARRAY_SIZE(set_props))); zassert_ok(
fuel_gauge_set_props(fixture->dev, prop_types, set_props, ARRAY_SIZE(set_props)));
zassert_ok(fuel_gauge_get_props(fixture->dev, get_props, ARRAY_SIZE(get_props))); zassert_ok(
fuel_gauge_get_props(fixture->dev, prop_types, get_props, ARRAY_SIZE(get_props)));
zassert_equal(get_props[0].value.sbs_mfr_access_word, word); zassert_equal(get_props[0].sbs_mfr_access_word, word);
zassert_equal(get_props[1].value.sbs_remaining_capacity_alarm, word); zassert_equal(get_props[1].sbs_remaining_capacity_alarm, word);
zassert_equal(get_props[2].value.sbs_remaining_time_alarm, word); zassert_equal(get_props[2].sbs_remaining_time_alarm, word);
zassert_equal(get_props[3].value.sbs_mode, word); zassert_equal(get_props[3].sbs_mode, word);
zassert_equal(get_props[4].value.sbs_at_rate, (int16_t)word); zassert_equal(get_props[4].sbs_at_rate, (int16_t)word);
} }
ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_get_props__returns_ok)
{ {
/* Validate what props are supported by the driver */ /* Validate what props are supported by the driver */
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ FUEL_GAUGE_VOLTAGE,
.property_type = FUEL_GAUGE_VOLTAGE, FUEL_GAUGE_CURRENT,
}, FUEL_GAUGE_AVG_CURRENT,
{ FUEL_GAUGE_TEMPERATURE,
.property_type = FUEL_GAUGE_CURRENT, FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE,
}, FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE,
{ FUEL_GAUGE_RUNTIME_TO_FULL,
.property_type = FUEL_GAUGE_AVG_CURRENT, FUEL_GAUGE_RUNTIME_TO_EMPTY,
}, FUEL_GAUGE_REMAINING_CAPACITY,
{ FUEL_GAUGE_FULL_CHARGE_CAPACITY,
.property_type = FUEL_GAUGE_TEMPERATURE, FUEL_GAUGE_CYCLE_COUNT,
}, FUEL_GAUGE_SBS_MFR_ACCESS,
{ FUEL_GAUGE_SBS_MODE,
.property_type = FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE, FUEL_GAUGE_CHARGE_CURRENT,
}, FUEL_GAUGE_CHARGE_VOLTAGE,
{ FUEL_GAUGE_STATUS,
.property_type = FUEL_GAUGE_RELATIVE_STATE_OF_CHARGE, FUEL_GAUGE_DESIGN_CAPACITY,
}, FUEL_GAUGE_DESIGN_VOLTAGE,
{ FUEL_GAUGE_SBS_ATRATE,
.property_type = FUEL_GAUGE_RUNTIME_TO_FULL, FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL,
}, FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
{ FUEL_GAUGE_SBS_ATRATE_OK,
.property_type = FUEL_GAUGE_RUNTIME_TO_EMPTY, FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
}, FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
{
.property_type = FUEL_GAUGE_REMAINING_CAPACITY,
},
{
.property_type = FUEL_GAUGE_FULL_CHARGE_CAPACITY,
},
{
.property_type = FUEL_GAUGE_CYCLE_COUNT,
},
{
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
},
{
.property_type = FUEL_GAUGE_SBS_MODE,
},
{
.property_type = FUEL_GAUGE_CHARGE_CURRENT,
},
{
.property_type = FUEL_GAUGE_CHARGE_VOLTAGE,
},
{
.property_type = FUEL_GAUGE_STATUS,
},
{
.property_type = FUEL_GAUGE_DESIGN_CAPACITY,
},
{
.property_type = FUEL_GAUGE_DESIGN_VOLTAGE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_FULL,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE_TIME_TO_EMPTY,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE_OK,
},
{
.property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
},
{
.property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
},
}; };
zassert_ok(fuel_gauge_get_props(fixture->dev, props, ARRAY_SIZE(props))); union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
zassert_ok(fuel_gauge_get_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)));
} }
ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_set_props__returns_ok)
{ {
/* Validate what props are supported by the driver */ /* Validate what props are supported by the driver */
struct fuel_gauge_property props[] = { fuel_gauge_prop_t prop_types[] = {
{ FUEL_GAUGE_SBS_MFR_ACCESS,
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS, FUEL_GAUGE_SBS_MODE,
}, FUEL_GAUGE_SBS_ATRATE,
{ FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
.property_type = FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM, FUEL_GAUGE_SBS_REMAINING_CAPACITY_ALARM,
},
{
.property_type = FUEL_GAUGE_SBS_REMAINING_TIME_ALARM,
},
{
.property_type = FUEL_GAUGE_SBS_MODE,
},
{
.property_type = FUEL_GAUGE_SBS_ATRATE,
},
}; };
union fuel_gauge_prop_val props[ARRAY_SIZE(prop_types)];
zassert_ok(fuel_gauge_set_props(fixture->dev, props, ARRAY_SIZE(props))); zassert_ok(fuel_gauge_set_props(fixture->dev, prop_types, props, ARRAY_SIZE(props)));
} }
ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok) ZTEST_USER_F(sbs_gauge_new_api, test_get_buffer_props__returns_ok)
{ {
/* Validate what properties are supported by the driver */ /* Validate what properties are supported by the driver */
struct fuel_gauge_buffer_property prop;
struct sbs_gauge_manufacturer_name mfg_name; struct sbs_gauge_manufacturer_name mfg_name;
struct sbs_gauge_device_name dev_name; struct sbs_gauge_device_name dev_name;
struct sbs_gauge_device_chemistry chem; struct sbs_gauge_device_chemistry chem;
prop.property_type = FUEL_GAUGE_MANUFACTURER_NAME; zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_MANUFACTURER_NAME, &mfg_name,
zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &mfg_name, sizeof(mfg_name))); sizeof(mfg_name)));
prop.property_type = FUEL_GAUGE_DEVICE_NAME; zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_NAME, &dev_name,
zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &dev_name, sizeof(dev_name))); sizeof(dev_name)));
prop.property_type = FUEL_GAUGE_DEVICE_CHEMISTRY; zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, FUEL_GAUGE_DEVICE_CHEMISTRY, &chem,
zassert_ok(fuel_gauge_get_buffer_prop(fixture->dev, &prop, &chem, sizeof(chem))); sizeof(chem)));
} }
ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a) ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a)
@ -283,23 +211,16 @@ ZTEST_USER_F(sbs_gauge_new_api, test_charging_5v_3a)
uint32_t expected_uV = 5000 * 1000; uint32_t expected_uV = 5000 * 1000;
uint32_t expected_uA = 3000 * 1000; uint32_t expected_uA = 3000 * 1000;
struct fuel_gauge_property voltage = { union fuel_gauge_prop_val voltage;
.property_type = FUEL_GAUGE_VOLTAGE, union fuel_gauge_prop_val current;
};
struct fuel_gauge_property current = {
.property_type = FUEL_GAUGE_CURRENT,
};
zassume_ok(emul_fuel_gauge_set_battery_charging(fixture->sbs_fuel_gauge, expected_uV, zassume_ok(emul_fuel_gauge_set_battery_charging(fixture->sbs_fuel_gauge, expected_uV,
expected_uA)); expected_uA));
zassert_ok(fuel_gauge_get_prop(fixture->dev, &voltage)); zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_VOLTAGE, &voltage));
zassert_ok(fuel_gauge_get_prop(fixture->dev, &current)); zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_CURRENT, &current));
zassert_equal(voltage.value.voltage, expected_uV, "Got %d instead of %d", zassert_equal(voltage.voltage, expected_uV, "Got %d instead of %d", voltage, expected_uV);
voltage.value.voltage, expected_uV); zassert_equal(current.current, expected_uA, "Got %d instead of %d", current, expected_uA);
zassert_equal(current.value.current, expected_uA, "Got %d instead of %d",
current.value.current, expected_uA);
} }
ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop) ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop)
@ -308,17 +229,14 @@ ZTEST_USER_F(sbs_gauge_new_api, test_set_get_single_prop)
uint16_t test_value = 0x1001; uint16_t test_value = 0x1001;
struct fuel_gauge_property mfr_acc_set = { union fuel_gauge_prop_val mfr_acc_set = {
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS, .sbs_mfr_access_word = test_value,
.value.sbs_mfr_access_word = test_value,
};
struct fuel_gauge_property mfr_acc_get = {
.property_type = FUEL_GAUGE_SBS_MFR_ACCESS,
}; };
union fuel_gauge_prop_val mfr_acc_get;
zassert_ok(fuel_gauge_set_prop(fixture->dev, &mfr_acc_set)); zassert_ok(fuel_gauge_set_prop(fixture->dev, FUEL_GAUGE_SBS_MFR_ACCESS, mfr_acc_set));
zassert_ok(fuel_gauge_get_prop(fixture->dev, &mfr_acc_get)); zassert_ok(fuel_gauge_get_prop(fixture->dev, FUEL_GAUGE_SBS_MFR_ACCESS, &mfr_acc_get));
zassert_equal(mfr_acc_get.value.sbs_mfr_access_word, test_value); zassert_equal(mfr_acc_get.sbs_mfr_access_word, test_value);
} }
ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL); ZTEST_SUITE(sbs_gauge_new_api, NULL, sbs_gauge_new_api_setup, NULL, NULL, NULL);