From c41baf9f7a6800db6c175987ec1fe74391a353a2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 11 Nov 2024 22:51:46 +0000 Subject: [PATCH] led: add a struct led_dt_spec and some _dt wrapper APIs Add a struct led_dt_spec to hold an LED device and index pointer, some initializer and wrapper APIs. This allows simpler LED usage, such as: static const struct led_dt_spec led = LED_DT_SPEC_GET(DT_NODELABEL(led0)); led_on_dt(&led); led_off_dt(&led); Signed-off-by: Fabio Baltieri --- doc/releases/release-notes-4.1.rst | 2 + include/zephyr/drivers/led.h | 129 +++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/doc/releases/release-notes-4.1.rst b/doc/releases/release-notes-4.1.rst index 202fdb20489ba..7d194954c1153 100644 --- a/doc/releases/release-notes-4.1.rst +++ b/doc/releases/release-notes-4.1.rst @@ -112,6 +112,8 @@ Drivers and Sensors * LED + * Added a new set of devicetree based LED APIs, see :c:struct:`led_dt_spec`. + * LED Strip * LoRa diff --git a/include/zephyr/drivers/led.h b/include/zephyr/drivers/led.h index fbb66b5f28517..dc0bd13321040 100644 --- a/include/zephyr/drivers/led.h +++ b/include/zephyr/drivers/led.h @@ -330,6 +330,135 @@ static inline int z_impl_led_off(const struct device *dev, uint32_t led) return api->off(dev, led); } +/* + * LED DT helpers. + */ + +/** + * @brief Container for an LED information specified in devicetree. + * + * This type contains a pointer to and LED device and an LED index. + * + * @see LED_DT_SPEC_GET + * @see LED_DT_SPEC_GET_OR + */ +struct led_dt_spec { + /** LED device instance. */ + const struct device *dev; + /** Index of the LED on the controller. */ + uint32_t index; +}; + +/** + * @brief Set LED brightness from a led_dt_spec. + * + * @param spec LED device specification from devicetree. + * @param value Brightness value to set in percent. + * @return 0 on success, negative on error. + * + * @see led_set_brightness() + */ +static inline int led_set_brightness_dt(const struct led_dt_spec *spec, + uint8_t value) +{ + return led_set_brightness(spec->dev, spec->index, value); +} + +/** + * @brief Turn on an LED from a struct led_dt_spec. + * + * @param spec LED device specification from devicetree. + * @return 0 on success, negative on error. + * + * @see led_on() + */ +static inline int led_on_dt(const struct led_dt_spec *spec) +{ + return led_on(spec->dev, spec->index); +} + +/** + * @brief Turn off an LED from a struct led_dt_spec. + * + * @param spec LED device specification from devicetree. + * @return 0 on success, negative on error. + * + * @see led_off() + */ +static inline int led_off_dt(const struct led_dt_spec *spec) +{ + return led_off(spec->dev, spec->index); +} + +/** + * @brief Validate that the LED device is ready. + * + * @param spec LED specification from devicetree. + * + * @retval true If the LED device is ready for use. + * @retval false If the LED device is not ready for use. + */ +static inline bool led_is_ready_dt(const struct led_dt_spec *spec) +{ + return device_is_ready(spec->dev); +} + +/** + * @brief Static initializer for a struct led_dt_spec + * + * This returns a static initializer for a struct led_dt_spec given a devicetree + * node identifier. + * + * Example devicetree fragment: + * + * @code{.dts} + * leds { + * compatible = "gpio-leds"; + * led0: led_0 { + * ... + * }; + * }; + * @endcode + * + * Example usage: + * + * @code{.c} + * const struct led_dt_spec spec = LED_DT_SPEC_GET(DT_NODELABEL(led0)); + * + * // Initializes 'spec' to: + * // { + * // .dev = DEVICE_DT_GET(DT_PARENT(led0)), + * // .index = 0, + * // } + * @endcode + * + * The device (dev) must still be checked for readiness, e.g. using + * device_is_ready(). + * + * @param node_id Devicetree node identifier. + * + * @return Static initializer for a struct led_dt_spec for the property. + */ +#define LED_DT_SPEC_GET(node_id) \ + { \ + .dev = DEVICE_DT_GET(DT_PARENT(node_id)), \ + .index = DT_NODE_CHILD_IDX(node_id), \ + } + +/** + * @brief Like LED_DT_SPEC_GET(), with a fallback value if the node does not exist. + * + * @param node_id Devicetree node identifier. + * + * @return Static initializer for a struct led_dt_spec for the property. + * + * @see LED_DT_SPEC_GET + */ +#define LED_DT_SPEC_GET_OR(node_id, default_value) \ + COND_CODE_1(DT_NODE_EXISTS(node_id), \ + (LED_DT_SPEC_GET(node_id)), \ + (default_value)) + /** * @} */