1 /*
2  * Copyright 2019-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_dc_fb_ssd1963.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 const dc_fb_ops_t g_dcFbOpsSSD1963 = {
14     .init                  = DC_FB_SSD1963_Init,
15     .deinit                = DC_FB_SSD1963_Deinit,
16     .enableLayer           = DC_FB_SSD1963_EnableLayer,
17     .disableLayer          = DC_FB_SSD1963_DisableLayer,
18     .setLayerConfig        = DC_FB_SSD1963_SetLayerConfig,
19     .getLayerDefaultConfig = DC_FB_SSD1963_GetLayerDefaultConfig,
20     .setFrameBuffer        = DC_FB_SSD1963_SetFrameBuffer,
21     .getProperty           = DC_FB_SSD1963_GetProperty,
22     .setCallback           = DC_FB_SSD1963_SetCallback,
23 };
24 
25 /*******************************************************************************
26  * Prototypes
27  ******************************************************************************/
DC_FB_SSD1963_FrameDoneCallback(status_t status,void * userData)28 static void DC_FB_SSD1963_FrameDoneCallback(status_t status, void *userData)
29 {
30     dc_fb_ssd1963_handle_t *dcHandle;
31     dc_fb_ssd1963_layer_t *layer;
32 
33     dcHandle = (dc_fb_ssd1963_handle_t *)userData;
34 
35     /* Currently only support one layer, so the layer index is always 0. */
36     layer = &(dcHandle->layers[0]);
37 
38     /* Frame buffer data has been sent to the panel, the frame buffer is free
39      * to be used for set new data, call the callback to notify upper layer.
40      * The callback is set in application or fbdev.
41      */
42     layer->callback(layer->cbParam, layer->frameBuffer);
43 }
44 
45 /*******************************************************************************
46  * Variables
47  ******************************************************************************/
48 
49 /*******************************************************************************
50  * Code
51  ******************************************************************************/
DC_FB_SSD1963_Init(const dc_fb_t * dc)52 status_t DC_FB_SSD1963_Init(const dc_fb_t *dc)
53 {
54     status_t status;
55 
56     const dc_fb_ssd1963_config_t *dcConfig;
57 
58     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
59 
60     if (0U == dcHandle->initTimes++)
61     {
62         dcConfig = (const dc_fb_ssd1963_config_t *)(dc->config);
63 
64         status = SSD1963_Init(&dcHandle->ssd1963, &dcConfig->ssd1963Config, dcConfig->xferOps, dcConfig->xferOpsData,
65                               dcConfig->srcClock_Hz);
66 
67         if (kStatus_Success != status)
68         {
69             return status;
70         }
71 
72         SSD1963_SetMemoryDoneCallback(&dcHandle->ssd1963, DC_FB_SSD1963_FrameDoneCallback, dcHandle);
73     }
74 
75     return kStatus_Success;
76 }
77 
DC_FB_SSD1963_Deinit(const dc_fb_t * dc)78 status_t DC_FB_SSD1963_Deinit(const dc_fb_t *dc)
79 {
80     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
81 
82     if (dcHandle->initTimes > 0U)
83     {
84         if (--dcHandle->initTimes == 0U)
85         {
86             SSD1963_Deinit(&dcHandle->ssd1963);
87         }
88     }
89 
90     return kStatus_Success;
91 }
92 
DC_FB_SSD1963_EnableLayer(const dc_fb_t * dc,uint8_t layer)93 status_t DC_FB_SSD1963_EnableLayer(const dc_fb_t *dc, uint8_t layer)
94 {
95     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
96     status_t status                  = kStatus_Success;
97 
98     if (0U == dcHandle->enabledLayerCount++)
99     {
100         status = SSD1963_StartDisplay(&dcHandle->ssd1963);
101 
102         if (kStatus_Success == status)
103         {
104             status = SSD1963_SetBackLight(&dcHandle->ssd1963, 255);
105         }
106     }
107 
108     return status;
109 }
110 
DC_FB_SSD1963_DisableLayer(const dc_fb_t * dc,uint8_t layer)111 status_t DC_FB_SSD1963_DisableLayer(const dc_fb_t *dc, uint8_t layer)
112 {
113     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
114     status_t status                  = kStatus_Success;
115 
116     if (dcHandle->enabledLayerCount > 0U)
117     {
118         if (--dcHandle->enabledLayerCount == 0U)
119         {
120             status = SSD1963_SetBackLight(&dcHandle->ssd1963, 0);
121 
122             if (kStatus_Success == status)
123             {
124                 status = SSD1963_StopDisplay(&dcHandle->ssd1963);
125             }
126         }
127     }
128 
129     return status;
130 }
131 
DC_FB_SSD1963_SetLayerConfig(const dc_fb_t * dc,uint8_t layer,dc_fb_info_t * fbInfo)132 status_t DC_FB_SSD1963_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
133 {
134     assert(layer < DC_FB_SSD1963_MAX_LAYER);
135 
136     dc_fb_ssd1963_handle_t *dcHandle = (dc_fb_ssd1963_handle_t *)(dc->prvData);
137 
138     /* The pixel format is already set by SSD1963_Init and could not be changed,
139        so here don't need to set the format.
140        */
141 
142     dcHandle->layers[layer].fbInfo = *fbInfo;
143 
144     return kStatus_Success;
145 }
146 
DC_FB_SSD1963_GetLayerDefaultConfig(const dc_fb_t * dc,uint8_t layer,dc_fb_info_t * fbInfo)147 status_t DC_FB_SSD1963_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
148 {
149     assert(layer < DC_FB_SSD1963_MAX_LAYER);
150 
151     dc_fb_ssd1963_handle_t *dcHandle = (dc_fb_ssd1963_handle_t *)(dc->prvData);
152 
153     fbInfo->startX      = 0;
154     fbInfo->startY      = 0;
155     fbInfo->width       = dcHandle->ssd1963.panelWidth;
156     fbInfo->height      = dcHandle->ssd1963.panelHeight;
157     fbInfo->strideBytes = (uint16_t)(DC_FB_SSD1963_DEFAULT_PIXEL_BYTES * dcHandle->ssd1963.panelWidth);
158     fbInfo->pixelFormat = DC_FB_SSD1963_DEFAULT_PIXEL_FORMAT;
159 
160     return kStatus_Success;
161 }
162 
DC_FB_SSD1963_SetFrameBuffer(const dc_fb_t * dc,uint8_t layer,void * frameBuffer)163 status_t DC_FB_SSD1963_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer)
164 {
165     assert(layer < DC_FB_SSD1963_MAX_LAYER);
166     status_t status;
167 
168     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
169     dc_fb_info_t *fbInfo             = &dcHandle->layers[layer].fbInfo;
170 
171     dcHandle->layers[layer].frameBuffer = frameBuffer;
172     status = SSD1963_SelectArea(&dcHandle->ssd1963, fbInfo->startX, fbInfo->startY, fbInfo->startX + fbInfo->width - 1U,
173                                 fbInfo->startY + fbInfo->height - 1U);
174 
175     if (kStatus_Success != status)
176     {
177         return status;
178     }
179 
180     return SSD1963_WriteMemory(&dcHandle->ssd1963, frameBuffer, (uint32_t)fbInfo->height * fbInfo->strideBytes);
181 }
182 
DC_FB_SSD1963_SetCallback(const dc_fb_t * dc,uint8_t layer,dc_fb_callback_t callback,void * param)183 void DC_FB_SSD1963_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param)
184 {
185     assert(layer < DC_FB_SSD1963_MAX_LAYER);
186     dc_fb_ssd1963_handle_t *dcHandle = dc->prvData;
187 
188     dcHandle->layers[layer].callback = callback;
189     dcHandle->layers[layer].cbParam  = param;
190 }
191 
DC_FB_SSD1963_GetProperty(const dc_fb_t * dc)192 uint32_t DC_FB_SSD1963_GetProperty(const dc_fb_t *dc)
193 {
194     return 0;
195 }
196