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