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