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-25 19:22:35

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

Generated by: LCOV version 2.0-1