Line data Source code
1 1 : /* 2 : * Copyright (c) 2017 Linaro Limited 3 : * Copyright (c) 2024 Jamie McCrae 4 : * 5 : * SPDX-License-Identifier: Apache-2.0 6 : */ 7 : 8 : /** 9 : * @file 10 : * @brief Public API for controlling linear strips of LEDs. 11 : * 12 : * This library abstracts the chipset drivers for individually 13 : * addressable strips of LEDs. 14 : */ 15 : 16 : #ifndef ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_ 17 : #define ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_ 18 : 19 : /** 20 : * @brief LED Strip Interface 21 : * @defgroup led_strip_interface LED Strip Interface 22 : * @ingroup io_interfaces 23 : * @{ 24 : */ 25 : 26 : #include <errno.h> 27 : #include <zephyr/types.h> 28 : #include <zephyr/device.h> 29 : 30 : #ifdef __cplusplus 31 : extern "C" { 32 : #endif 33 : 34 : /** 35 : * @brief Color value for a single RGB LED. 36 : * 37 : * Individual strip drivers may ignore lower-order bits if their 38 : * resolution in any channel is less than a full byte. 39 : */ 40 1 : struct led_rgb { 41 : #ifdef CONFIG_LED_STRIP_RGB_SCRATCH 42 : /* 43 : * Pad/scratch space needed by some drivers. Users should 44 : * ignore. 45 : */ 46 : uint8_t scratch; 47 : #endif 48 : /** Red channel */ 49 1 : uint8_t r; 50 : /** Green channel */ 51 1 : uint8_t g; 52 : /** Blue channel */ 53 1 : uint8_t b; 54 : }; 55 : 56 : /** 57 : * @typedef led_api_update_rgb 58 : * @brief Callback API for updating an RGB LED strip 59 : * 60 : * @see led_strip_update_rgb() for argument descriptions. 61 : */ 62 1 : typedef int (*led_api_update_rgb)(const struct device *dev, 63 : struct led_rgb *pixels, 64 : size_t num_pixels); 65 : 66 : /** 67 : * @typedef led_api_update_channels 68 : * @brief Callback API for updating channels without an RGB interpretation. 69 : * 70 : * @see led_strip_update_channels() for argument descriptions. 71 : */ 72 1 : typedef int (*led_api_update_channels)(const struct device *dev, 73 : uint8_t *channels, 74 : size_t num_channels); 75 : 76 : /** 77 : * @typedef led_api_length 78 : * @brief Callback API for getting length of an LED strip. 79 : * 80 : * @see led_strip_length() for argument descriptions. 81 : */ 82 1 : typedef size_t (*led_api_length)(const struct device *dev); 83 : 84 : /** 85 : * @brief LED strip driver API 86 : * 87 : * This is the mandatory API any LED strip driver needs to expose. 88 : */ 89 1 : __subsystem struct led_strip_driver_api { 90 0 : led_api_update_rgb update_rgb; 91 0 : led_api_update_channels update_channels; 92 0 : led_api_length length; 93 : }; 94 : 95 : /** 96 : * @brief Mandatory function to update an LED strip with the given RGB array. 97 : * 98 : * @param dev LED strip device. 99 : * @param pixels Array of pixel data. 100 : * @param num_pixels Length of pixels array. 101 : * 102 : * @retval 0 on success. 103 : * @retval -errno negative errno code on failure. 104 : * 105 : * @warning This routine may overwrite @a pixels. 106 : */ 107 1 : static inline int led_strip_update_rgb(const struct device *dev, 108 : struct led_rgb *pixels, 109 : size_t num_pixels) 110 : { 111 : const struct led_strip_driver_api *api = 112 : (const struct led_strip_driver_api *)dev->api; 113 : 114 : /* Allow for out-of-tree drivers that do not have this function for 2 Zephyr releases 115 : * until making it mandatory, function added after Zephyr 3.6 116 : */ 117 : if (api->length != NULL) { 118 : /* Ensure supplied pixel size is valid for this device */ 119 : if (api->length(dev) < num_pixels) { 120 : return -ERANGE; 121 : } 122 : } 123 : 124 : return api->update_rgb(dev, pixels, num_pixels); 125 : } 126 : 127 : /** 128 : * @brief Optional function to update an LED strip with the given channel array 129 : * (each channel byte corresponding to an individually addressable color 130 : * channel or LED. Channels are updated linearly in strip order. 131 : * 132 : * @param dev LED strip device. 133 : * @param channels Array of per-channel data. 134 : * @param num_channels Length of channels array. 135 : * 136 : * @retval 0 on success. 137 : * @retval -ENOSYS if not implemented. 138 : * @retval -errno negative errno code on other failure. 139 : * 140 : * @warning This routine may overwrite @a channels. 141 : */ 142 1 : static inline int led_strip_update_channels(const struct device *dev, 143 : uint8_t *channels, 144 : size_t num_channels) 145 : { 146 : const struct led_strip_driver_api *api = 147 : (const struct led_strip_driver_api *)dev->api; 148 : 149 : if (api->update_channels == NULL) { 150 : return -ENOSYS; 151 : } 152 : 153 : return api->update_channels(dev, channels, num_channels); 154 : } 155 : 156 : /** 157 : * @brief Mandatory function to get chain length (in pixels) of an LED strip device. 158 : * 159 : * @param dev LED strip device. 160 : * 161 : * @retval Length of LED strip device. 162 : */ 163 1 : static inline size_t led_strip_length(const struct device *dev) 164 : { 165 : const struct led_strip_driver_api *api = 166 : (const struct led_strip_driver_api *)dev->api; 167 : 168 : return api->length(dev); 169 : } 170 : 171 : #ifdef __cplusplus 172 : } 173 : #endif 174 : 175 : /** 176 : * @} 177 : */ 178 : 179 : #endif /* ZEPHYR_INCLUDE_DRIVERS_LED_STRIP_H_ */