/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _DRV_LCD_DEFS_H_ #define _DRV_LCD_DEFS_H_ #include "osi_compiler.h" OSI_EXTERN_C_BEGIN /** * \brief maximum overlay count */ #define DRV_LCD_OVERLAY_COUNT (3) /** * \brief combine 8bits RGB to RGB565 * * [15:11] red * [10:5] green * [4:0] blue */ #define DRV_LCD_RGB565(r, g, b) ((((uint8_t)(b) >> 3) & 0x1f) | (((uint8_t)(g) << 3) & 0x7e0) | (((uint8_t)(r) << 8) & 0xf800)) /** * \brief 8bits R from RGB565 */ #define DRV_LCD_RGB565_R(c) (((uint16_t)(c)&0xf800) >> 8) /** * \brief 8bits G from RGB565 */ #define DRV_LCD_RGB565_G(c) (((uint16_t)(c)&0x7e0) >> 3) /** * \brief 8bits B from RGB565 */ #define DRV_LCD_RGB565_B(c) (((uint16_t)(c)&0x1f) << 3) /** * \brief input buffer color format */ typedef enum { /** RGB565 in little endian, [15:11] R, [10:5] G, [4:0] B */ DRV_LCD_IN_FMT_RGB565, /** ARGB8888 in little endian, [31:24] A, [23:16] R, [15:8] G, [7:0] B */ DRV_LCD_IN_FMT_ARGB8888, /** UYVY pixel-packed format */ DRV_LCD_IN_FMT_UYVY, /** YUYV pixel-packed format */ DRV_LCD_IN_FMT_YUYV, /** IYUV planar format */ DRV_LCD_IN_FMT_IYUV, } drvLcdInputFormat_t; /** * \brief video layer blending depth */ typedef enum { /** at the bottom of all overlays */ DRV_LCD_VIDEO_BLEND_BOTTOM, /** above overlay 0, under overlay 1 */ DRV_LCD_VIDEO_BLEND_ABOVE_0, /** above overlay 1, under overlay 2 */ DRV_LCD_VIDEO_BLEND_ABOVE_1, /** above overlay 2 */ DRV_LCD_VIDEO_BLEND_ABOVE_2, /** at the top of all overlays */ DRV_LCD_VIDEO_BLEND_TOP = DRV_LCD_VIDEO_BLEND_ABOVE_2, } drvLcdVideoBlendDepth_t; /** * \brief LCD panel interface type */ typedef enum { DRV_LCD_INTF_SPI, ///< SPI DRV_LCD_INTF_DSI, ///< MIPI DSI } drvLcdInterface_t; /** * \brief direction transform */ typedef enum { /** normal direction */ DRV_LCD_DIR_NORMAL, /** Y is inverted */ DRV_LCD_DIR_YINV, /** X is inverted */ DRV_LCD_DIR_XINV, /** both Y and X are inverted */ DRV_LCD_DIR_YINV_XINV, /** X-Y are swapped */ DRV_LCD_DIR_EXCHG, /** X-Y are swapped, Y is inverted */ DRV_LCD_DIR_EXCHG_YINV, /** X-Y are swapped, X is inverted */ DRV_LCD_DIR_EXCHG_XINV, /** X-Y are swapped, both X and Y are inverted */ DRV_LCD_DIR_EXCHG_XINV_YINV, /** alias for rotate 0 degree */ DRV_LCD_DIR_ROTATE_0 = DRV_LCD_DIR_NORMAL, /** alias for rotate 90 degree */ DRV_LCD_DIR_ROTATE_90 = DRV_LCD_DIR_EXCHG_XINV, /** alias for rotate 180 degree */ DRV_LCD_DIR_ROTATE_180 = DRV_LCD_DIR_YINV_XINV, /** alias for rotate 270 degree */ DRV_LCD_DIR_ROTATE_270 = DRV_LCD_DIR_EXCHG_YINV, } drvLcdDirection_t; /** * \brief combine two transform direction * * \param first the 1st transform direction * \param second the 2nd transform direction * \return * - the combined transform direction */ static inline drvLcdDirection_t drvLcdDirCombine(drvLcdDirection_t first, drvLcdDirection_t second) { return first ^ second; } /** * \brief whether the transform direction swap X and Y * * For example, rotate 90 and 270 degree will swap X and Y * * \param dir the transform direction * \return * - true if X and Y is swapped */ static inline bool drvLcdDirSwapped(drvLcdDirection_t dir) { return (dir & 4) != 0; } /** * \brief panel information */ typedef struct { /** string name */ const char *name; /** panel ID */ uint32_t dev_id; /** virtual panel width, direction transform considered */ uint16_t width; /** virtual panel height, direction transform considered */ uint16_t height; /** interface type */ drvLcdInterface_t intf; /** whether fmark enabled */ bool fmark_enabled; /** data transfer speed, in pixel per second */ unsigned speed; /** frame duration, in us */ unsigned frame_us; } drvLcdPanelInfo_t; /** * \brief an area * * Area with (w == 0 || h == 0) is nul or invalid area. */ typedef struct { uint16_t x; ///< starting x uint16_t y; ///< starting y uint16_t w; ///< width uint16_t h; ///< height } drvLcdArea_t; /** * \brief helper to check whether area are the same * \param a first area * \param b second area * \return * - true if matches, false otherwise */ static inline bool drvLcdAreaEqual(const drvLcdArea_t *a, const drvLcdArea_t *b) { return (a->x == b->x && a->y == b->y && a->w == b->w && a->h == b->h); } /** * \brief helper to check whether area shape are the same * \param a first area * \param b second area * \return * - true if matches, false otherwise */ static inline bool drvLcdAreaShapeEqual(const drvLcdArea_t *a, const drvLcdArea_t *b) { return a->w == b->w && a->h == b->h; } /** * \brief helper to check whether area is nul * \param a area * \return * - true if either width or height is 0 * - false if not */ static inline bool drvLcdAreaIsNul(const drvLcdArea_t *a) { return (a->w == 0 || a->h == 0); } /** * \brief helper for end X of srea * \param a area * \return * - end X */ static inline uint16_t drvLcdAreaEndX(const drvLcdArea_t *a) { return a->x + a->w - 1; } /** * \brief helper for end Y of srea * \param a area * \return * - end X */ static inline uint16_t drvLcdAreaEndY(const drvLcdArea_t *a) { return a->y + a->h - 1; } /** * \brief video layer description */ typedef struct { /** buffer at top-left */ void *buf; /** U buffer at top-left for IYUV */ void *buf_u; /** V buffer at top-left for IYUV */ void *buf_v; /** whether this layer is enabled */ bool enabled; /** video blending depth */ uint8_t depth; /** input format */ uint8_t in_fmt; /** blending alpha, 0 for transparent */ uint8_t alpha; /** whether to rotate 90 degree clockwise */ bool rotation; /** whether to enable color key */ bool key_en; /** key color mask */ uint8_t key_mask; /** key color in RGB565 */ uint16_t key_color; /** input buffer stride in pixel */ uint16_t stride; /** input buffer width in pixel */ uint16_t buf_width; /** input buffer height in pixel */ uint16_t buf_height; /** layer ROI */ drvLcdArea_t out; } drvLcdVideoLayer_t; /** * \brief overlay definition */ typedef struct { /** buffer at top-left */ void *buf; /** whether this layer is enabled */ bool enabled; /** input format */ uint8_t in_fmt; /** blending alpha, 0 for transparent */ uint8_t alpha; /** whether to enable color key */ bool key_en; /** key color mask */ uint8_t key_mask; /** key color in RGB565 */ uint16_t key_color; /** input buffer stride in pixel */ uint16_t stride; /** layer ROI */ drvLcdArea_t out; } drvLcdOverlay_t; /** * \brief LCD output layers * * The configuration will be used for screen update. */ typedef struct { /** video layer, NULL for not enabled */ drvLcdVideoLayer_t *vl; /** overlay layers, NULL for not enabled */ drvLcdOverlay_t *ovl[DRV_LCD_OVERLAY_COUNT]; /** background color */ uint16_t bg_color; /** blended layers ROI */ drvLcdArea_t layer_roi; /** screen ROI */ drvLcdArea_t screen_roi; } drvLcdLayers_t; /** * \brief panel spi interface type */ typedef enum { DRV_LCD_SPI_4WIRE, DRV_LCD_SPI_3WIRE, DRV_LCD_SPI_4WIRE_START_BYTE, DRV_LCD_SPI_3WIRE_2LANE, } drvLcdSpiLineMode_t; /** * \brief panel data format */ typedef enum { DRV_LCD_OUT_FMT_8BIT_RGB332 = 0, DRV_LCD_OUT_FMT_8BIT_RGB444 = 1, DRV_LCD_OUT_FMT_8BIT_RGB565 = 2, DRV_LCD_OUT_FMT_16BIT_RGB332 = 4, DRV_LCD_OUT_FMT_16BIT_RGB444 = 5, DRV_LCD_OUT_FMT_16BIT_RGB565 = 6, } drvLcdOutputFormat_t; /** * \brief LCD panel operations * * All functions can't be NULL. User won't check NULL pointer before calling * panel operations. Also, caller will take care thread safe. */ typedef struct { /** * \brief probe the panel * \param d LCD instance * \return * - true if the panel matches the driver * - false if not match */ bool (*probe)(void *d); /** * \brief initialization * \param d LCD instance */ void (*init)(void *d); /** * \brief prepare data transfer, set direction and ROI * \param d LCD instance * \param dir direction * \param roi region of interest */ void (*blit_prepare)(void *d, drvLcdDirection_t dir, const drvLcdArea_t *roi); } drvLcdPanelOps_t; /** * \brief panel configuration description */ typedef struct { /** panel operation */ drvLcdPanelOps_t ops; /** name string */ const char *name; /** device ID */ unsigned dev_id; /** reset time in us */ unsigned reset_us; /** delay time after reset in us */ unsigned init_delay_us; /** width in normal direction */ uint16_t width; /** height in normal direction */ uint16_t height; /** output format */ drvLcdOutputFormat_t out_fmt; /** panel initial direction */ drvLcdDirection_t dir; /** SPI line mode */ drvLcdSpiLineMode_t line_mode; /** fmark enabled */ bool fmark_enabled; /** fmark delay */ unsigned fmark_delay; /** SPI frequency */ unsigned freq; /** frmae period in us */ unsigned frame_us; } drvLcdPanelDesc_t; /** * \brief get panel description from LCD instance * * This should be called only in panel driver, and implemented in lcd driver. * * \param d LCD instance * \return * - panel description */ const drvLcdPanelDesc_t *drvLcdGetDesc(void *d); /** * \brief write command to panel * * This should be called only in panel driver, and implemented in lcd driver. * * \param d LCD instance * \param cmd command */ void drvLcdWriteCmd(void *d, uint16_t cmd); /** * \brief write data to panel * * This should be called only in panel driver, and implemented in lcd driver. * * \param d LCD instance * \param data data */ void drvLcdWriteData(void *d, uint16_t data); /** * \brief read data from panel by command * * This should be called only in panel driver, and implemented in lcd driver. * * \param d LCD instance * \param cmd command * \param data data * \param len data length */ void drvLcdReadData(void *d, uint16_t cmd, uint8_t *data, unsigned len); OSI_EXTERN_C_END #endif