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 * @ingroup io_interfaces
19 * @{
20 */
21
22 #include <errno.h>
23
24 #include <zephyr/types.h>
25 #include <zephyr/device.h>
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 /**
32 * @brief LED information structure
33 *
34 * This structure gathers useful information about LED controller.
35 *
36 * @param label LED label.
37 * @param num_colors Number of colors per LED.
38 * @param index Index of the LED on the controller.
39 * @param color_mapping Mapping of the LED colors.
40 */
41 struct led_info {
42 const char *label;
43 uint32_t index;
44 uint8_t num_colors;
45 const uint8_t *color_mapping;
46 };
47
48 /**
49 * @typedef led_api_blink()
50 * @brief Callback API for blinking an LED
51 *
52 * @see led_blink() for argument descriptions.
53 */
54 typedef int (*led_api_blink)(const struct device *dev, uint32_t led,
55 uint32_t delay_on, uint32_t delay_off);
56
57 /**
58 * @typedef led_api_get_info()
59 * @brief Optional API callback to get LED information
60 *
61 * @see led_get_info() for argument descriptions.
62 */
63 typedef int (*led_api_get_info)(const struct device *dev, uint32_t led,
64 const struct led_info **info);
65
66 /**
67 * @typedef led_api_set_brightness()
68 * @brief Callback API for setting brightness of an LED
69 *
70 * @see led_set_brightness() for argument descriptions.
71 */
72 typedef int (*led_api_set_brightness)(const struct device *dev, uint32_t led,
73 uint8_t value);
74 /**
75 * @typedef led_api_set_color()
76 * @brief Optional API callback to set the colors of a LED.
77 *
78 * @see led_set_color() for argument descriptions.
79 */
80 typedef int (*led_api_set_color)(const struct device *dev, uint32_t led,
81 uint8_t num_colors, const uint8_t *color);
82
83 /**
84 * @typedef led_api_on()
85 * @brief Callback API for turning on an LED
86 *
87 * @see led_on() for argument descriptions.
88 */
89 typedef int (*led_api_on)(const struct device *dev, uint32_t led);
90
91 /**
92 * @typedef led_api_off()
93 * @brief Callback API for turning off an LED
94 *
95 * @see led_off() for argument descriptions.
96 */
97 typedef int (*led_api_off)(const struct device *dev, uint32_t led);
98
99 /**
100 * @typedef led_api_write_channels()
101 * @brief Callback API for writing a strip of LED channels
102 *
103 * @see led_api_write_channels() for arguments descriptions.
104 */
105 typedef int (*led_api_write_channels)(const struct device *dev,
106 uint32_t start_channel,
107 uint32_t num_channels,
108 const uint8_t *buf);
109
110 /**
111 * @brief LED driver API
112 */
113 __subsystem struct led_driver_api {
114 /* Mandatory callbacks. */
115 led_api_on on;
116 led_api_off off;
117 /* Optional callbacks. */
118 led_api_blink blink;
119 led_api_get_info get_info;
120 led_api_set_brightness set_brightness;
121 led_api_set_color set_color;
122 led_api_write_channels write_channels;
123 };
124
125 /**
126 * @brief Blink an LED
127 *
128 * This optional routine starts blinking a LED forever with the given time
129 * period.
130 *
131 * @param dev LED device
132 * @param led LED number
133 * @param delay_on Time period (in milliseconds) an LED should be ON
134 * @param delay_off Time period (in milliseconds) an LED should be OFF
135 * @return 0 on success, negative on error
136 */
137 __syscall int led_blink(const struct device *dev, uint32_t led,
138 uint32_t delay_on, uint32_t delay_off);
139
z_impl_led_blink(const struct device * dev,uint32_t led,uint32_t delay_on,uint32_t delay_off)140 static inline int z_impl_led_blink(const struct device *dev, uint32_t led,
141 uint32_t delay_on, uint32_t delay_off)
142 {
143 const struct led_driver_api *api =
144 (const struct led_driver_api *)dev->api;
145
146 if (api->blink == NULL) {
147 return -ENOSYS;
148 }
149 return api->blink(dev, led, delay_on, delay_off);
150 }
151
152 /**
153 * @brief Get LED information
154 *
155 * This optional routine provides information about a LED.
156 *
157 * @param dev LED device
158 * @param led LED number
159 * @param info Pointer to a pointer filled with LED information
160 * @return 0 on success, negative on error
161 */
162 __syscall int led_get_info(const struct device *dev, uint32_t led,
163 const struct led_info **info);
164
z_impl_led_get_info(const struct device * dev,uint32_t led,const struct led_info ** info)165 static inline int z_impl_led_get_info(const struct device *dev, uint32_t led,
166 const struct led_info **info)
167 {
168 const struct led_driver_api *api =
169 (const struct led_driver_api *)dev->api;
170
171 if (api->get_info == NULL) {
172 *info = NULL;
173 return -ENOSYS;
174 }
175 return api->get_info(dev, led, info);
176 }
177
178 /**
179 * @brief Set LED brightness
180 *
181 * This optional routine sets the brightness of a LED to the given value.
182 * Calling this function after led_blink() won't affect blinking.
183 *
184 * LEDs which can only be turned on or off may provide this function.
185 * These should simply turn the LED on if @p value is nonzero, and off
186 * if @p value is zero.
187 *
188 * @param dev LED device
189 * @param led LED number
190 * @param value Brightness value to set in percent
191 * @return 0 on success, negative on error
192 */
193 __syscall int led_set_brightness(const struct device *dev, uint32_t led,
194 uint8_t value);
195
z_impl_led_set_brightness(const struct device * dev,uint32_t led,uint8_t value)196 static inline int z_impl_led_set_brightness(const struct device *dev,
197 uint32_t led,
198 uint8_t value)
199 {
200 const struct led_driver_api *api =
201 (const struct led_driver_api *)dev->api;
202
203 if (api->set_brightness == NULL) {
204 return -ENOSYS;
205 }
206 return api->set_brightness(dev, led, value);
207 }
208
209 /**
210 * @brief Write/update a strip of LED channels
211 *
212 * This optional routine writes a strip of LED channels to the given array of
213 * levels. Therefore it can be used to configure several LEDs at the same time.
214 *
215 * Calling this function after led_blink() won't affect blinking.
216 *
217 * @param dev LED device
218 * @param start_channel Absolute number (i.e. not relative to a LED) of the
219 * first channel to update.
220 * @param num_channels The number of channels to write/update.
221 * @param buf array of values to configure the channels with. num_channels
222 * entries must be provided.
223 * @return 0 on success, negative on error
224 */
225 __syscall int led_write_channels(const struct device *dev,
226 uint32_t start_channel,
227 uint32_t num_channels, const uint8_t *buf);
228
229 static inline int
z_impl_led_write_channels(const struct device * dev,uint32_t start_channel,uint32_t num_channels,const uint8_t * buf)230 z_impl_led_write_channels(const struct device *dev, uint32_t start_channel,
231 uint32_t num_channels, const uint8_t *buf)
232 {
233 const struct led_driver_api *api =
234 (const struct led_driver_api *)dev->api;
235
236 if (api->write_channels == NULL) {
237 return -ENOSYS;
238 }
239 return api->write_channels(dev, start_channel, num_channels, buf);
240 }
241
242 /**
243 * @brief Set a single LED channel
244 *
245 * This optional routine sets a single LED channel to the given value.
246 *
247 * Calling this function after led_blink() won't affect blinking.
248 *
249 * @param dev LED device
250 * @param channel Absolute channel number (i.e. not relative to a LED)
251 * @param value Value to configure the channel with
252 * @return 0 on success, negative on error
253 */
254 __syscall int led_set_channel(const struct device *dev,
255 uint32_t channel, uint8_t value);
256
z_impl_led_set_channel(const struct device * dev,uint32_t channel,uint8_t value)257 static inline int z_impl_led_set_channel(const struct device *dev,
258 uint32_t channel, uint8_t value)
259 {
260 return z_impl_led_write_channels(dev, channel, 1, &value);
261 }
262
263 /**
264 * @brief Set LED color
265 *
266 * This routine configures all the color channels of a LED with the given
267 * color array.
268 *
269 * Calling this function after led_blink() won't affect blinking.
270 *
271 * @param dev LED device
272 * @param led LED number
273 * @param num_colors Number of colors in the array.
274 * @param color Array of colors. It must be ordered following the color
275 * mapping of the LED controller. See the the color_mapping member
276 * in struct led_info.
277 * @return 0 on success, negative on error
278 */
279 __syscall int led_set_color(const struct device *dev, uint32_t led,
280 uint8_t num_colors, const uint8_t *color);
281
z_impl_led_set_color(const struct device * dev,uint32_t led,uint8_t num_colors,const uint8_t * color)282 static inline int z_impl_led_set_color(const struct device *dev, uint32_t led,
283 uint8_t num_colors, const uint8_t *color)
284 {
285 const struct led_driver_api *api =
286 (const struct led_driver_api *)dev->api;
287
288 if (api->set_color == NULL) {
289 return -ENOSYS;
290 }
291 return api->set_color(dev, led, num_colors, color);
292 }
293
294 /**
295 * @brief Turn on an LED
296 *
297 * This routine turns on an LED
298 *
299 * @param dev LED device
300 * @param led LED number
301 * @return 0 on success, negative on error
302 */
303 __syscall int led_on(const struct device *dev, uint32_t led);
304
z_impl_led_on(const struct device * dev,uint32_t led)305 static inline int z_impl_led_on(const struct device *dev, uint32_t led)
306 {
307 const struct led_driver_api *api =
308 (const struct led_driver_api *)dev->api;
309
310 return api->on(dev, led);
311 }
312
313 /**
314 * @brief Turn off an LED
315 *
316 * This routine turns off an LED
317 *
318 * @param dev LED device
319 * @param led LED number
320 * @return 0 on success, negative on error
321 */
322 __syscall int led_off(const struct device *dev, uint32_t led);
323
z_impl_led_off(const struct device * dev,uint32_t led)324 static inline int z_impl_led_off(const struct device *dev, uint32_t led)
325 {
326 const struct led_driver_api *api =
327 (const struct led_driver_api *)dev->api;
328
329 return api->off(dev, led);
330 }
331
332 /**
333 * @}
334 */
335
336 #ifdef __cplusplus
337 }
338 #endif
339
340 #include <syscalls/led.h>
341
342 #endif /* ZEPHYR_INCLUDE_DRIVERS_LED_H_ */
343