/* * Copyright (c) 2020 Actions Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Public API for display engine drivers */ #ifndef ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_ENGINE_H_ #define ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_ENGINE_H_ #include #include #include #include #include "display_graphics.h" /** * @brief Display Engine Interface * @defgroup display_engine_interface Display Engine Interface * @ingroup display_interfaces * @{ */ #ifdef __cplusplus extern "C" { #endif /* open flags of display engine */ #define DISPLAY_ENGINE_FLAG_HIGH_PRIO BIT(0) #define DISPLAY_ENGINE_FLAG_POST BIT(1) /* For display post */ /** * @enum display_engine_mode_type * @brief Enumeration with possible display engine modes * */ enum display_engine_mode_type { DISPLAY_ENGINE_MODE_DEFAULT = 0, DISPLAY_ENGINE_MODE_DISPLAY_ONLY, }; /** * @enum display_engine_ctrl_type * @brief Enumeration with possible display engine ctrl command * */ enum display_engine_ctrl_type { DISPLAY_ENGINE_CTRL_DISPLAY_PORT = 0, /* configure display video port */ DISPLAY_ENGINE_CTRL_DISPLAY_MODE, /* configure display video mode */ /* prepare display refreshing. * arg1 is the callback function, arg2 must point to the display device structure */ DISPLAY_ENGINE_CTRL_DISPLAY_PREPARE_CB, /* start display refreshing * arg1 is the callback function, arg2 must point to the display device structure */ DISPLAY_ENGINE_CTRL_DISPLAY_START_CB, /* stop display refreshing during sync mode * arg1 is the timeout in milliseconds */ DISPLAY_ENGINE_CTRL_DISPLAY_SYNC_STOP, /* work mode */ DISPLAY_ENGINE_CTRL_WORK_MODE, }; /** * @struct display_engine_capabilities * @brief Structure holding display engine capabilities * * @var uint8_t display_engine_capabilities::num_overlays * Maximum number of overlays supported * * @var uint16_t display_engine_capabilities::max_width * X Resolution at maximum * * @var uint16_t display_engine_capabilities::max_height * Y Resolution at maximum * * @var uint8_t display_engine_capabilities::support_blend_fg * Blending constant fg color supported * * @var uint8_t display_engine_capabilities::support_blend_b * Blending constant bg color supported * * @var uint32_t display_engine_capabilities::supported_input_pixel_formats * Bitwise or of input pixel formats supported by the display engine * * @var uint32_t display_engine_capabilities::supported_output_pixel_formats * Bitwise or of output pixel formats supported by the display engine * * @var uint32_t display_engine_capabilities::supported_rotate_pixel_formats * Bitwise or of rotation pixel formats supported by the display engine * */ struct display_engine_capabilities { uint16_t max_width; uint16_t max_height; uint16_t max_pitch; uint16_t num_overlays : 3; uint16_t support_fill : 1; uint16_t support_blend : 1; uint16_t support_blend_fg : 1; uint16_t support_blend_bg : 1; uint32_t supported_input_pixel_formats; uint32_t supported_output_pixel_formats; uint32_t supported_rotate_pixel_formats; }; /** * @struct display_engine_rotate_circle * @brief Structure holding display engine rotation configuration * */ typedef struct display_engine_rotate_param { uint32_t is_circle : 1; uint32_t blend_en : 1; /* * the ARGB-8888 color value combined fill color with global alpha, where * 1) RGB channels plus fixed Alpha 0x00 as the fill color * 2) A channel as the global alpha applied to both src image and fill color area */ display_color_t color; /* transform mapping parameters */ display_matrix_t matrix; union { struct { /* line range [line_start, line_start + dest_height) to do rotation */ uint16_t line_start; /* * The ring area is decided by outer_radius_sq and inner_radius_sq, and the pixles * outside the ring will be filled with fill_color if enable. * * The outer_diameter must be equal to the width - 1 of the source image */ uint32_t outer_radius_sq; /* outer circle radius square in .2 fixedpoint format */ uint32_t inner_radius_sq; /* inner circle radius square in .2 fixedpoint format */ } circle; }; } display_engine_transform_param_t; /** * @typedef display_engine_prepare_display_t * @brief Callback API executed when display engine prepare refreshing the display * */ typedef void (*display_engine_prepare_display_t)(void *arg, const display_rect_t *area); /** * @typedef display_engine_start_display_t * @brief Callback API executed when display engine start refreshing the display * */ typedef void (*display_engine_start_display_t)(void *arg); /** * @typedef display_engine_instance_callback_t * @brief Callback API executed when any display engine instance transfer complete or error * */ typedef void (*display_engine_instance_callback_t)(int err_code, uint16_t cmd_seq, void *user_data); /** * @typedef display_engine_control_api * @brief Callback API to control display engine device * See display_engine_control() for argument description */ typedef int (*display_engine_control_api)(const struct device *dev, int cmd, void *arg1, void *arg2); /** * @typedef display_engine_open_api * @brief Callback API to open display engine * See display_engine_open() for argument description */ typedef int (*display_engine_open_api)(const struct device *dev, uint32_t flags); /** * @typedef display_engine_close_api * @brief Callback API to close display engine * See display_engine_close() for argument description */ typedef int (*display_engine_close_api)(const struct device *dev, int inst); /** * @typedef display_engine_get_capabilities_api * @brief Callback API to get display engine capabilities * See display_engine_get_capabilities() for argument description */ typedef void (*display_engine_get_capabilities_api)(const struct device *dev, struct display_engine_capabilities *capabilities); /** * @typedef display_engine_register_callback_api * @brief Callback API to register instance callback * See display_engine_register_callback() for argument description */ typedef int (*display_engine_register_callback_api)(const struct device *dev, int inst, display_engine_instance_callback_t callback, void *user_data); /** * @typedef display_engine_fill_api * @brief Callback API to fill color using display engine * See display_engine_fill() for argument description */ typedef int (*display_engine_fill_api)(const struct device *dev, int inst, const display_buffer_t *dest, display_color_t color); /** * @typedef display_engine_blit_api * @brief Callback API to blit using display engine * See display_engine_blit() for argument description */ typedef int (*display_engine_blit_api)(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *src); /** * @typedef display_engine_blend_api * @brief Callback API to blend using display engine * See display_engine_blend() for argument description */ typedef int (*display_engine_blend_api)(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *fg, display_color_t fg_color, const display_buffer_t *bg, display_color_t bg_color); /** * @typedef display_engine_transform_api * @brief Callback API to transform using display engine * See display_engine_transform() for argument description */ typedef int (*display_engine_transform_api)(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *src, const display_engine_transform_param_t *param); /** * @typedef display_engine_compose_api * @brief Callback API to compose using display engine * See display_engine_compose() for argument description */ typedef int (*display_engine_compose_api)(const struct device *dev, int inst, const display_buffer_t *target, const display_layer_t *layers, int num_ovls); /** * @typedef display_engine_set_clut_api * @brief Callback API to set CLUT * See display_engine_set_clut() for argument description */ typedef int (*display_engine_set_clut_api)(const struct device *dev, int inst, uint16_t layer_idx, uint16_t size, const uint32_t *clut); /** * @typedef display_engine_poll_api * @brief Callback API to poll complete of display engine * See display_engine_poll() for argument description */ typedef int (*display_engine_poll_api)(const struct device *dev, int inst, int timeout_ms); /** * @brief Display Engine driver API * API which a display engine driver should expose */ struct display_engine_driver_api { display_engine_control_api control; display_engine_open_api open; display_engine_close_api close; display_engine_get_capabilities_api get_capabilities; display_engine_register_callback_api register_callback; display_engine_fill_api fill; display_engine_blit_api blit; display_engine_blend_api blend; display_engine_transform_api transform; display_engine_compose_api compose; display_engine_set_clut_api set_clut; display_engine_poll_api poll; }; /** * @brief Control display engine * * @param dev Pointer to device structure * @param cmd Control command * @param arg1 Control command argument 1 * @param arg2 Control command argument 2 * * @retval 0 on success else negative errno code. */ static inline int display_engine_control(const struct device *dev, int cmd, void *arg1, void *arg2) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; if (api->control) { return api->control(dev, cmd, arg1, arg2); } return -ENOTSUP; } /** * @brief Open display engine * * The instance is not thread safe, and must be referred in the same thread. * * @param dev Pointer to device structure * @param flags flags to display engine * * @retval instance id on success else negative errno code. */ static inline int display_engine_open(const struct device *dev, uint32_t flags) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->open(dev, flags); } /** * @brief Close display engine * * The caller must make sure all the commands belong to the inst have completed before close. * * @param dev Pointer to device structure * @param inst instance id return in open() * * @retval 0 on success else negative errno code. */ static inline int display_engine_close(const struct device *dev, int inst) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->close(dev, inst); } /** * @brief Get display engine capabilities * * @param dev Pointer to device structure * @param capabilities Pointer to capabilities structure to populate */ static inline void display_engine_get_capabilities(const struct device *dev, struct display_engine_capabilities *capabilities) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; api->get_capabilities(dev, capabilities); } /** * @brief Register display engine instance callback * * This procedure will only succeed when display engine instance is not busy, and the * registered callback may be called in isr. * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param callback callback function * @param user_data callback parameter "user_data" * * @retval 0 on success else negative errno code. */ static inline int display_engine_register_callback(const struct device *dev, int inst, display_engine_instance_callback_t callback, void *user_data) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->register_callback(dev, inst, callback, user_data); } /** * @brief Fill color * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param dest Pointer to the filling display framebuffer * @param color The filling color * * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_fill(const struct device *dev, int inst, const display_buffer_t *dest, display_color_t color) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->fill(dev, inst, dest, color); } /** * @brief Blit source fb to destination fb * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param dest Pointer to the destination fb * @param src Pointer to the source fb * * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_blit(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *src) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->blit(dev, inst, dest, src); } /** * @brief Blending source fb over destination fb * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param dest Pointer to the destination fb * @param fg Pointer to the foreground fb, can be NULL * @param fg_color Foreground color 1) used as fg plane color, when fg is NULL 2) used as fg pixel rgb color component, when fg format is A8 (A4/1 not allowed) 3) used as fg plane alpha, when fg format is not A8 * @param bg Pointer to the background fb * @param bg Background color 1) used as bg plane color, when fg is NULL 2) used as bg pixel rgb color component, when fg format is A8 (A4/1 not allowed) 3) used as bg plane alpha, when fg format is not A8 * @param plane_alpha plane alpha applied to blending * * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_blend(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *fg, display_color_t fg_color, const display_buffer_t *bg, display_color_t bg_color) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->blend(dev, inst, dest, fg, fg_color, bg, bg_color); } /** * @brief Transform an image to a framebuffer * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param dest Pointer to the destination fb * @param param Pointer to structure display_engine_rotate_param * @param src Pointer to the source fb whose address must be the origin image address before transformation * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_transform(const struct device *dev, int inst, const display_buffer_t *dest, const display_buffer_t *src, const display_engine_transform_param_t *param) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; if (api->transform) { return api->transform(dev, inst, dest, src, param); } return -ENOTSUP; } /** * @brief Composing layers to diplay device or target framebuffer * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param target Target buffer, set NULL if output to display device * @param layers Array of layers * @param num_layers Number of layers * * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_compose(const struct device *dev, int inst, const display_buffer_t *target, const display_layer_t *layers, int num_layers) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->compose(dev, inst, target, layers, num_layers); } /** * @brief Composing layers to diplay device or target framebuffer * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param layer_idx layer index to upload clut * @param size Number of colors in the color look up table * @param clut Pointer to the color look up table * * @retval command sequence (uint16_t) on success else negative errno code. */ static inline int display_engine_set_clut(const struct device *dev, int inst, uint16_t layer_idx, uint16_t size, const uint32_t *clut) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; if (api->set_clut) { return api->set_clut(dev, inst, layer_idx, size, clut); } return -ENOTSUP; } /** * @brief Polling display engine complete * * @param dev Pointer to device structure * @param inst Instance id returned in open() * @param timeout_ms Timeout duration in milliseconds * * @retval 0 on success else negative errno code. */ static inline int display_engine_poll(const struct device *dev, int inst, int timeout_ms) { struct display_engine_driver_api *api = (struct display_engine_driver_api *)dev->api; return api->poll(dev, inst, timeout_ms); } #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_ENGINE_H_ */