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