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 <fabiobaltieri@google.com>
This commit is contained in:
Fabio Baltieri 2024-11-11 22:51:46 +00:00 committed by Anas Nashif
parent 0ea212918f
commit 6342eff58b
2 changed files with 131 additions and 0 deletions

View file

@ -118,6 +118,8 @@ Drivers and Sensors
* LED
* Added a new set of devicetree based LED APIs, see :c:struct:`led_dt_spec`.
* LED Strip
* LoRa

View file

@ -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))
/**
* @}
*/