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_ */
|