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