From 4df450aaa1fe87e73ea311b02a93af97e9112e32 Mon Sep 17 00:00:00 2001 From: Aaron Massey Date: Wed, 16 Aug 2023 14:39:38 -0600 Subject: [PATCH] fuel_gauge: Add battery cutoff support Many fuel gauge ICs offer a battery cutoff/shipping mode functionality that cutoff charge from the battery. This is often useful for preserving battery charge on devices while in storage. Add battery cutoff support to the fuel gauge API with a generic default SBS driver showing an example of support in tests. Signed-off-by: Aaron Massey --- doc/hardware/peripherals/fuel_gauge.rst | 9 +++ .../fuel_gauge/fuel_gauge_syscall_handlers.c | 9 +++ drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c | 70 +++++++++++++++++++ drivers/fuel_gauge/sbs_gauge/sbs_gauge.c | 57 +++++++++++++-- drivers/fuel_gauge/sbs_gauge/sbs_gauge.h | 25 +++++++ dts/bindings/fuel-gauge/battery-cutoff.yaml | 29 ++++++++ .../fuel-gauge/sbs,default-sbs-gauge.yaml | 22 ++++++ include/zephyr/drivers/emul_fuel_gauge.h | 21 ++++++ include/zephyr/drivers/fuel_gauge.h | 31 ++++++++ .../fuel_gauge/sbs_gauge/CMakeLists.txt | 5 +- tests/drivers/fuel_gauge/sbs_gauge/Kconfig | 11 +++ .../boards/emulated_board_cutoff.overlay | 30 ++++++++ .../fuel_gauge/sbs_gauge/src/test_cutoff.c | 29 ++++++++ .../sbs_gauge/src/test_cutoff_disabled.c | 29 ++++++++ .../fuel_gauge/sbs_gauge/testcase.yaml | 14 ++++ 15 files changed, 385 insertions(+), 6 deletions(-) create mode 100644 dts/bindings/fuel-gauge/battery-cutoff.yaml create mode 100644 dts/bindings/fuel-gauge/sbs,default-sbs-gauge.yaml create mode 100644 tests/drivers/fuel_gauge/sbs_gauge/Kconfig create mode 100644 tests/drivers/fuel_gauge/sbs_gauge/boards/emulated_board_cutoff.overlay create mode 100644 tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff.c create mode 100644 tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff_disabled.c diff --git a/doc/hardware/peripherals/fuel_gauge.rst b/doc/hardware/peripherals/fuel_gauge.rst index bc042c8b21f936d..bef7b12279603d2 100644 --- a/doc/hardware/peripherals/fuel_gauge.rst +++ b/doc/hardware/peripherals/fuel_gauge.rst @@ -23,6 +23,15 @@ or present-time current/voltage. Properties are fetched using a client allocated array of :c:struct:`fuel_gauge_get_property`. This array is then populated by values as according to its `property_type` field. +Battery Cutoff +============== + +Many fuel gauges embedded within battery packs expose a register address that when written to with a +specific payload will do a battery cutoff. This battery cutoff is often referred to as ship, shelf, +or sleep mode due to its utility in reducing battery drain while devices are stored or shipped. + +The fuel gauge API exposes battery cutoff with the :c:func:`fuel_gauge_battery_cutoff` function. + Caching ======= diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 299bd3d5c09d69c..4c664b0f5513b53 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -70,3 +70,12 @@ static inline int z_vrfy_fuel_gauge_get_buffer_prop(const struct device *dev, } #include + +static inline int z_vrfy_fuel_gauge_battery_cutoff(const struct device *dev) +{ + Z_OOPS(Z_SYSCALL_DRIVER_FUEL_GAUGE(dev, battery_cutoff)); + + return z_impl_fuel_gauge_battery_cutoff(dev); +} + +#include diff --git a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c index 69b9f798b55e480..c84a73e75ffe009 100644 --- a/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/emul_sbs_gauge.c @@ -16,13 +16,17 @@ #include LOG_MODULE_REGISTER(sbs_sbs_gauge); +#include +#include #include +#include #include #include #include #include #include #include +#include #include "sbs_gauge.h" @@ -33,6 +37,13 @@ struct sbs_gauge_emul_data { uint16_t remaining_time_alarm; uint16_t mode; int16_t at_rate; + /* Whether the battery cutoff or not */ + bool is_cutoff; + /* + * Counts the number of times the cutoff payload has been sent to the designated + * register + */ + uint8_t cutoff_writes; struct { /* Non-register values associated with the state of the battery */ /* Battery terminal voltage */ @@ -46,8 +57,46 @@ struct sbs_gauge_emul_data { struct sbs_gauge_emul_cfg { /** I2C address of emulator */ uint16_t addr; + bool cutoff_support; + uint32_t cutoff_reg_addr; + uint16_t cutoff_payload[SBS_GAUGE_CUTOFF_PAYLOAD_MAX_SIZE]; }; +static void emul_sbs_gauge_maybe_do_battery_cutoff(const struct emul *target, int reg, int val) +{ + struct sbs_gauge_emul_data *data = target->data; + const struct sbs_gauge_emul_cfg *cfg = target->cfg; + + /* Check if this is a cutoff write */ + if (cfg->cutoff_support && reg == cfg->cutoff_reg_addr) { + __ASSERT_NO_MSG(ARRAY_SIZE(cfg->cutoff_payload) > 0); + /* + * Calculate the next payload element value for a battery cutoff. + * + * We thoroughly check bounds elsewhere, so we can be confident we're not indexing + * past the end of the array. + */ + uint16_t target_payload_elem_val = cfg->cutoff_payload[data->cutoff_writes]; + + if (target_payload_elem_val == val) { + data->cutoff_writes++; + __ASSERT_NO_MSG(data->cutoff_writes <= ARRAY_SIZE(cfg->cutoff_payload)); + } else { + /* Wrong payload target value, reset cutoff sequence detection. */ + data->cutoff_writes = 0; + } + + if (data->cutoff_writes == ARRAY_SIZE(cfg->cutoff_payload)) { + data->is_cutoff = true; + data->cutoff_writes = 0; + } + } + /* Not a cutoff write, reset payload counter */ + else { + data->cutoff_writes = 0; + } +} + static int emul_sbs_gauge_reg_write(const struct emul *target, int reg, int val) { struct sbs_gauge_emul_data *data = target->data; @@ -74,6 +123,12 @@ static int emul_sbs_gauge_reg_write(const struct emul *target, int reg, int val) return -EIO; } + /* + * One of the above registers is always designated as a "cutoff" register, usually it's + * MANUFACTURER ACCESS, but not always. + */ + emul_sbs_gauge_maybe_do_battery_cutoff(target, reg, val); + return 0; } @@ -245,8 +300,20 @@ static int emul_sbs_fuel_gauge_set_battery_charging(const struct emul *target, u return 0; } +static int emul_sbs_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff) +{ + struct sbs_gauge_emul_data *data = target->data; + + __ASSERT_NO_MSG(cutoff != NULL); + + *cutoff = data->is_cutoff; + + return 0; +} + static const struct fuel_gauge_emul_driver_api sbs_gauge_backend_api = { .set_battery_charging = emul_sbs_fuel_gauge_set_battery_charging, + .is_battery_cutoff = emul_sbs_fuel_gauge_is_battery_cutoff, }; static const struct i2c_emul_api sbs_gauge_emul_api_i2c = { @@ -303,6 +370,9 @@ static int emul_sbs_sbs_gauge_init(const struct emul *target, const struct devic static struct sbs_gauge_emul_data sbs_gauge_emul_data_##n; \ static const struct sbs_gauge_emul_cfg sbs_gauge_emul_cfg_##n = { \ .addr = DT_INST_REG_ADDR(n), \ + .cutoff_support = DT_PROP_OR(DT_DRV_INST(n), battery_cutoff_support, false), \ + .cutoff_reg_addr = DT_PROP_OR(DT_DRV_INST(n), battery_cutoff_reg_addr, 0), \ + .cutoff_payload = DT_PROP_OR(DT_DRV_INST(n), battery_cutoff_payload, {}), \ }; \ EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_gauge_init, &sbs_gauge_emul_data_##n, \ &sbs_gauge_emul_cfg_##n, &sbs_gauge_emul_api_i2c, \ diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c index f1d107330cb3d5c..69c0d7dfdbfa497 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.c @@ -11,10 +11,14 @@ #include "sbs_gauge.h" +#include +#include +#include #include #include #include #include +#include LOG_MODULE_REGISTER(sbs_gauge); @@ -173,6 +177,25 @@ static int sbs_gauge_get_prop(const struct device *dev, struct fuel_gauge_get_pr return rc; } +static int sbs_gauge_do_battery_cutoff(const struct device *dev) +{ + int rc; + const struct sbs_gauge_config *cfg = dev->config; + + if (cfg->cutoff_cfg == NULL) { + return -ENOTSUP; + } + + for (int i = 0; i < cfg->cutoff_cfg->payload_size; i++) { + rc = sbs_cmd_reg_write(dev, cfg->cutoff_cfg->reg, cfg->cutoff_cfg->payload[i]); + if (rc != 0) { + return rc; + } + } + + return rc; +} + static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_property *prop) { int rc = 0; @@ -203,7 +226,6 @@ static int sbs_gauge_set_prop(const struct device *dev, struct fuel_gauge_set_pr rc = sbs_cmd_reg_write(dev, SBS_GAUGE_CMD_AR, prop->value.sbs_at_rate); prop->value.sbs_at_rate = val; break; - default: rc = -ENOTSUP; } @@ -307,17 +329,44 @@ static const struct fuel_gauge_driver_api sbs_gauge_driver_api = { .get_property = &sbs_gauge_get_props, .set_property = &sbs_gauge_set_props, .get_buffer_property = &sbs_gauge_get_buffer_prop, + .battery_cutoff = &sbs_gauge_do_battery_cutoff, }; -/* FIXME: fix init priority */ +/* Concatenates index to battery config to create unique cfg variable name per instance. */ +#define _SBS_GAUGE_BATT_CUTOFF_CFG_VAR_NAME(index) sbs_gauge_batt_cutoff_cfg_##index + +/* Declare and define the battery config struct */ +#define _SBS_GAUGE_CONFIG_INIT(index) \ + static const struct sbs_gauge_battery_cutoff_config _SBS_GAUGE_BATT_CUTOFF_CFG_VAR_NAME( \ + index) = { \ + .reg = DT_INST_PROP(index, battery_cutoff_reg_addr), \ + .payload = DT_INST_PROP(index, battery_cutoff_payload), \ + .payload_size = DT_INST_PROP_LEN(index, battery_cutoff_payload), \ + }; + +/* Conditionally defined battery config based on battery cutoff support */ +#define SBS_GAUGE_CONFIG_DEFINE(index) \ + COND_CODE_1(DT_INST_PROP_OR(index, battery_cutoff_support, false), \ + (_SBS_GAUGE_CONFIG_INIT(index)), (;)) + +/* Conditionally get the battery config variable name or NULL based on battery cutoff support */ +#define SBS_GAUGE_GET_BATTERY_CONFIG_NAME(index) \ + COND_CODE_1(DT_INST_PROP_OR(index, battery_cutoff_support, false), \ + (&_SBS_GAUGE_BATT_CUTOFF_CFG_VAR_NAME(index)), (NULL)) + #define SBS_GAUGE_INIT(index) \ - \ + SBS_GAUGE_CONFIG_DEFINE(index); \ static const struct sbs_gauge_config sbs_gauge_config_##index = { \ .i2c = I2C_DT_SPEC_INST_GET(index), \ - }; \ + .cutoff_cfg = SBS_GAUGE_GET_BATTERY_CONFIG_NAME(index)}; \ \ DEVICE_DT_INST_DEFINE(index, &sbs_gauge_init, NULL, NULL, &sbs_gauge_config_##index, \ POST_KERNEL, CONFIG_FUEL_GAUGE_INIT_PRIORITY, \ &sbs_gauge_driver_api); DT_INST_FOREACH_STATUS_OKAY(SBS_GAUGE_INIT) + +#define CUTOFF_PAYLOAD_SIZE_ASSERT(inst) \ + BUILD_ASSERT(DT_INST_PROP_LEN_OR(inst, battery_cutoff_payload, 0) <= \ + SBS_GAUGE_CUTOFF_PAYLOAD_MAX_SIZE); +DT_INST_FOREACH_STATUS_OKAY(CUTOFF_PAYLOAD_SIZE_ASSERT) diff --git a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.h b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.h index 8cafb65df38ca36..2ae8007125c5b63 100644 --- a/drivers/fuel_gauge/sbs_gauge/sbs_gauge.h +++ b/drivers/fuel_gauge/sbs_gauge/sbs_gauge.h @@ -47,8 +47,33 @@ #define SBS_GAUGE_DELAY 1000 +/* + * Nearly all cutoff payloads are actually a singular value that must be written twice to the fuel + * gauge. For the case where it's a singular value that must only be written to the fuel gauge only + * once, retransmitting the duplicate write has no significant negative consequences. + * + * Why not devicetree: Finding the maximum length of all the battery cutoff payloads in a devicetree + * at compile-time would require labyrinthine amount of macro-batics. + * + * Why not compute at runtime: It's not worth the memory given having more than a single fuel gauge + * is rare, and most will have a payload size of 2. + * + * This is validated as a BUILD_ASSERT in the driver. + */ +#define SBS_GAUGE_CUTOFF_PAYLOAD_MAX_SIZE 2 + +struct sbs_gauge_battery_cutoff_config { + /* Size of the payload array */ + size_t payload_size; + /* Array SMBus word values to write to cut off the battery */ + uint32_t payload[SBS_GAUGE_CUTOFF_PAYLOAD_MAX_SIZE]; + /* Register to write cutoff payload */ + uint8_t reg; +}; + struct sbs_gauge_config { struct i2c_dt_spec i2c; + const struct sbs_gauge_battery_cutoff_config *cutoff_cfg; }; #endif diff --git a/dts/bindings/fuel-gauge/battery-cutoff.yaml b/dts/bindings/fuel-gauge/battery-cutoff.yaml new file mode 100644 index 000000000000000..c3272cc5376ddf1 --- /dev/null +++ b/dts/bindings/fuel-gauge/battery-cutoff.yaml @@ -0,0 +1,29 @@ +# +# Copyright 2023 Google LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: | + + Properties for fuel-gauges that may control battery cutoff, this is common in SBS-compliant or + similarly smart battery fuel gauges. + + Note: These properties are to be used with meaningful defaults in fuel gauge ICs that can cut off + their associated battery from the system. See the default fuel gauge SBS Gauge compatible as an + example. + +properties: + battery-cutoff-support: + description: | + Helper prop that indicates whether this device can cutoff the battery; this is also often + referred to as ship or sleep mode. + type: boolean + battery-cutoff-reg-addr: + description: | + Address of register to receive cutoff payload for battery cutoff. + type: int + battery-cutoff-payload: + description: | + Payload to write to cutoff battery register. This must be array of maximum 2 integers. + type: array diff --git a/dts/bindings/fuel-gauge/sbs,default-sbs-gauge.yaml b/dts/bindings/fuel-gauge/sbs,default-sbs-gauge.yaml new file mode 100644 index 000000000000000..db000b80298aa73 --- /dev/null +++ b/dts/bindings/fuel-gauge/sbs,default-sbs-gauge.yaml @@ -0,0 +1,22 @@ +# +# Copyright 2023 Google LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +compatible: "sbs,default-sbs-gauge" + +include: ["sbs,sbs-gauge-new-api.yaml", "battery-cutoff.yaml"] + +description: | + Default generic smart battery fuel gauge driver. Includes support for battery cutoff if enabled. + + This compatible is intended to be used with the abstract SBS Gauge compatible because it is + actuated by the SBS driver for SBS compliant fuel gauge ICs. + +properties: + battery-cutoff-reg-addr: + # For SBS compliant fuel gauges this is usually "ManufactuerAccess" + default: 0x0 + battery-cutoff-payload: + default: [0x0010, 0x0010] diff --git a/include/zephyr/drivers/emul_fuel_gauge.h b/include/zephyr/drivers/emul_fuel_gauge.h index c8af1c91a561a1e..63b85d227c195a8 100644 --- a/include/zephyr/drivers/emul_fuel_gauge.h +++ b/include/zephyr/drivers/emul_fuel_gauge.h @@ -34,6 +34,7 @@ extern "C" { */ __subsystem struct fuel_gauge_emul_driver_api { int (*set_battery_charging)(const struct emul *emul, uint32_t uV, int uA); + int (*is_battery_cutoff)(const struct emul *emul, bool *cutoff); }; /** * @endcond @@ -66,6 +67,26 @@ static inline int emul_fuel_gauge_set_battery_charging(const struct emul *target return backend_api->set_battery_charging(target, uV, uA); } +/** + * @brief Check if the battery has been cut off. + * + * @param target Pointer to the emulator structure for the fuel gauge emulator instance. + * @param cutoff Pointer to bool storing variable. + * + * @retval 0 If successful. + * @retval -ENOTSUP if not supported by emulator. + */ +static inline int emul_fuel_gauge_is_battery_cutoff(const struct emul *target, bool *cutoff) +{ + const struct fuel_gauge_emul_driver_api *backend_api = + (const struct fuel_gauge_emul_driver_api *)target->backend_api; + + if (backend_api->is_battery_cutoff == 0) { + return -ENOTSUP; + } + return backend_api->is_battery_cutoff(target, cutoff); +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index fc8dd0d1d6b1ebe..5be69baa8ab2a97 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -38,6 +38,8 @@ enum fuel_gauge_property { */ FUEL_GAUGE_AVG_CURRENT = 0, + /** Used to cutoff the battery from the system - useful for storage/shipping of devices */ + FUEL_GAUGE_BATTERY_CUTOFF, /** Battery current (uA); negative=discharging */ FUEL_GAUGE_CURRENT, /** Whether the battery underlying the fuel-gauge is cut off from charge */ @@ -268,6 +270,13 @@ typedef int (*fuel_gauge_get_buffer_property_t)(const struct device *dev, struct fuel_gauge_get_buffer_property *prop, void *dst, size_t dst_len); +/** + * @typedef fuel_gauge_battery_cutoff_t + * @brief Callback API for doing a battery cutoff. + * + * See fuel_gauge_battery_cutoff() for argument description + */ +typedef int (*fuel_gauge_battery_cutoff_t)(const struct device *dev); /* Caching is entirely on the onus of the client */ @@ -275,6 +284,7 @@ __subsystem struct fuel_gauge_driver_api { fuel_gauge_get_property_t get_property; fuel_gauge_set_property_t set_property; fuel_gauge_get_buffer_property_t get_buffer_property; + fuel_gauge_battery_cutoff_t battery_cutoff; }; /** @@ -363,6 +373,27 @@ static inline int z_impl_fuel_gauge_get_buffer_prop(const struct device *dev, return api->get_buffer_property(dev, prop, dst, dst_len); } +/** + * @brief Have fuel gauge cutoff its associated battery. + * + * @param dev Pointer to the battery fuel-gauge device + * + * @return return=0 if successful and battery cutoff is now in process, return < 0 if failed to do + * battery cutoff. + */ +__syscall int fuel_gauge_battery_cutoff(const struct device *dev); + +static inline int z_impl_fuel_gauge_battery_cutoff(const struct device *dev) +{ + const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; + + if (api->battery_cutoff == NULL) { + return -ENOSYS; + } + + return api->battery_cutoff(dev); +} + /** * @} */ diff --git a/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt b/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt index 151d3bf8ce9db61..cd386c5afd3e271 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt +++ b/tests/drivers/fuel_gauge/sbs_gauge/CMakeLists.txt @@ -4,7 +4,8 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(device) -FILE(GLOB app_sources src/test_sbs_gauge.c) +target_sources(app PRIVATE src/test_sbs_gauge.c) +target_sources_ifndef(CONFIG_TEST_SBS_CUTOFF_EXTENSION app PRIVATE src/test_cutoff_disabled.c) +target_sources_ifdef(CONFIG_TEST_SBS_CUTOFF_EXTENSION app PRIVATE src/test_cutoff.c) target_include_directories(app PRIVATE include) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/fuel_gauge/sbs_gauge/Kconfig b/tests/drivers/fuel_gauge/sbs_gauge/Kconfig new file mode 100644 index 000000000000000..c7a8fbb930fae36 --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/Kconfig @@ -0,0 +1,11 @@ +# Copyright 2023 Google LLC +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config TEST_SBS_CUTOFF_EXTENSION + bool "Test Battery Cutoff" + help + Enabling this option adds test sources that verify if the battery cutoff extension to the + SBS driver are functional. diff --git a/tests/drivers/fuel_gauge/sbs_gauge/boards/emulated_board_cutoff.overlay b/tests/drivers/fuel_gauge/sbs_gauge/boards/emulated_board_cutoff.overlay new file mode 100644 index 000000000000000..cf40ff46b20bce4 --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/boards/emulated_board_cutoff.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + fake_i2c_bus: i2c@100 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x100 4>; + }; +}; + +&fake_i2c_bus { + clock-frequency = ; + compatible = "zephyr,i2c-emul-controller"; + smartbattery0: smartbattery@b { + compatible = "sbs,default-sbs-gauge","sbs,sbs-gauge-new-api"; + reg = <0x0b>; + status = "okay"; + battery-cutoff-support; + battery-cutoff-payload = <0x0010 0x0020>; + }; +}; diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff.c new file mode 100644 index 000000000000000..2728ac9ffb894a9 --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff.c @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "test_sbs_gauge.h" + +ZTEST_F(sbs_gauge_new_api, test_cutoff) +{ + bool is_cutoff; + + /* Initially there should be no cutoff */ + zassert_ok(emul_fuel_gauge_is_battery_cutoff(fixture->sbs_fuel_gauge, &is_cutoff)); + zassert_false(is_cutoff); + + zassert_ok(fuel_gauge_battery_cutoff(fixture->dev)); + + /* Now we should've cutoff */ + zassert_ok(emul_fuel_gauge_is_battery_cutoff(fixture->sbs_fuel_gauge, &is_cutoff)); + zassert_true(is_cutoff); +} diff --git a/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff_disabled.c b/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff_disabled.c new file mode 100644 index 000000000000000..12084542e6db020 --- /dev/null +++ b/tests/drivers/fuel_gauge/sbs_gauge/src/test_cutoff_disabled.c @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "test_sbs_gauge.h" + +ZTEST_F(sbs_gauge_new_api, test_cutoff_disabled) +{ + bool is_cutoff; + + /* Initially there should be no cutoff */ + zassert_ok(emul_fuel_gauge_is_battery_cutoff(fixture->sbs_fuel_gauge, &is_cutoff)); + zassert_false(is_cutoff); + + zassert_not_equal(fuel_gauge_battery_cutoff(fixture->dev), 0); + + /* We confirm there was no cutoff */ + zassert_ok(emul_fuel_gauge_is_battery_cutoff(fixture->sbs_fuel_gauge, &is_cutoff)); + zassert_false(is_cutoff); +} diff --git a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml index 5e8500a8dece28a..d7f85f58bb6789a 100644 --- a/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml +++ b/tests/drivers/fuel_gauge/sbs_gauge/testcase.yaml @@ -40,3 +40,17 @@ tests: extra_args: - CONF_FILE="prj.conf;boards/qemu_cortex_a53.conf" - DTC_OVERLAY_FILE="boards/qemu_cortex_a53.overlay" + drivers.sbs_gauge_new_api.emulated.cutoff: + tags: + - drivers + - fuel_gauge + filter: dt_compat_enabled("sbs,sbs-gauge-new-api") + extra_args: + - DTC_OVERLAY_FILE="boards/emulated_board_cutoff.overlay" + extra_configs: + - CONFIG_EMUL=y + - CONFIG_TEST_SBS_CUTOFF_EXTENSION=y + - CONFIG_USERSPACE=y + platform_allow: + - native_posix + - qemu_x86