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 };
131
132 /**
133 * @typedef display_blanking_on_api
134 * @brief Callback API to turn on display blanking
135 * See display_blanking_on() for argument description
136 */
137 typedef int (*display_blanking_on_api)(const struct device *dev);
138
139 /**
140 * @typedef display_blanking_off_api
141 * @brief Callback API to turn off display blanking
142 * See display_blanking_off() for argument description
143 */
144 typedef int (*display_blanking_off_api)(const struct device *dev);
145
146 /**
147 * @typedef display_write_api
148 * @brief Callback API for writing data to the display
149 * See display_write() for argument description
150 */
151 typedef int (*display_write_api)(const struct device *dev, const uint16_t x,
152 const uint16_t y,
153 const struct display_buffer_descriptor *desc,
154 const void *buf);
155
156 /**
157 * @typedef display_read_api
158 * @brief Callback API for reading data from the display
159 * See display_read() for argument description
160 */
161 typedef int (*display_read_api)(const struct device *dev, const uint16_t x,
162 const uint16_t y,
163 const struct display_buffer_descriptor *desc,
164 void *buf);
165
166 /**
167 * @typedef display_get_framebuffer_api
168 * @brief Callback API to get framebuffer pointer
169 * See display_get_framebuffer() for argument description
170 */
171 typedef void *(*display_get_framebuffer_api)(const struct device *dev);
172
173 /**
174 * @typedef display_set_brightness_api
175 * @brief Callback API to set display brightness
176 * See display_set_brightness() for argument description
177 */
178 typedef int (*display_set_brightness_api)(const struct device *dev,
179 const uint8_t brightness);
180
181 /**
182 * @typedef display_set_contrast_api
183 * @brief Callback API to set display contrast
184 * See display_set_contrast() for argument description
185 */
186 typedef int (*display_set_contrast_api)(const struct device *dev,
187 const uint8_t contrast);
188
189 /**
190 * @typedef display_get_capabilities_api
191 * @brief Callback API to get display capabilities
192 * See display_get_capabilities() for argument description
193 */
194 typedef void (*display_get_capabilities_api)(const struct device *dev,
195 struct display_capabilities *
196 capabilities);
197
198 /**
199 * @typedef display_set_pixel_format_api
200 * @brief Callback API to set pixel format used by the display
201 * See display_set_pixel_format() for argument description
202 */
203 typedef int (*display_set_pixel_format_api)(const struct device *dev,
204 const enum display_pixel_format
205 pixel_format);
206
207 /**
208 * @typedef display_set_orientation_api
209 * @brief Callback API to set orientation used by the display
210 * See display_set_orientation() for argument description
211 */
212 typedef int (*display_set_orientation_api)(const struct device *dev,
213 const enum display_orientation
214 orientation);
215
216 /**
217 * @brief Display driver API
218 * API which a display driver should expose
219 */
220 __subsystem struct display_driver_api {
221 display_blanking_on_api blanking_on;
222 display_blanking_off_api blanking_off;
223 display_write_api write;
224 display_read_api read;
225 display_get_framebuffer_api get_framebuffer;
226 display_set_brightness_api set_brightness;
227 display_set_contrast_api set_contrast;
228 display_get_capabilities_api get_capabilities;
229 display_set_pixel_format_api set_pixel_format;
230 display_set_orientation_api set_orientation;
231 };
232
233 /**
234 * @brief Write data to display
235 *
236 * @param dev Pointer to device structure
237 * @param x x Coordinate of the upper left corner where to write the buffer
238 * @param y y Coordinate of the upper left corner where to write the buffer
239 * @param desc Pointer to a structure describing the buffer layout
240 * @param buf Pointer to buffer array
241 *
242 * @retval 0 on success else negative errno code.
243 */
display_write(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,const void * buf)244 static inline int display_write(const struct device *dev, const uint16_t x,
245 const uint16_t y,
246 const struct display_buffer_descriptor *desc,
247 const void *buf)
248 {
249 struct display_driver_api *api =
250 (struct display_driver_api *)dev->api;
251
252 return api->write(dev, x, y, desc, buf);
253 }
254
255 /**
256 * @brief Read data from display
257 *
258 * @param dev Pointer to device structure
259 * @param x x Coordinate of the upper left corner where to read from
260 * @param y y Coordinate of the upper left corner where to read from
261 * @param desc Pointer to a structure describing the buffer layout
262 * @param buf Pointer to buffer array
263 *
264 * @retval 0 on success else negative errno code.
265 * @retval -ENOSYS if not implemented.
266 */
display_read(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,void * buf)267 static inline int display_read(const struct device *dev, const uint16_t x,
268 const uint16_t y,
269 const struct display_buffer_descriptor *desc,
270 void *buf)
271 {
272 struct display_driver_api *api =
273 (struct display_driver_api *)dev->api;
274
275 if (api->read == NULL) {
276 return -ENOSYS;
277 }
278
279 return api->read(dev, x, y, desc, buf);
280 }
281
282 /**
283 * @brief Get pointer to framebuffer for direct access
284 *
285 * @param dev Pointer to device structure
286 *
287 * @retval Pointer to frame buffer or NULL if direct framebuffer access
288 * is not supported
289 *
290 */
display_get_framebuffer(const struct device * dev)291 static inline void *display_get_framebuffer(const struct device *dev)
292 {
293 struct display_driver_api *api =
294 (struct display_driver_api *)dev->api;
295
296 if (api->get_framebuffer == NULL) {
297 return NULL;
298 }
299
300 return api->get_framebuffer(dev);
301 }
302
303 /**
304 * @brief Turn display blanking on
305 *
306 * This function blanks the complete display.
307 * The content of the frame buffer will be retained while blanking is enabled
308 * and the frame buffer will be accessible for read and write operations.
309 *
310 * In case backlight control is supported by the driver the backlight is
311 * turned off. The backlight configuration is retained and accessible for
312 * configuration.
313 *
314 * In case the driver supports display blanking the initial state of the driver
315 * would be the same as if this function was called.
316 *
317 * @param dev Pointer to device structure
318 *
319 * @retval 0 on success else negative errno code.
320 * @retval -ENOSYS if not implemented.
321 */
display_blanking_on(const struct device * dev)322 static inline int display_blanking_on(const struct device *dev)
323 {
324 struct display_driver_api *api =
325 (struct display_driver_api *)dev->api;
326
327 if (api->blanking_on == NULL) {
328 return -ENOSYS;
329 }
330
331 return api->blanking_on(dev);
332 }
333
334 /**
335 * @brief Turn display blanking off
336 *
337 * Restore the frame buffer content to the display.
338 * In case backlight control is supported by the driver the backlight
339 * configuration is restored.
340 *
341 * @param dev Pointer to device structure
342 *
343 * @retval 0 on success else negative errno code.
344 * @retval -ENOSYS if not implemented.
345 */
display_blanking_off(const struct device * dev)346 static inline int display_blanking_off(const struct device *dev)
347 {
348 struct display_driver_api *api =
349 (struct display_driver_api *)dev->api;
350
351 if (api->blanking_off == NULL) {
352 return -ENOSYS;
353 }
354
355 return api->blanking_off(dev);
356 }
357
358 /**
359 * @brief Set the brightness of the display
360 *
361 * Set the brightness of the display in steps of 1/256, where 255 is full
362 * brightness and 0 is minimal.
363 *
364 * @param dev Pointer to device structure
365 * @param brightness Brightness in steps of 1/256
366 *
367 * @retval 0 on success else negative errno code.
368 * @retval -ENOSYS if not implemented.
369 */
display_set_brightness(const struct device * dev,uint8_t brightness)370 static inline int display_set_brightness(const struct device *dev,
371 uint8_t brightness)
372 {
373 struct display_driver_api *api =
374 (struct display_driver_api *)dev->api;
375
376 if (api->set_brightness == NULL) {
377 return -ENOSYS;
378 }
379
380 return api->set_brightness(dev, brightness);
381 }
382
383 /**
384 * @brief Set the contrast of the display
385 *
386 * Set the contrast of the display in steps of 1/256, where 255 is maximum
387 * difference and 0 is minimal.
388 *
389 * @param dev Pointer to device structure
390 * @param contrast Contrast in steps of 1/256
391 *
392 * @retval 0 on success else negative errno code.
393 * @retval -ENOSYS if not implemented.
394 */
display_set_contrast(const struct device * dev,uint8_t contrast)395 static inline int display_set_contrast(const struct device *dev, uint8_t contrast)
396 {
397 struct display_driver_api *api =
398 (struct display_driver_api *)dev->api;
399
400 if (api->set_contrast == NULL) {
401 return -ENOSYS;
402 }
403
404 return api->set_contrast(dev, contrast);
405 }
406
407 /**
408 * @brief Get display capabilities
409 *
410 * @param dev Pointer to device structure
411 * @param capabilities Pointer to capabilities structure to populate
412 */
display_get_capabilities(const struct device * dev,struct display_capabilities * capabilities)413 static inline void display_get_capabilities(const struct device *dev,
414 struct display_capabilities *
415 capabilities)
416 {
417 struct display_driver_api *api =
418 (struct display_driver_api *)dev->api;
419
420 api->get_capabilities(dev, capabilities);
421 }
422
423 /**
424 * @brief Set pixel format used by the display
425 *
426 * @param dev Pointer to device structure
427 * @param pixel_format Pixel format to be used by display
428 *
429 * @retval 0 on success else negative errno code.
430 * @retval -ENOSYS if not implemented.
431 */
432 static inline int
display_set_pixel_format(const struct device * dev,const enum display_pixel_format pixel_format)433 display_set_pixel_format(const struct device *dev,
434 const enum display_pixel_format pixel_format)
435 {
436 struct display_driver_api *api =
437 (struct display_driver_api *)dev->api;
438
439 if (api->set_pixel_format == NULL) {
440 return -ENOSYS;
441 }
442
443 return api->set_pixel_format(dev, pixel_format);
444 }
445
446 /**
447 * @brief Set display orientation
448 *
449 * @param dev Pointer to device structure
450 * @param orientation Orientation to be used by display
451 *
452 * @retval 0 on success else negative errno code.
453 * @retval -ENOSYS if not implemented.
454 */
display_set_orientation(const struct device * dev,const enum display_orientation orientation)455 static inline int display_set_orientation(const struct device *dev,
456 const enum display_orientation
457 orientation)
458 {
459 struct display_driver_api *api =
460 (struct display_driver_api *)dev->api;
461
462 if (api->set_orientation == NULL) {
463 return -ENOSYS;
464 }
465
466 return api->set_orientation(dev, orientation);
467 }
468
469 #ifdef __cplusplus
470 }
471 #endif
472
473 /**
474 * @}
475 */
476
477 #endif /* ZEPHYR_INCLUDE_DRIVERS_DISPLAY_H_ */
478