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