diff options
-rw-r--r-- | zephyr/shim/src/led_driver/led.h | 5 | ||||
-rw-r--r-- | zephyr/shim/src/led_driver/led_gpio.c | 19 | ||||
-rw-r--r-- | zephyr/test/drivers/BUILD.py | 9 | ||||
-rw-r--r-- | zephyr/test/drivers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/test/drivers/led_driver/CMakeLists.txt | 20 | ||||
-rw-r--r-- | zephyr/test/drivers/led_driver/led_pins.dts | 54 | ||||
-rw-r--r-- | zephyr/test/drivers/led_driver/led_policy.dts | 215 | ||||
-rw-r--r-- | zephyr/test/drivers/led_driver/prj.conf | 6 | ||||
-rw-r--r-- | zephyr/test/drivers/led_driver/src/led.c | 69 | ||||
-rw-r--r-- | zephyr/test/drivers/overlay.dts | 18 |
10 files changed, 414 insertions, 2 deletions
diff --git a/zephyr/shim/src/led_driver/led.h b/zephyr/shim/src/led_driver/led.h index af2b11fa92..8c4e7654d5 100644 --- a/zephyr/shim/src/led_driver/led.h +++ b/zephyr/shim/src/led_driver/led.h @@ -119,4 +119,9 @@ void led_set_color(enum led_color color, enum ec_led_id led_id); */ void led_set_color_with_node(const struct led_pins_node_t *pins_node); +#ifdef TEST_BUILD +const struct led_pins_node_t *led_get_node(enum led_color color, + enum ec_led_id led_id); +#endif /* TEST_BUILD */ + #endif /* __CROS_EC_LED_H__ */ diff --git a/zephyr/shim/src/led_driver/led_gpio.c b/zephyr/shim/src/led_driver/led_gpio.c index 598839a30f..5a4735a162 100644 --- a/zephyr/shim/src/led_driver/led_gpio.c +++ b/zephyr/shim/src/led_driver/led_gpio.c @@ -128,4 +128,23 @@ __override int led_is_supported(enum ec_led_id led_id) return ((1 << (int)led_id) & supported_leds); } + +#ifdef TEST_BUILD +const struct led_pins_node_t *led_get_node(enum led_color color, + enum ec_led_id led_id) +{ + const struct led_pins_node_t *pin_node = NULL; + + for (int i = 0; i < ARRAY_SIZE(pins_node); i++) { + if (pins_node[i]->led_id == led_id && + pins_node[i]->led_color == color) { + pin_node = pins_node[i]; + break; + } + } + + return pin_node; +} +#endif /* TEST_BUILD */ + #endif /* DT_HAS_COMPAT_STATUS_OKAY(COMPAT_GPIO_LED) */ diff --git a/zephyr/test/drivers/BUILD.py b/zephyr/test/drivers/BUILD.py index 9e3465c18e..c43579da2e 100644 --- a/zephyr/test/drivers/BUILD.py +++ b/zephyr/test/drivers/BUILD.py @@ -6,6 +6,13 @@ register_host_test( "drivers", - dts_overlays=["overlay.dts"], + dts_overlays=[ + "overlay.dts", + here / "led_driver/led_pins.dts", + here / "led_driver/led_policy.dts", + ], + kconfig_files=[ + here / "led_driver/prj.conf", + ], test_args=["-flash={test_temp_dir}/flash.bin"], ) diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt index b4c85defa2..6ba55f51ec 100644 --- a/zephyr/test/drivers/CMakeLists.txt +++ b/zephyr/test/drivers/CMakeLists.txt @@ -74,5 +74,6 @@ target_sources(app PRIVATE ) add_subdirectory(isl923x) +add_subdirectory(led_driver) set_compiler_property(APPEND PROPERTY coverage -O0) diff --git a/zephyr/test/drivers/led_driver/CMakeLists.txt b/zephyr/test/drivers/led_driver/CMakeLists.txt new file mode 100644 index 0000000000..2f96eba2d3 --- /dev/null +++ b/zephyr/test/drivers/led_driver/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright 2022 The ChromiumOS Authors. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Create library name based on current directory +zephyr_library_get_current_dir_lib_name(${ZEPHYR_BASE} lib_name) + +# Create interface library +zephyr_interface_library_named(${lib_name}) + +# Add include paths +zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}") +zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") +zephyr_include_directories("${PLATFORM_EC}/zephyr/shim/src/led_driver") + +# Add source files +zephyr_library_sources("${CMAKE_CURRENT_SOURCE_DIR}/src/led.c") + +# Link in the library +zephyr_library_link_libraries(${lib_name}) diff --git a/zephyr/test/drivers/led_driver/led_pins.dts b/zephyr/test/drivers/led_driver/led_pins.dts new file mode 100644 index 0000000000..0127d762b2 --- /dev/null +++ b/zephyr/test/drivers/led_driver/led_pins.dts @@ -0,0 +1,54 @@ +/* Copyright 2022 The ChromiumOS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + /* Based off of `ec/zephyr/projects/herobrine/led_pins_herobrine.dts` + * Modified led-colors to obtain better test coverage. + */ +/ { + gpio-led-pins { + compatible = "cros-ec,gpio-led-pins"; + + color_off_left: color-off-left { + led-color = "LED_OFF"; + led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; + led-pins = <&gpio_ec_chg_led_y_c1 0>, + <&gpio_ec_chg_led_w_c1 0>; + }; + color_off_right: color-off-right { + led-color = "LED_OFF"; + led-id = "EC_LED_ID_RIGHT_LED"; + led-pins = <&gpio_ec_chg_led_y_c0 0>, + <&gpio_ec_chg_led_w_c0 0>; + }; + color_blue_left: color-blue-left { + led-color = "LED_BLUE"; + led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; + br-color = "EC_LED_COLOR_BLUE"; + led-pins = <&gpio_ec_chg_led_y_c1 1>, + <&gpio_ec_chg_led_w_c1 0>; + }; + color_blue_right: color-blue-right { + led-color = "LED_BLUE"; + led-id = "EC_LED_ID_RIGHT_LED"; + br-color = "EC_LED_COLOR_BLUE"; + led-pins = <&gpio_ec_chg_led_y_c0 1>, + <&gpio_ec_chg_led_w_c0 0>; + }; + color_white_left: color-white-left { + led-color = "LED_WHITE"; + led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; + br-color = "EC_LED_COLOR_WHITE"; + led-pins = <&gpio_ec_chg_led_y_c1 0>, + <&gpio_ec_chg_led_w_c1 1>; + }; + color_white_right: color-white-right { + led-color = "LED_WHITE"; + led-id = "EC_LED_ID_RIGHT_LED"; + br-color = "EC_LED_COLOR_WHITE"; + led-pins = <&gpio_ec_chg_led_y_c0 0>, + <&gpio_ec_chg_led_w_c0 1>; + }; + }; +}; diff --git a/zephyr/test/drivers/led_driver/led_policy.dts b/zephyr/test/drivers/led_driver/led_policy.dts new file mode 100644 index 0000000000..dbbc23062f --- /dev/null +++ b/zephyr/test/drivers/led_driver/led_policy.dts @@ -0,0 +1,215 @@ +/* Copyright 2022 The ChromiumOS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Based off of `ec/zephyr/projects/herobrine/led_policy_herobrine.dts` + * Modified led-colors to obtain better test coverage. + */ + +#include <dt-bindings/battery.h> + +/ { + led-colors { + compatible = "cros-ec,led-colors"; + + power-state-charge-left { + charge-state = "PWR_STATE_CHARGE"; + charge-port = <1>; /* Left port */ + + /* Turn off the right LED */ + color-0 { + led-color = <&color_off_right>; + }; + /* Left LED to Blue */ + color-1 { + led-color = <&color_blue_left>; + }; + }; + + power-state-charge-right { + charge-state = "PWR_STATE_CHARGE"; + charge-port = <0>; /* Right port */ + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED to Blue */ + color-1 { + led-color = <&color_blue_right>; + }; + }; + + power-state-discharge-right-low { + charge-state = "PWR_STATE_DISCHARGE"; + /* Battery percent range (>= Empty, <= Low) */ + batt-lvl = <BATTERY_LEVEL_EMPTY BATTERY_LEVEL_LOW>; + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED - White 1 sec, off 3 sec */ + color-1 { + led-color = <&color_white_right>; + period-ms = <1000>; + }; + color-2 { + led-color = <&color_off_right>; + period-ms = <3000>; + }; + }; + + power-state-discharge-right { + charge-state = "PWR_STATE_DISCHARGE"; + /* Battery percent range (> Low, <= Full) */ + batt-lvl = <(BATTERY_LEVEL_LOW + 1) BATTERY_LEVEL_FULL>; + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Turn off the right LED */ + color-1 { + led-color = <&color_off_right>; + }; + }; + + power-state-error-left { + charge-state = "PWR_STATE_ERROR"; + charge-port = <1>; /* Left port */ + + /* Turn off the right LED */ + color-0 { + led-color = <&color_off_right>; + }; + /* Left LED - White 2 sec, off 2 sec */ + color-1 { + led-color = <&color_white_left>; + period-ms = <2000>; + }; + color-2 { + led-color = <&color_off_right>; + period-ms = <2000>; + }; + }; + + power-state-error-right { + charge-state = "PWR_STATE_ERROR"; + charge-port = <0>; /* Right port */ + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED - White 2 sec, off 2 sec */ + color-1 { + led-color = <&color_white_right>; + period-ms = <2000>; + }; + color-2 { + led-color = <&color_off_right>; + period-ms = <2000>; + }; + }; + + power-state-near-full-left { + charge-state = "PWR_STATE_CHARGE_NEAR_FULL"; + charge-port = <1>; /* Left port */ + + /* Turn off the right LED */ + color-0 { + led-color = <&color_off_right>; + }; + /* Left LED to White */ + color-1 { + led-color = <&color_white_left>; + }; + }; + + power-state-near-full-right { + charge-state = "PWR_STATE_CHARGE_NEAR_FULL"; + charge-port = <0>; /* Right port */ + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED to White */ + color-1 { + led-color = <&color_white_right>; + }; + }; + + power-state-idle-forced-left { + charge-state = "PWR_STATE_IDLE"; + charge-port = <1>; /* Left port */ + extra-flag = "LED_CHFLAG_FORCE_IDLE"; + + /* Turn off the right LED */ + color-0 { + led-color = <&color_off_right>; + }; + /* Left LED - Blue 3 sec, Off 1 sec */ + color-1 { + led-color = <&color_blue_left>; + period-ms = <3000>; + }; + color-2 { + led-color = <&color_off_left>; + period-ms = <1000>; + }; + }; + + power-state-idle-forced-right { + charge-state = "PWR_STATE_IDLE"; + charge-port = <0>; /* Right port */ + extra-flag = "LED_CHFLAG_FORCE_IDLE"; + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED - Blue 3 sec, Off 1 sec */ + color-1 { + led-color = <&color_blue_right>; + period-ms = <3000>; + }; + color-2 { + led-color = <&color_off_right>; + period-ms = <1000>; + }; + }; + + power-state-idle-default-left { + charge-state = "PWR_STATE_IDLE"; + charge-port = <1>; /* Left port */ + extra-flag = "LED_CHFLAG_DEFAULT"; + + /* Turn off the right LED */ + color-0 { + led-color = <&color_off_right>; + }; + /* Left LED to White */ + color-1 { + led-color = <&color_white_left>; + }; + }; + + power-state-idle-default-right { + charge-state = "PWR_STATE_IDLE"; + charge-port = <0>; /* Right port */ + extra-flag = "LED_CHFLAG_DEFAULT"; + + /* Turn off the left LED */ + color-0 { + led-color = <&color_off_left>; + }; + /* Right LED to White */ + color-1 { + led-color = <&color_white_right>; + }; + }; + }; +}; diff --git a/zephyr/test/drivers/led_driver/prj.conf b/zephyr/test/drivers/led_driver/prj.conf new file mode 100644 index 0000000000..abdb8cc6a1 --- /dev/null +++ b/zephyr/test/drivers/led_driver/prj.conf @@ -0,0 +1,6 @@ +# Copyright 2022 The ChromiumOS Authors. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_PLATFORM_EC_LED_COMMON=n +CONFIG_PLATFORM_EC_LED_DT=y diff --git a/zephyr/test/drivers/led_driver/src/led.c b/zephyr/test/drivers/led_driver/src/led.c new file mode 100644 index 0000000000..5c0c9d0c01 --- /dev/null +++ b/zephyr/test/drivers/led_driver/src/led.c @@ -0,0 +1,69 @@ +/* Copyright 2022 The ChromiumOS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <ztest.h> +#include "ec_commands.h" +#include "gpio.h" +#include "led.h" +#include "led_common.h" +#include "test/drivers/test_state.h" + +#define VERIFY_LED_COLOR(color, led_id) \ + { \ + const struct led_pins_node_t *pin_node = \ + led_get_node(color, led_id); \ + for (int j = 0; j < pin_node->pins_count; j++) { \ + int val = gpio_pin_get_dt(gpio_get_dt_spec( \ + pin_node->gpio_pins[j].signal)); \ + int expecting = pin_node->gpio_pins[j].val; \ + zassert_equal(expecting, val, "[%d]: %d != %d", j, \ + expecting, val); \ + } \ + } + +ZTEST_SUITE(led_driver, drivers_predicate_post_main, NULL, NULL, NULL, NULL); + +ZTEST(led_driver, test_led_control) +{ + /* Exercise valid led_id, set to RESET state */ + led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_RESET); + VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED); + + /* Exercise valid led_id, set to OFF state. + * Verify matches OFF color defined in device tree + */ + led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_OFF); + VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED); + + /* Exercise valid led_id, set to ON state. + * Verify matches ON color defined in device tree + */ + led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_ON); + VERIFY_LED_COLOR(LED_BLUE, EC_LED_ID_SYSRQ_DEBUG_LED); + + /* Exercise invalid led_id -- no change to led color */ + led_control(EC_LED_ID_LEFT_LED, LED_STATE_RESET); + VERIFY_LED_COLOR(LED_BLUE, EC_LED_ID_SYSRQ_DEBUG_LED); +} + +ZTEST(led_driver, test_led_brightness) +{ + uint8_t brightness[EC_LED_COLOR_COUNT] = { -1 }; + + /* Verify LED set to OFF */ + led_set_brightness(EC_LED_ID_SYSRQ_DEBUG_LED, brightness); + VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED); + + /* Verify LED colors defined in device tree are reflected in the + * brightness array. + */ + led_get_brightness_range(EC_LED_ID_SYSRQ_DEBUG_LED, brightness); + zassert_equal(brightness[EC_LED_COLOR_BLUE], 1, NULL); + zassert_equal(brightness[EC_LED_COLOR_WHITE], 1, NULL); + + /* Verify LED set to WHITE */ + led_set_brightness(EC_LED_ID_SYSRQ_DEBUG_LED, brightness); + VERIFY_LED_COLOR(LED_WHITE, EC_LED_ID_SYSRQ_DEBUG_LED); +} diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts index df0888175f..d8c92a53ef 100644 --- a/zephyr/test/drivers/overlay.dts +++ b/zephyr/test/drivers/overlay.dts @@ -166,6 +166,22 @@ gpios = <&gpio0 29 (GPIO_ACTIVE_LOW | GPIO_INPUT)>; no-auto-init; }; + gpio_ec_chg_led_y_c0: ec_chg_led_y_c0 { + #led-pin-cells = <1>; + gpios = <&gpio0 30 (GPIO_INPUT | GPIO_OUTPUT_LOW)>; + }; + gpio_ec_chg_led_w_c0: ec_chg_led_w_c0 { + #led-pin-cells = <1>; + gpios = <&gpio0 31 (GPIO_INPUT | GPIO_OUTPUT_LOW)>; + }; + gpio_ec_chg_led_y_c1: ec_chg_led_y_c1 { + #led-pin-cells = <1>; + gpios = <&gpio0 32 (GPIO_INPUT | GPIO_OUTPUT_LOW)>; + }; + gpio_ec_chg_led_w_c1: ec_chg_led_w_c1 { + #led-pin-cells = <1>; + gpios = <&gpio0 33 (GPIO_INPUT | GPIO_OUTPUT_LOW)>; + }; }; gpio-interrupts { @@ -776,7 +792,7 @@ }; &gpio0 { - ngpios = <30>; + ngpios = <34>; }; &i2c0 { |