1 /*
2 * Copyright (c) 2017 Jan Van Winkel <jan.van_winkel@dxplore.eu>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API for display drivers and applications
10 */
11
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_
14
15 /**
16 * @brief Display Interface
17 * @defgroup display_interface Display Interface
18 * @since 1.14
19 * @version 0.8.0
20 * @ingroup io_interfaces
21 * @{
22 */
23
24 #include <zephyr/device.h>
25 #include <errno.h>
26 #include <stddef.h>
27 #include <zephyr/types.h>
28 #include <zephyr/dt-bindings/display/panel.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /**
35 * @brief Display pixel formats
36 *
37 * Display pixel format enumeration.
38 *
39 * In case a pixel format consists out of multiple bytes the byte order is
40 * big endian.
41 */
42 enum display_pixel_format {
43 PIXEL_FORMAT_RGB_888 = BIT(0), /**< 24-bit RGB */
44 PIXEL_FORMAT_MONO01 = BIT(1), /**< Monochrome (0=Black 1=White) */
45 PIXEL_FORMAT_MONO10 = BIT(2), /**< Monochrome (1=Black 0=White) */
46 PIXEL_FORMAT_ARGB_8888 = BIT(3), /**< 32-bit ARGB */
47 PIXEL_FORMAT_RGB_565 = BIT(4), /**< 16-bit RGB */
48 PIXEL_FORMAT_BGR_565 = BIT(5), /**< 16-bit BGR */
49 };
50
51 /**
52 * @brief Bits required per pixel for display format
53 *
54 * This macro expands to the number of bits required for a given display
55 * format. It can be used to allocate a framebuffer based on a given
56 * display format type
57 */
58 #define DISPLAY_BITS_PER_PIXEL(fmt) \
59 ((((fmt & PIXEL_FORMAT_RGB_888) >> 0) * 24U) + \
60 (((fmt & PIXEL_FORMAT_MONO01) >> 1) * 1U) + \
61 (((fmt & PIXEL_FORMAT_MONO10) >> 2) * 1U) + \
62 (((fmt & PIXEL_FORMAT_ARGB_8888) >> 3) * 32U) + \
63 (((fmt & PIXEL_FORMAT_RGB_565) >> 4) * 16U) + \
64 (((fmt & PIXEL_FORMAT_BGR_565) >> 5) * 16U))
65
66 /**
67 * @brief Display screen information
68 */
69 enum display_screen_info {
70 /**
71 * If selected, one octet represents 8 pixels ordered vertically,
72 * otherwise ordered horizontally.
73 */
74 SCREEN_INFO_MONO_VTILED = BIT(0),
75 /**
76 * If selected, the MSB represents the first pixel,
77 * otherwise MSB represents the last pixel.
78 */
79 SCREEN_INFO_MONO_MSB_FIRST = BIT(1),
80 /**
81 * Electrophoretic Display.
82 */
83 SCREEN_INFO_EPD = BIT(2),
84 /**
85 * Screen has two alternating ram buffers
86 */
87 SCREEN_INFO_DOUBLE_BUFFER = BIT(3),
88 /**
89 * Screen has x alignment constrained to width.
90 */
91 SCREEN_INFO_X_ALIGNMENT_WIDTH = BIT(4),
92 };
93
94 /**
95 * @brief Enumeration with possible display orientation
96 */
97 enum display_orientation {
98 DISPLAY_ORIENTATION_NORMAL, /**< No rotation */
99 DISPLAY_ORIENTATION_ROTATED_90, /**< Rotated 90 degrees clockwise */
100 DISPLAY_ORIENTATION_ROTATED_180, /**< Rotated 180 degrees clockwise */
101 DISPLAY_ORIENTATION_ROTATED_270, /**< Rotated 270 degrees clockwise */
102 };
103
104 /** @brief Structure holding display capabilities. */
105 struct display_capabilities {
106 /** Display resolution in the X direction */
107 uint16_t x_resolution;
108 /** Display resolution in the Y direction */
109 uint16_t y_resolution;
110 /** Bitwise or of pixel formats supported by the display */
111 uint32_t supported_pixel_formats;
112 /** Information about display panel */
113 uint32_t screen_info;
114 /** Currently active pixel format for the display */
115 enum display_pixel_format current_pixel_format;
116 /** Current display orientation */
117 enum display_orientation current_orientation;
118 };
119
120 /** @brief Structure to describe display data buffer layout */
121 struct display_buffer_descriptor {
122 /** Data buffer size in bytes */
123 uint32_t buf_size;
124 /** Data buffer row width in pixels */
125 uint16_t width;
126 /** Data buffer column height in pixels */
127 uint16_t height;
128 /** Number of pixels between consecutive rows in the data buffer */
129 uint16_t pitch;
130 /** Indicates that this is not the last write buffer of the frame */
131 bool frame_incomplete;
132 };
133
134 /**
135 * @typedef display_blanking_on_api
136 * @brief Callback API to turn on display blanking
137 * See display_blanking_on() for argument description
138 */
139 typedef int (*display_blanking_on_api)(const struct device *dev);
140
141 /**
142 * @typedef display_blanking_off_api
143 * @brief Callback API to turn off display blanking
144 * See display_blanking_off() for argument description
145 */
146 typedef int (*display_blanking_off_api)(const struct device *dev);
147
148 /**
149 * @typedef display_write_api
150 * @brief Callback API for writing data to the display
151 * See display_write() for argument description
152 */
153 typedef int (*display_write_api)(const struct device *dev, const uint16_t x,
154 const uint16_t y,
155 const struct display_buffer_descriptor *desc,
156 const void *buf);
157
158 /**
159 * @typedef display_read_api
160 * @brief Callback API for reading data from the display
161 * See display_read() for argument description
162 */
163 typedef int (*display_read_api)(const struct device *dev, const uint16_t x,
164 const uint16_t y,
165 const struct display_buffer_descriptor *desc,
166 void *buf);
167
168 /**
169 * @typedef display_get_framebuffer_api
170 * @brief Callback API to get framebuffer pointer
171 * See display_get_framebuffer() for argument description
172 */
173 typedef void *(*display_get_framebuffer_api)(const struct device *dev);
174
175 /**
176 * @typedef display_set_brightness_api
177 * @brief Callback API to set display brightness
178 * See display_set_brightness() for argument description
179 */
180 typedef int (*display_set_brightness_api)(const struct device *dev,
181 const uint8_t brightness);
182
183 /**
184 * @typedef display_set_contrast_api
185 * @brief Callback API to set display contrast
186 * See display_set_contrast() for argument description
187 */
188 typedef int (*display_set_contrast_api)(const struct device *dev,
189 const uint8_t contrast);
190
191 /**
192 * @typedef display_get_capabilities_api
193 * @brief Callback API to get display capabilities
194 * See display_get_capabilities() for argument description
195 */
196 typedef void (*display_get_capabilities_api)(const struct device *dev,
197 struct display_capabilities *
198 capabilities);
199
200 /**
201 * @typedef display_set_pixel_format_api
202 * @brief Callback API to set pixel format used by the display
203 * See display_set_pixel_format() for argument description
204 */
205 typedef int (*display_set_pixel_format_api)(const struct device *dev,
206 const enum display_pixel_format
207 pixel_format);
208
209 /**
210 * @typedef display_set_orientation_api
211 * @brief Callback API to set orientation used by the display
212 * See display_set_orientation() for argument description
213 */
214 typedef int (*display_set_orientation_api)(const struct device *dev,
215 const enum display_orientation
216 orientation);
217
218 /**
219 * @brief Display driver API
220 * API which a display driver should expose
221 */
222 __subsystem struct display_driver_api {
223 display_blanking_on_api blanking_on;
224 display_blanking_off_api blanking_off;
225 display_write_api write;
226 display_read_api read;
227 display_get_framebuffer_api get_framebuffer;
228 display_set_brightness_api set_brightness;
229 display_set_contrast_api set_contrast;
230 display_get_capabilities_api get_capabilities;
231 display_set_pixel_format_api set_pixel_format;
232 display_set_orientation_api set_orientation;
233 };
234
235 /**
236 * @brief Write data to display
237 *
238 * @param dev Pointer to device structure
239 * @param x x Coordinate of the upper left corner where to write the buffer
240 * @param y y Coordinate of the upper left corner where to write the buffer
241 * @param desc Pointer to a structure describing the buffer layout
242 * @param buf Pointer to buffer array
243 *
244 * @retval 0 on success else negative errno code.
245 */
display_write(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,const void * buf)246 static inline int display_write(const struct device *dev, const uint16_t x,
247 const uint16_t y,
248 const struct display_buffer_descriptor *desc,
249 const void *buf)
250 {
251 struct display_driver_api *api =
252 (struct display_driver_api *)dev->api;
253
254 return api->write(dev, x, y, desc, buf);
255 }
256
257 /**
258 * @brief Read data from display
259 *
260 * @param dev Pointer to device structure
261 * @param x x Coordinate of the upper left corner where to read from
262 * @param y y Coordinate of the upper left corner where to read from
263 * @param desc Pointer to a structure describing the buffer layout
264 * @param buf Pointer to buffer array
265 *
266 * @retval 0 on success else negative errno code.
267 * @retval -ENOSYS if not implemented.
268 */
display_read(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,void * buf)269 static inline int display_read(const struct device *dev, const uint16_t x,
270 const uint16_t y,
271 const struct display_buffer_descriptor *desc,
272 void *buf)
273 {
274 struct display_driver_api *api =
275 (struct display_driver_api *)dev->api;
276
277 if (api->read == NULL) {
278 return -ENOSYS;
279 }
280
281 return api->read(dev, x, y, desc, buf);
282 }
283
284 /**
285 * @brief Get pointer to framebuffer for direct access
286 *
287 * @param dev Pointer to device structure
288 *
289 * @retval Pointer to frame buffer or NULL if direct framebuffer access
290 * is not supported
291 *
292 */
display_get_framebuffer(const struct device * dev)293 static inline void *display_get_framebuffer(const struct device *dev)
294 {
295 struct display_driver_api *api =
296 (struct display_driver_api *)dev->api;
297
298 if (api->get_framebuffer == NULL) {
299 return NULL;
300 }
301
302 return api->get_framebuffer(dev);
303 }
304
305 /**
306 * @brief Turn display blanking on
307 *
308 * This function blanks the complete display.
309 * The content of the frame buffer will be retained while blanking is enabled
310 * and the frame buffer will be accessible for read and write operations.
311 *
312 * In case backlight control is supported by the driver the backlight is
313 * turned off. The backlight configuration is retained and accessible for
314 * configuration.
315 *
316 * In case the driver supports display blanking the initial state of the driver
317 * would be the same as if this function was called.
318 *
319 * @param dev Pointer to device structure
320 *
321 * @retval 0 on success else negative errno code.
322 * @retval -ENOSYS if not implemented.
323 */
display_blanking_on(const struct device * dev)324 static inline int display_blanking_on(const struct device *dev)
325 {
326 struct display_driver_api *api =
327 (struct display_driver_api *)dev->api;
328
329 if (api->blanking_on == NULL) {
330 return -ENOSYS;
331 }
332
333 return api->blanking_on(dev);
334 }
335
336 /**
337 * @brief Turn display blanking off
338 *
339 * Restore the frame buffer content to the display.
340 * In case backlight control is supported by the driver the backlight
341 * configuration is restored.
342 *
343 * @param dev Pointer to device structure
344 *
345 * @retval 0 on success else negative errno code.
346 * @retval -ENOSYS if not implemented.
347 */
display_blanking_off(const struct device * dev)348 static inline int display_blanking_off(const struct device *dev)
349 {
350 struct display_driver_api *api =
351 (struct display_driver_api *)dev->api;
352
353 if (api->blanking_off == NULL) {
354 return -ENOSYS;
355 }
356
357 return api->blanking_off(dev);
358 }
359
360 /**
361 * @brief Set the brightness of the display
362 *
363 * Set the brightness of the display in steps of 1/256, where 255 is full
364 * brightness and 0 is minimal.
365 *
366 * @param dev Pointer to device structure
367 * @param brightness Brightness in steps of 1/256
368 *
369 * @retval 0 on success else negative errno code.
370 * @retval -ENOSYS if not implemented.
371 */
display_set_brightness(const struct device * dev,uint8_t brightness)372 static inline int display_set_brightness(const struct device *dev,
373 uint8_t brightness)
374 {
375 struct display_driver_api *api =
376 (struct display_driver_api *)dev->api;
377
378 if (api->set_brightness == NULL) {
379 return -ENOSYS;
380 }
381
382 return api->set_brightness(dev, brightness);
383 }
384
385 /**
386 * @brief Set the contrast of the display
387 *
388 * Set the contrast of the display in steps of 1/256, where 255 is maximum
389 * difference and 0 is minimal.
390 *
391 * @param dev Pointer to device structure
392 * @param contrast Contrast in steps of 1/256
393 *
394 * @retval 0 on success else negative errno code.
395 * @retval -ENOSYS if not implemented.
396 */
display_set_contrast(const struct device * dev,uint8_t contrast)397 static inline int display_set_contrast(const struct device *dev, uint8_t contrast)
398 {
399 struct display_driver_api *api =
400 (struct display_driver_api *)dev->api;
401
402 if (api->set_contrast == NULL) {
403 return -ENOSYS;
404 }
405
406 return api->set_contrast(dev, contrast);
407 }
408
409 /**
410 * @brief Get display capabilities
411 *
412 * @param dev Pointer to device structure
413 * @param capabilities Pointer to capabilities structure to populate
414 */
display_get_capabilities(const struct device * dev,struct display_capabilities * capabilities)415 static inline void display_get_capabilities(const struct device *dev,
416 struct display_capabilities *
417 capabilities)
418 {
419 struct display_driver_api *api =
420 (struct display_driver_api *)dev->api;
421
422 api->get_capabilities(dev, capabilities);
423 }
424
425 /**
426 * @brief Set pixel format used by the display
427 *
428 * @param dev Pointer to device structure
429 * @param pixel_format Pixel format to be used by display
430 *
431 * @retval 0 on success else negative errno code.
432 * @retval -ENOSYS if not implemented.
433 */
434 static inline int
display_set_pixel_format(const struct device * dev,const enum display_pixel_format pixel_format)435 display_set_pixel_format(const struct device *dev,
436 const enum display_pixel_format pixel_format)
437 {
438 struct display_driver_api *api =
439 (struct display_driver_api *)dev->api;
440
441 if (api->set_pixel_format == NULL) {
442 return -ENOSYS;
443 }
444
445 return api->set_pixel_format(dev, pixel_format);
446 }
447
448 /**
449 * @brief Set display orientation
450 *
451 * @param dev Pointer to device structure
452 * @param orientation Orientation to be used by display
453 *
454 * @retval 0 on success else negative errno code.
455 * @retval -ENOSYS if not implemented.
456 */
display_set_orientation(const struct device * dev,const enum display_orientation orientation)457 static inline int display_set_orientation(const struct device *dev,
458 const enum display_orientation
459 orientation)
460 {
461 struct display_driver_api *api =
462 (struct display_driver_api *)dev->api;
463
464 if (api->set_orientation == NULL) {
465 return -ENOSYS;
466 }
467
468 return api->set_orientation(dev, orientation);
469 }
470
471 #ifdef __cplusplus
472 }
473 #endif
474
475 /**
476 * @}
477 */
478
479 #endif /* ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_ */
480