From e667c0ac372ae4eaf5d8f32322f82a8d73ef3e87 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 31 Mar 2023 13:43:51 -0500 Subject: [PATCH] charger: Sample sbs charger driver with tests Adds a sample sbs charger driver and basics tests. Signed-off-by: Ricardo Rivera-Matos --- drivers/CMakeLists.txt | 1 + drivers/Kconfig | 1 + drivers/charger/CMakeLists.txt | 5 + drivers/charger/Kconfig | 24 +++ drivers/charger/charger_syscall_handlers.c | 26 ++++ drivers/charger/sbs_charger/CMakeLists.txt | 6 + drivers/charger/sbs_charger/Kconfig | 17 +++ .../charger/sbs_charger/emul_sbs_charger.c | 142 ++++++++++++++++++ drivers/charger/sbs_charger/sbs_charger.c | 122 +++++++++++++++ drivers/charger/sbs_charger/sbs_charger.h | 29 ++++ dts/bindings/charger/sbs,sbs-charger.yaml | 5 + include/zephyr/drivers/charger.h | 36 ++++- .../charger/sbs_charger/CMakeLists.txt | 8 + .../sbs_charger/boards/emulated_board.conf | 6 + .../sbs_charger/boards/emulated_board.overlay | 28 ++++ .../sbs_charger/boards/qemu_cortex_a53.conf | 7 + .../boards/qemu_cortex_a53.overlay | 32 ++++ tests/drivers/charger/sbs_charger/prj.conf | 7 + .../sbs_charger/src/test_sbs_charger.c | 109 ++++++++++++++ .../drivers/charger/sbs_charger/testcase.yaml | 30 ++++ 20 files changed, 635 insertions(+), 6 deletions(-) create mode 100644 drivers/charger/CMakeLists.txt create mode 100644 drivers/charger/Kconfig create mode 100644 drivers/charger/charger_syscall_handlers.c create mode 100644 drivers/charger/sbs_charger/CMakeLists.txt create mode 100644 drivers/charger/sbs_charger/Kconfig create mode 100644 drivers/charger/sbs_charger/emul_sbs_charger.c create mode 100644 drivers/charger/sbs_charger/sbs_charger.c create mode 100644 drivers/charger/sbs_charger/sbs_charger.h create mode 100644 dts/bindings/charger/sbs,sbs-charger.yaml create mode 100644 tests/drivers/charger/sbs_charger/CMakeLists.txt create mode 100644 tests/drivers/charger/sbs_charger/boards/emulated_board.conf create mode 100644 tests/drivers/charger/sbs_charger/boards/emulated_board.overlay create mode 100644 tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf create mode 100644 tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay create mode 100644 tests/drivers/charger/sbs_charger/prj.conf create mode 100644 tests/drivers/charger/sbs_charger/src/test_sbs_charger.c create mode 100644 tests/drivers/charger/sbs_charger/testcase.yaml diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 98d5b55a2b9d173..52291148d2d4738 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth) add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache) add_subdirectory_ifdef(CONFIG_CAN can) add_subdirectory_ifdef(CONFIG_CLOCK_CONTROL clock_control) +add_subdirectory_ifdef(CONFIG_CHARGER charger) add_subdirectory_ifdef(CONFIG_CONSOLE console) add_subdirectory_ifdef(CONFIG_COREDUMP_DEVICE coredump) add_subdirectory_ifdef(CONFIG_COUNTER counter) diff --git a/drivers/Kconfig b/drivers/Kconfig index 1439d53307196c8..b7a63db5c46f2be 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -11,6 +11,7 @@ source "drivers/bbram/Kconfig" source "drivers/bluetooth/Kconfig" source "drivers/cache/Kconfig" source "drivers/can/Kconfig" +source "drivers/charger/Kconfig" source "drivers/clock_control/Kconfig" source "drivers/console/Kconfig" source "drivers/coredump/Kconfig" diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt new file mode 100644 index 000000000000000..426a9a5d9093d4d --- /dev/null +++ b/drivers/charger/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_SBS_CHARGER sbs_charger) + +zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_syscall_handlers.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig new file mode 100644 index 000000000000000..efddbcba329d8aa --- /dev/null +++ b/drivers/charger/Kconfig @@ -0,0 +1,24 @@ +# Copyright 2023 Cirrus Logic, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig CHARGER + bool "Battery charger drivers" + help + Enable battery charger driver configuration. + +if CHARGER + +module = CHARGER +module-str = charger +source "subsys/logging/Kconfig.template.log_config" + +config CHARGER_INIT_PRIORITY + int "Battery charger init priority" + default 90 + help + Battery charger initialization priority. + +source "drivers/charger/sbs_charger/Kconfig" + +endif # CHARGER diff --git a/drivers/charger/charger_syscall_handlers.c b/drivers/charger/charger_syscall_handlers.c new file mode 100644 index 000000000000000..6ac042c613552a4 --- /dev/null +++ b/drivers/charger/charger_syscall_handlers.c @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static inline int z_vrfy_charger_get_prop(const struct device *dev, + struct charger_get_property *props, size_t props_len) +{ + struct charger_get_property k_props[props_len]; + + Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, get_property)); + + Z_OOPS(z_user_from_copy(k_props, props, props_len * sizeof(struct charger_get_property))); + + int ret = z_impl_charger_get_prop(dev, k_props, props_len); + + Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct charger_get_property))); + + return ret; +} + +#include diff --git a/drivers/charger/sbs_charger/CMakeLists.txt b/drivers/charger/sbs_charger/CMakeLists.txt new file mode 100644 index 000000000000000..53d2ec139e6de7f --- /dev/null +++ b/drivers/charger/sbs_charger/CMakeLists.txt @@ -0,0 +1,6 @@ +zephyr_library() + +zephyr_library_sources(sbs_charger.c) + +zephyr_include_directories_ifdef(CONFIG_EMUL_SBS_CHARGER .) +zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/sbs_charger/Kconfig b/drivers/charger/sbs_charger/Kconfig new file mode 100644 index 000000000000000..4d31a5176ea798d --- /dev/null +++ b/drivers/charger/sbs_charger/Kconfig @@ -0,0 +1,17 @@ +# Copyright 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SBS_CHARGER + bool "Smart Battery Charger" + default y + depends on DT_HAS_SBS_SBS_CHARGER_ENABLED + select I2C + help + Enable I2C-based/SMBus-based driver for a Smart Battery Charger. + +config EMUL_SBS_CHARGER + bool "Emulate an SBS 1.1 compliant smart battery charger" + depends on EMUL + help + It provides reading which follow a simple sequence, thus allowing + test code to check that things are working as expected. diff --git a/drivers/charger/sbs_charger/emul_sbs_charger.c b/drivers/charger/sbs_charger/emul_sbs_charger.c new file mode 100644 index 000000000000000..7035ff0a8993bec --- /dev/null +++ b/drivers/charger/sbs_charger/emul_sbs_charger.c @@ -0,0 +1,142 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Emulator for SBS 1.1 compliant smart battery charger. + */ + +#define DT_DRV_COMPAT sbs_sbs_charger + +#include +LOG_MODULE_REGISTER(sbs_sbs_charger); + +#include +#include +#include +#include +#include + +#include "sbs_charger.h" + +/** Static configuration for the emulator */ +struct sbs_charger_emul_cfg { + /** I2C address of emulator */ + uint16_t addr; +}; + +static int emul_sbs_charger_reg_write(const struct emul *target, int reg, int val) +{ + LOG_INF("write %x = %x", reg, val); + switch (reg) { + default: + LOG_ERR("Unknown write %x", reg); + return -EIO; + } + + return 0; +} + +static int emul_sbs_charger_reg_read(const struct emul *target, int reg, int *val) +{ + switch (reg) { + case SBS_CHARGER_REG_SPEC_INFO: + case SBS_CHARGER_REG_STATUS: + case SBS_CHARGER_REG_ALARM_WARNING: + /* Arbitrary stub value. */ + *val = 1; + break; + default: + LOG_ERR("Unknown register 0x%x read", reg); + return -EIO; + } + LOG_INF("read 0x%x = 0x%x", reg, *val); + + return 0; +} + +static int sbs_charger_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, + int num_msgs, int addr) +{ + /* Largely copied from emul_sbs_gauge.c */ + struct sbs_charger_emul_data *data; + unsigned int val; + int reg; + int rc; + + data = target->data; + + __ASSERT_NO_MSG(msgs && num_msgs); + + i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false); + switch (num_msgs) { + case 2: + if (msgs->flags & I2C_MSG_READ) { + LOG_ERR("Unexpected read"); + return -EIO; + } + if (msgs->len != 1) { + LOG_ERR("Unexpected msg0 length %d", msgs->len); + return -EIO; + } + reg = msgs->buf[0]; + + /* Now process the 'read' part of the message */ + msgs++; + if (msgs->flags & I2C_MSG_READ) { + switch (msgs->len - 1) { + case 1: + rc = emul_sbs_charger_reg_read(target, reg, &val); + if (rc) { + /* Return before writing bad value to message buffer */ + return rc; + } + + /* SBS uses SMBus, which sends data in little-endian format. */ + sys_put_le16(val, msgs->buf); + break; + default: + LOG_ERR("Unexpected msg1 length %d", msgs->len); + return -EIO; + } + } else { + /* We write a word (2 bytes by the SBS spec) */ + if (msgs->len != 2) { + LOG_ERR("Unexpected msg1 length %d", msgs->len); + } + uint16_t value = sys_get_le16(msgs->buf); + + rc = emul_sbs_charger_reg_write(target, reg, value); + } + break; + default: + LOG_ERR("Invalid number of messages: %d", num_msgs); + return -EIO; + } + + return rc; +} + +static const struct i2c_emul_api sbs_charger_emul_api_i2c = { + .transfer = sbs_charger_emul_transfer_i2c, +}; + +static int emul_sbs_sbs_charger_init(const struct emul *target, const struct device *parent) +{ + ARG_UNUSED(target); + ARG_UNUSED(parent); + + return 0; +} + +/* + * Main instantiation macro. SBS Charger Emulator only implemented for I2C + */ +#define SBS_CHARGER_EMUL(n) \ + static const struct sbs_charger_emul_cfg sbs_charger_emul_cfg_##n = { \ + .addr = DT_INST_REG_ADDR(n), \ + }; \ + EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_charger_init, NULL, &sbs_charger_emul_cfg_##n, \ + &sbs_charger_emul_api_i2c, NULL) + +DT_INST_FOREACH_STATUS_OKAY(SBS_CHARGER_EMUL) diff --git a/drivers/charger/sbs_charger/sbs_charger.c b/drivers/charger/sbs_charger/sbs_charger.c new file mode 100644 index 000000000000000..fb3a46f1508cd66 --- /dev/null +++ b/drivers/charger/sbs_charger/sbs_charger.c @@ -0,0 +1,122 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sbs_sbs_charger + +#include "sbs_charger.h" + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sbs_charger); + +static int sbs_cmd_reg_read(const struct device *dev, uint8_t reg_addr, uint16_t *val) +{ + const struct sbs_charger_config *cfg; + uint8_t i2c_data[2]; + int status; + + cfg = dev->config; + status = i2c_burst_read_dt(&cfg->i2c, reg_addr, i2c_data, ARRAY_SIZE(i2c_data)); + if (status < 0) { + LOG_ERR("Unable to read register"); + return status; + } + + *val = sys_get_le16(i2c_data); + + return 0; +} + +static int sbs_charger_get_prop(const struct device *dev, struct charger_get_property *prop) +{ + uint16_t val = 0; + int ret = 0; + + switch (prop->property_type) { + case CHARGER_ONLINE: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, &val); + if (val & SBS_CHARGER_STATUS_AC_PRESENT) + prop->value.online = CHARGER_ONLINE_FIXED; + else + prop->value.online = CHARGER_ONLINE_OFFLINE; + + break; + case CHARGER_PRESENT: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, &val); + prop->value.present = !!(val & SBS_CHARGER_STATUS_BATTERY_PRESENT); + + break; + case CHARGER_STATUS: + ret = sbs_cmd_reg_read(dev, SBS_CHARGER_REG_STATUS, &val); + if (!(val & SBS_CHARGER_STATUS_BATTERY_PRESENT)) + prop->value.status = CHARGER_STATUS_NOT_CHARGING; + else if (val & SBS_CHARGER_STATUS_AC_PRESENT && + !(val & SBS_CHARGER_STATUS_CHARGE_INHIBITED)) + prop->value.status = CHARGER_STATUS_CHARGING; + else + prop->value.status = CHARGER_STATUS_DISCHARGING; + break; + default: + ret = -ENOTSUP; + } + + prop->err = ret; + + return ret; +} + +static int sbs_charger_get_props(const struct device *dev, struct charger_get_property *props, + size_t len) +{ + int err_count = 0; + + for (int i = 0; i < len; i++) { + int ret = sbs_charger_get_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 + * + * @return 0 for success + */ +static int sbs_charger_init(const struct device *dev) +{ + const struct sbs_charger_config *cfg; + + cfg = dev->config; + + if (!device_is_ready(cfg->i2c.bus)) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + return 0; +} + +static const struct charger_driver_api sbs_charger_driver_api = { + .get_property = &sbs_charger_get_props, +}; + +#define SBS_CHARGER_INIT(index) \ + \ + static const struct sbs_charger_config sbs_charger_config_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, &sbs_charger_init, NULL, NULL, &sbs_charger_config_##index, \ + POST_KERNEL, CONFIG_CHARGER_INIT_PRIORITY, &sbs_charger_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SBS_CHARGER_INIT) diff --git a/drivers/charger/sbs_charger/sbs_charger.h b/drivers/charger/sbs_charger/sbs_charger.h new file mode 100644 index 000000000000000..3a94735d20d8529 --- /dev/null +++ b/drivers/charger/sbs_charger/sbs_charger.h @@ -0,0 +1,29 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_SBS_CHARGER_H_ +#define ZEPHYR_DRIVERS_SENSOR_SBS_CHARGER_H_ + +#include +#include + +#define SBS_CHARGER_REG_SPEC_INFO 0x11 +#define SBS_CHARGER_REG_STATUS 0x13 +#define SBS_CHARGER_REG_ALARM_WARNING 0x16 + +#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1) +#define SBS_CHARGER_STATUS_RES_COLD BIT(9) +#define SBS_CHARGER_STATUS_RES_HOT BIT(10) +#define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14) +#define SBS_CHARGER_STATUS_AC_PRESENT BIT(15) + +#define SBS_CHARGER_POLL_TIME 500 + +struct sbs_charger_config { + struct i2c_dt_spec i2c; +}; + +#endif diff --git a/dts/bindings/charger/sbs,sbs-charger.yaml b/dts/bindings/charger/sbs,sbs-charger.yaml new file mode 100644 index 000000000000000..544d1d07ed6c6b4 --- /dev/null +++ b/dts/bindings/charger/sbs,sbs-charger.yaml @@ -0,0 +1,5 @@ +description: SBS 1.1 compliant charger (http://www.sbs-forum.org/specs) + +compatible: "sbs,sbs-charger" + +include: [i2c-device.yaml, charger.yaml] diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index dcbd3a9ea17b9fc..0b06ecb9d590e97 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -20,6 +20,7 @@ extern "C" { #endif /* __cplusplus */ +#include #include #include #include @@ -102,6 +103,22 @@ struct charger_get_property { } value; }; +/** + * @typedef charger_get_property_t + * @brief Callback API for getting a charger property. + * + * See charger_get_property() for argument description + */ +typedef int (*charger_get_property_t)(const struct device *dev, + struct charger_get_property *props, + size_t props_len); + +/* Caching is entirely on the onus of the client */ + +__subsystem struct charger_driver_api { + charger_get_property_t get_property; +}; + /** * @brief Fetch a battery charger property * @@ -114,14 +131,21 @@ struct charger_get_property { * @return return=0 if successful, return < 0 if getting all properties failed, return > 0 if some * properties failed where return=number of failing properties. */ -typedef int (*charger_get_property_t)(const struct device *dev, struct charger_get_property *props, - size_t props_len); +__syscall int charger_get_prop(const struct device *dev, struct charger_get_property *props, + size_t props_len); -/* Caching is entirely on the onus of the client */ +static inline int z_impl_charger_get_prop(const struct device *dev, + struct charger_get_property *props, + size_t props_len) +{ + const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; -__subsystem struct charger_driver_api { - charger_get_property_t get_property; -}; + if (api->get_property == NULL) { + return -ENOSYS; + } + + return api->get_property(dev, props, props_len); +} /** * @} diff --git a/tests/drivers/charger/sbs_charger/CMakeLists.txt b/tests/drivers/charger/sbs_charger/CMakeLists.txt new file mode 100644 index 000000000000000..2c1dfa0e0216061 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +FILE(GLOB app_sources src/test_sbs_charger.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/charger/sbs_charger/boards/emulated_board.conf b/tests/drivers/charger/sbs_charger/boards/emulated_board.conf new file mode 100644 index 000000000000000..355bc5d8ed895ac --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/emulated_board.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y +CONFIG_EMUL_SBS_CHARGER=y +CONFIG_I2C_EMUL=y diff --git a/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay b/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay new file mode 100644 index 000000000000000..a4684a78a960a8d --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/emulated_board.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * + * 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"; + smartcharger0: smartcharger@b { + compatible = "sbs,sbs-charger"; + reg = <0x0B>; + status = "okay"; + }; +}; diff --git a/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf new file mode 100644 index 000000000000000..ce6a8cd8df03b47 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.conf @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_EMUL=y +CONFIG_EMUL_SBS_CHARGER=y +CONFIG_I2C=y +CONFIG_I2C_EMUL=y diff --git a/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay new file mode 100644 index 000000000000000..cd29ddf8284b05e --- /dev/null +++ b/tests/drivers/charger/sbs_charger/boards/qemu_cortex_a53.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Cirrus Logic, Inc. + * + * 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>; + /* + * qemu_cortex_a53 SoC requires a 64 bit child addresses (reg properties) + * See its /soc #address-cells & #size-cells properties. + */ + reg = <0x0 0x100 0 4>; + }; +}; + +&fake_i2c_bus { + clock-frequency = ; + compatible = "zephyr,i2c-emul-controller"; + smartcharger0: smartcharger@b { + compatible = "sbs,sbs-charger"; + reg = <0x0B>; + status = "okay"; + }; +}; diff --git a/tests/drivers/charger/sbs_charger/prj.conf b/tests/drivers/charger/sbs_charger/prj.conf new file mode 100644 index 000000000000000..2e2c14646e25280 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_I2C=y +CONFIG_TEST_USERSPACE=y +CONFIG_LOG=y + +CONFIG_CHARGER=y diff --git a/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c b/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c new file mode 100644 index 000000000000000..2a7bfada07cd621 --- /dev/null +++ b/tests/drivers/charger/sbs_charger/src/test_sbs_charger.c @@ -0,0 +1,109 @@ +/* + * Copyright 2023 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sbs_charger_fixture { + const struct device *dev; + const struct charger_driver_api *api; +}; + +static void *sbs_charger_setup(void) +{ + static ZTEST_DMEM struct sbs_charger_fixture fixture; + + fixture.dev = DEVICE_DT_GET_ANY(sbs_sbs_charger); + + k_object_access_all_grant(fixture.dev); + + zassert_true(device_is_ready(fixture.dev), "Charger not found"); + + return &fixture; +} + +ZTEST_USER_F(sbs_charger, test_get_all_props_failed_returns_negative) +{ + struct charger_get_property props[] = { + { + /* Invalid property */ + .property_type = CHARGER_PROP_MAX, + }, + }; + + int ret = charger_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + zassert_equal(props[0].err, -ENOTSUP, "Getting bad property %d has a good status.", + props[0].property_type); + + zassert_true(ret < 0); +} + +ZTEST_USER_F(sbs_charger, test_get_some_props_failed_returns_failed_prop_count) +{ + struct charger_get_property props[] = { + { + /* First invalid property */ + .property_type = CHARGER_PROP_MAX, + }, + { + /* Second invalid property */ + .property_type = CHARGER_PROP_MAX, + }, + { + /* Valid property */ + .property_type = CHARGER_ONLINE, + }, + + }; + + int ret = charger_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + zassert_equal(props[0].err, -ENOTSUP, "Getting bad property %d has a good status.", + props[0].property_type); + + zassert_equal(props[1].err, -ENOTSUP, "Getting bad property %d has a good status.", + props[1].property_type); + + zassert_ok(props[2].err, "Property %d getting %d has a bad status.", 2, + props[2].property_type); + + zassert_equal(ret, 2); +} + +ZTEST_USER_F(sbs_charger, test_get_props__returns_ok) +{ + /* Validate what props are supported by the driver */ + + struct charger_get_property props[] = { + { + .property_type = CHARGER_ONLINE, + }, + { + .property_type = CHARGER_PRESENT, + }, + { + .property_type = CHARGER_STATUS, + }, + }; + + int ret = charger_get_prop(fixture->dev, props, ARRAY_SIZE(props)); + + for (int i = 0; i < ARRAY_SIZE(props); i++) { + zassert_ok(props[i].err, "Property %d getting %d has a bad status.", i, + props[i].property_type); + } + + zassert_ok(ret); +} + +ZTEST_SUITE(sbs_charger, NULL, sbs_charger_setup, NULL, NULL, NULL); diff --git a/tests/drivers/charger/sbs_charger/testcase.yaml b/tests/drivers/charger/sbs_charger/testcase.yaml new file mode 100644 index 000000000000000..1945f162a1323cf --- /dev/null +++ b/tests/drivers/charger/sbs_charger/testcase.yaml @@ -0,0 +1,30 @@ +tests: + # section.subsection + drivers.sbs_charger.emulated: + tags: drivers charger + filter: > + dt_compat_enabled("sbs,sbs-charger") and + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + extra_args: + CONF_FILE="prj.conf;boards/emulated_board.conf" + DTC_OVERLAY_FILE="boards/emulated_board.overlay" + platform_exclude: + qemu_cortex_a53 + qemu_cortex_a53_smp + qemu_kvm_arm64 + xenvm + xenvm_gicv3 + drivers.sbs_charger.emulated_64_bit_i2c_addr: + tags: drivers charger + filter: > + dt_compat_enabled("sbs,sbs-charger") and + (CONFIG_QEMU_TARGET or CONFIG_BOARD_NATIVE_POSIX) + platform_allow: + qemu_cortex_a53 + qemu_cortex_a53_smp + qemu_kvm_arm64 + xenvm + xenvm_gicv3 + extra_args: + CONF_FILE="prj.conf;boards/qemu_cortex_a53.conf" + DTC_OVERLAY_FILE="boards/qemu_cortex_a53.overlay"