LCOV - code coverage report
Current view: top level - zephyr/drivers - led.h Coverage Total Hit
Test: new.info Lines: 82.1 % 39 32
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2018 Linaro Limited
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief Public LED driver APIs
      10              :  */
      11              : 
      12              : #ifndef ZEPHYR_INCLUDE_DRIVERS_LED_H_
      13              : #define ZEPHYR_INCLUDE_DRIVERS_LED_H_
      14              : 
      15              : /**
      16              :  * @brief LED Interface
      17              :  * @defgroup led_interface LED Interface
      18              :  * @since 1.12
      19              :  * @version 1.0.0
      20              :  * @ingroup io_interfaces
      21              :  * @{
      22              :  */
      23              : 
      24              : #include <errno.h>
      25              : 
      26              : #include <zephyr/types.h>
      27              : #include <zephyr/device.h>
      28              : 
      29              : #ifdef __cplusplus
      30              : extern "C" {
      31              : #endif
      32              : 
      33              : /**
      34              :  * @brief Maximum brightness level, range is 0 to 100.
      35              :  */
      36            1 : #define LED_BRIGHTNESS_MAX 100u
      37              : 
      38              : /**
      39              :  * @brief LED information structure
      40              :  *
      41              :  * This structure gathers useful information about LED controller.
      42              :  */
      43            1 : struct led_info {
      44              :         /** LED label */
      45            1 :         const char *label;
      46              :         /** Index of the LED on the controller */
      47            1 :         uint32_t index;
      48              :         /** Number of colors per LED */
      49            1 :         uint8_t num_colors;
      50              :         /** Mapping of the LED colors */
      51            1 :         const uint8_t *color_mapping;
      52              : };
      53              : 
      54              : /**
      55              :  * @typedef led_api_blink()
      56              :  * @brief Callback API for blinking an LED
      57              :  *
      58              :  * @see led_blink() for argument descriptions.
      59              :  */
      60            1 : typedef int (*led_api_blink)(const struct device *dev, uint32_t led,
      61              :                              uint32_t delay_on, uint32_t delay_off);
      62              : 
      63              : /**
      64              :  * @typedef led_api_get_info()
      65              :  * @brief Optional API callback to get LED information
      66              :  *
      67              :  * @see led_get_info() for argument descriptions.
      68              :  */
      69            1 : typedef int (*led_api_get_info)(const struct device *dev, uint32_t led,
      70              :                                 const struct led_info **info);
      71              : 
      72              : /**
      73              :  * @typedef led_api_set_brightness()
      74              :  * @brief Callback API for setting brightness of an LED
      75              :  *
      76              :  * @see led_set_brightness() for argument descriptions.
      77              :  */
      78            1 : typedef int (*led_api_set_brightness)(const struct device *dev, uint32_t led,
      79              :                                       uint8_t value);
      80              : /**
      81              :  * @typedef led_api_set_color()
      82              :  * @brief Optional API callback to set the colors of a LED.
      83              :  *
      84              :  * @see led_set_color() for argument descriptions.
      85              :  */
      86            1 : typedef int (*led_api_set_color)(const struct device *dev, uint32_t led,
      87              :                                  uint8_t num_colors, const uint8_t *color);
      88              : 
      89              : /**
      90              :  * @typedef led_api_on()
      91              :  * @brief Callback API for turning on an LED
      92              :  *
      93              :  * @see led_on() for argument descriptions.
      94              :  */
      95            1 : typedef int (*led_api_on)(const struct device *dev, uint32_t led);
      96              : 
      97              : /**
      98              :  * @typedef led_api_off()
      99              :  * @brief Callback API for turning off an LED
     100              :  *
     101              :  * @see led_off() for argument descriptions.
     102              :  */
     103            1 : typedef int (*led_api_off)(const struct device *dev, uint32_t led);
     104              : 
     105              : /**
     106              :  * @typedef led_api_write_channels()
     107              :  * @brief Callback API for writing a strip of LED channels
     108              :  *
     109              :  * @see led_api_write_channels() for arguments descriptions.
     110              :  */
     111            1 : typedef int (*led_api_write_channels)(const struct device *dev,
     112              :                                       uint32_t start_channel,
     113              :                                       uint32_t num_channels,
     114              :                                       const uint8_t *buf);
     115              : 
     116              : /**
     117              :  * @brief LED driver API
     118              :  */
     119            1 : __subsystem struct led_driver_api {
     120              :         /* Mandatory callbacks, either on/off or set_brightness. */
     121            0 :         led_api_on on;
     122            0 :         led_api_off off;
     123            0 :         led_api_set_brightness set_brightness;
     124              :         /* Optional callbacks. */
     125            0 :         led_api_blink blink;
     126            0 :         led_api_get_info get_info;
     127            0 :         led_api_set_color set_color;
     128            0 :         led_api_write_channels write_channels;
     129              : };
     130              : 
     131              : /**
     132              :  * @brief Blink an LED
     133              :  *
     134              :  * This optional routine starts blinking a LED forever with the given time
     135              :  * period.
     136              :  *
     137              :  * @param dev LED device
     138              :  * @param led LED number
     139              :  * @param delay_on Time period (in milliseconds) an LED should be ON
     140              :  * @param delay_off Time period (in milliseconds) an LED should be OFF
     141              :  * @return 0 on success, negative on error
     142              :  */
     143            1 : __syscall int led_blink(const struct device *dev, uint32_t led,
     144              :                             uint32_t delay_on, uint32_t delay_off);
     145              : 
     146              : static inline int z_impl_led_blink(const struct device *dev, uint32_t led,
     147              :                                    uint32_t delay_on, uint32_t delay_off)
     148              : {
     149              :         const struct led_driver_api *api =
     150              :                 (const struct led_driver_api *)dev->api;
     151              : 
     152              :         if (api->blink == NULL) {
     153              :                 return -ENOSYS;
     154              :         }
     155              :         return api->blink(dev, led, delay_on, delay_off);
     156              : }
     157              : 
     158              : /**
     159              :  * @brief Get LED information
     160              :  *
     161              :  * This optional routine provides information about a LED.
     162              :  *
     163              :  * @param dev LED device
     164              :  * @param led LED number
     165              :  * @param info Pointer to a pointer filled with LED information
     166              :  * @return 0 on success, negative on error
     167              :  */
     168            1 : __syscall int led_get_info(const struct device *dev, uint32_t led,
     169              :                            const struct led_info **info);
     170              : 
     171              : static inline int z_impl_led_get_info(const struct device *dev, uint32_t led,
     172              :                                       const struct led_info **info)
     173              : {
     174              :         const struct led_driver_api *api =
     175              :                 (const struct led_driver_api *)dev->api;
     176              : 
     177              :         if (api->get_info == NULL) {
     178              :                 *info = NULL;
     179              :                 return -ENOSYS;
     180              :         }
     181              :         return api->get_info(dev, led, info);
     182              : }
     183              : 
     184              : /**
     185              :  * @brief Set LED brightness
     186              :  *
     187              :  * This optional routine sets the brightness of a LED to the given value.
     188              :  * Calling this function after led_blink() won't affect blinking.
     189              :  *
     190              :  * LEDs which can only be turned on or off do not need to provide this
     191              :  * function.
     192              :  * These should simply turn the LED on if @p value is nonzero, and off
     193              :  * if @p value is zero using the on/off APIs automatically.
     194              :  *
     195              :  * @param dev LED device
     196              :  * @param led LED number
     197              :  * @param value Brightness value to set in percent
     198              :  * @return 0 on success, negative on error
     199              :  */
     200            1 : __syscall int led_set_brightness(const struct device *dev, uint32_t led,
     201              :                                      uint8_t value);
     202              : 
     203              : static inline int z_impl_led_set_brightness(const struct device *dev,
     204              :                                             uint32_t led,
     205              :                                             uint8_t value)
     206              : {
     207              :         const struct led_driver_api *api =
     208              :                 (const struct led_driver_api *)dev->api;
     209              : 
     210              :         if (api->set_brightness == NULL) {
     211              :                 if (api->on == NULL || api->off == NULL) {
     212              :                         return -ENOSYS;
     213              :                 }
     214              :         }
     215              : 
     216              :         if (value > LED_BRIGHTNESS_MAX) {
     217              :                 return -EINVAL;
     218              :         }
     219              : 
     220              :         if (api->set_brightness == NULL) {
     221              :                 if (value) {
     222              :                         return api->on(dev, led);
     223              :                 } else {
     224              :                         return api->off(dev, led);
     225              :                 }
     226              :         }
     227              : 
     228              :         return api->set_brightness(dev, led, value);
     229              : }
     230              : 
     231              : /**
     232              :  * @brief Write/update a strip of LED channels
     233              :  *
     234              :  * This optional routine writes a strip of LED channels to the given array of
     235              :  * levels. Therefore it can be used to configure several LEDs at the same time.
     236              :  *
     237              :  * Calling this function after led_blink() won't affect blinking.
     238              :  *
     239              :  * @param dev LED device
     240              :  * @param start_channel Absolute number (i.e. not relative to a LED) of the
     241              :  *        first channel to update.
     242              :  * @param num_channels The number of channels to write/update.
     243              :  * @param buf array of values to configure the channels with. num_channels
     244              :  *        entries must be provided.
     245              :  * @return 0 on success, negative on error
     246              :  */
     247            1 : __syscall int led_write_channels(const struct device *dev,
     248              :                                  uint32_t start_channel,
     249              :                                  uint32_t num_channels, const uint8_t *buf);
     250              : 
     251              : static inline int
     252              : z_impl_led_write_channels(const struct device *dev, uint32_t start_channel,
     253              :                           uint32_t num_channels, const uint8_t *buf)
     254              : {
     255              :         const struct led_driver_api *api =
     256              :                 (const struct led_driver_api *)dev->api;
     257              : 
     258              :         if (api->write_channels == NULL) {
     259              :                 return -ENOSYS;
     260              :         }
     261              :         return api->write_channels(dev, start_channel, num_channels, buf);
     262              : }
     263              : 
     264              : /**
     265              :  * @brief Set a single LED channel
     266              :  *
     267              :  * This optional routine sets a single LED channel to the given value.
     268              :  *
     269              :  * Calling this function after led_blink() won't affect blinking.
     270              :  *
     271              :  * @param dev LED device
     272              :  * @param channel Absolute channel number (i.e. not relative to a LED)
     273              :  * @param value Value to configure the channel with
     274              :  * @return 0 on success, negative on error
     275              :  */
     276            1 : __syscall int led_set_channel(const struct device *dev,
     277              :                               uint32_t channel, uint8_t value);
     278              : 
     279              : static inline int z_impl_led_set_channel(const struct device *dev,
     280              :                                          uint32_t channel, uint8_t value)
     281              : {
     282              :         return z_impl_led_write_channels(dev, channel, 1, &value);
     283              : }
     284              : 
     285              : /**
     286              :  * @brief Set LED color
     287              :  *
     288              :  * This routine configures all the color channels of a LED with the given
     289              :  * color array.
     290              :  *
     291              :  * Calling this function after led_blink() won't affect blinking.
     292              :  *
     293              :  * @param dev LED device
     294              :  * @param led LED number
     295              :  * @param num_colors Number of colors in the array.
     296              :  * @param color Array of colors. It must be ordered following the color
     297              :  *        mapping of the LED controller. See the color_mapping member
     298              :  *        in struct led_info.
     299              :  * @return 0 on success, negative on error
     300              :  */
     301            1 : __syscall int led_set_color(const struct device *dev, uint32_t led,
     302              :                             uint8_t num_colors, const uint8_t *color);
     303              : 
     304              : static inline int z_impl_led_set_color(const struct device *dev, uint32_t led,
     305              :                                        uint8_t num_colors, const uint8_t *color)
     306              : {
     307              :         const struct led_driver_api *api =
     308              :                 (const struct led_driver_api *)dev->api;
     309              : 
     310              :         if (api->set_color == NULL) {
     311              :                 return -ENOSYS;
     312              :         }
     313              :         return api->set_color(dev, led, num_colors, color);
     314              : }
     315              : 
     316              : /**
     317              :  * @brief Turn on an LED
     318              :  *
     319              :  * This routine turns on an LED
     320              :  *
     321              :  * LEDs which implements brightness control do not need to implement this, the
     322              :  * set_brightness API is used automatically.
     323              :  *
     324              :  * @param dev LED device
     325              :  * @param led LED number
     326              :  * @return 0 on success, negative on error
     327              :  */
     328            1 : __syscall int led_on(const struct device *dev, uint32_t led);
     329              : 
     330              : static inline int z_impl_led_on(const struct device *dev, uint32_t led)
     331              : {
     332              :         const struct led_driver_api *api =
     333              :                 (const struct led_driver_api *)dev->api;
     334              : 
     335              :         if (api->set_brightness == NULL && api->on == NULL) {
     336              :                 return -ENOSYS;
     337              :         }
     338              : 
     339              :         if (api->on == NULL) {
     340              :                 return api->set_brightness(dev, led, LED_BRIGHTNESS_MAX);
     341              :         }
     342              : 
     343              :         return api->on(dev, led);
     344              : }
     345              : 
     346              : /**
     347              :  * @brief Turn off an LED
     348              :  *
     349              :  * This routine turns off an LED
     350              :  *
     351              :  * LEDs which implements brightness control do not need to implement this, the
     352              :  * set_brightness API is used automatically.
     353              :  *
     354              :  * @param dev LED device
     355              :  * @param led LED number
     356              :  * @return 0 on success, negative on error
     357              :  */
     358            1 : __syscall int led_off(const struct device *dev, uint32_t led);
     359              : 
     360              : static inline int z_impl_led_off(const struct device *dev, uint32_t led)
     361              : {
     362              :         const struct led_driver_api *api =
     363              :                 (const struct led_driver_api *)dev->api;
     364              : 
     365              :         if (api->set_brightness == NULL && api->off == NULL) {
     366              :                 return -ENOSYS;
     367              :         }
     368              : 
     369              :         if (api->off == NULL) {
     370              :                 return api->set_brightness(dev, led, 0);
     371              :         }
     372              : 
     373              :         return api->off(dev, led);
     374              : }
     375              : 
     376              : /*
     377              :  * LED DT helpers.
     378              :  */
     379              : 
     380              : /**
     381              :  * @brief Container for an LED information specified in devicetree.
     382              :  *
     383              :  * This type contains a pointer to and LED device and an LED index.
     384              :  *
     385              :  * @see LED_DT_SPEC_GET
     386              :  * @see LED_DT_SPEC_GET_OR
     387              :  */
     388            1 : struct led_dt_spec {
     389              :         /** LED device instance. */
     390            1 :         const struct device *dev;
     391              :         /** Index of the LED on the controller. */
     392            1 :         uint32_t index;
     393              : };
     394              : 
     395              : /**
     396              :  * @brief Set LED brightness from a led_dt_spec.
     397              :  *
     398              :  * @param spec LED device specification from devicetree.
     399              :  * @param value Brightness value to set in percent.
     400              :  * @return 0 on success, negative on error.
     401              :  *
     402              :  * @see led_set_brightness()
     403              :  */
     404            1 : static inline int led_set_brightness_dt(const struct led_dt_spec *spec,
     405              :                                         uint8_t value)
     406              : {
     407              :         return led_set_brightness(spec->dev, spec->index, value);
     408              : }
     409              : 
     410              : /**
     411              :  * @brief Turn on an LED from a struct led_dt_spec.
     412              :  *
     413              :  * @param spec LED device specification from devicetree.
     414              :  * @return 0 on success, negative on error.
     415              :  *
     416              :  * @see led_on()
     417              :  */
     418            1 : static inline int led_on_dt(const struct led_dt_spec *spec)
     419              : {
     420              :         return led_on(spec->dev, spec->index);
     421              : }
     422              : 
     423              : /**
     424              :  * @brief Turn off an LED from a struct led_dt_spec.
     425              :  *
     426              :  * @param spec LED device specification from devicetree.
     427              :  * @return 0 on success, negative on error.
     428              :  *
     429              :  * @see led_off()
     430              :  */
     431            1 : static inline int led_off_dt(const struct led_dt_spec *spec)
     432              : {
     433              :         return led_off(spec->dev, spec->index);
     434              : }
     435              : 
     436              : /**
     437              :  * @brief Validate that the LED device is ready.
     438              :  *
     439              :  * @param spec LED specification from devicetree.
     440              :  *
     441              :  * @retval true If the LED device is ready for use.
     442              :  * @retval false If the LED device is not ready for use.
     443              :  */
     444            1 : static inline bool led_is_ready_dt(const struct led_dt_spec *spec)
     445              : {
     446              :         return device_is_ready(spec->dev);
     447              : }
     448              : 
     449              : /**
     450              :  * @brief Static initializer for a struct led_dt_spec
     451              :  *
     452              :  * This returns a static initializer for a struct led_dt_spec given a devicetree
     453              :  * node identifier.
     454              :  *
     455              :  * Example devicetree fragment:
     456              :  *
     457              :  * @code{.dts}
     458              :  *    leds {
     459              :  *        compatible = "gpio-leds";
     460              :  *        led0: led_0 {
     461              :  *            ...
     462              :  *        };
     463              :  *    };
     464              :  * @endcode
     465              :  *
     466              :  * Example usage:
     467              :  *
     468              :  * @code{.c}
     469              :  *    const struct led_dt_spec spec = LED_DT_SPEC_GET(DT_NODELABEL(led0));
     470              :  *
     471              :  *    // Initializes 'spec' to:
     472              :  *    // {
     473              :  *    //         .dev = DEVICE_DT_GET(DT_PARENT(led0)),
     474              :  *    //         .index = 0,
     475              :  *    // }
     476              :  * @endcode
     477              :  *
     478              :  * The device (dev) must still be checked for readiness, e.g. using
     479              :  * device_is_ready().
     480              :  *
     481              :  * @param node_id Devicetree node identifier.
     482              :  *
     483              :  * @return Static initializer for a struct led_dt_spec for the property.
     484              :  */
     485            1 : #define LED_DT_SPEC_GET(node_id)                                               \
     486              :         {                                                                      \
     487              :                 .dev = DEVICE_DT_GET(DT_PARENT(node_id)),                      \
     488              :                 .index = DT_NODE_CHILD_IDX(node_id),                           \
     489              :         }
     490              : 
     491              : /**
     492              :  * @brief Like LED_DT_SPEC_GET(), with a fallback value if the node does not exist.
     493              :  *
     494              :  * @param node_id Devicetree node identifier.
     495              :  *
     496              :  * @return Static initializer for a struct led_dt_spec for the property.
     497              :  *
     498              :  * @see LED_DT_SPEC_GET
     499              :  */
     500            1 : #define LED_DT_SPEC_GET_OR(node_id, default_value)                             \
     501              :         COND_CODE_1(DT_NODE_EXISTS(node_id),                                   \
     502              :                     (LED_DT_SPEC_GET(node_id)),                                \
     503              :                     (default_value))
     504              : 
     505              : /**
     506              :  * @}
     507              :  */
     508              : 
     509              : #ifdef __cplusplus
     510              : }
     511              : #endif
     512              : 
     513              : #include <zephyr/syscalls/led.h>
     514              : 
     515              : #endif  /* ZEPHYR_INCLUDE_DRIVERS_LED_H_ */
        

Generated by: LCOV version 2.0-1