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