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