• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "cmsis_os2.h"
16 #include "hdf_log.h"
17 #include "lcd_abs_if.h"
18 #include "hdf_device_desc.h"
19 #include "hal_gpio.h"
20 #include "hal_iomux.h"
21 #include "hal_dsi.h"
22 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
23 #include "hcs_macro.h"
24 #include "hdf_config_macro.h"
25 #else
26 #include "device_resource_if.h"
27 #endif
28 
29 #ifdef CONFIG_DISPLAY_ILI9488
30 #define WIDTH 320
31 #define HEIGHT 480
32 
33 static void PanelPowerControl(bool on);
34 static int32_t PanelCheckStatus(struct PanelData *panel);
35 static int32_t PanelReadId();
36 
37 static uint8_t cmd0[] = {0xE0, 0x00, 0x13, 0x18, 0x04, 0x0F, 0x06, 0x3A, 0x56, 0x4D, 0x03, 0x0A, 0x06, 0x30, 0x3E, 0x0F};
38 static uint8_t cmd1[] = {0xE1, 0x00, 0x13, 0x18, 0x01, 0x11, 0x06, 0x38, 0x34, 0x4D, 0x06, 0x0D, 0x0B, 0x31, 0x37, 0x0F};
39 static uint8_t cmd2[] = {0x35, 0x00};
40 static uint8_t cmd3[] = {0XC0, 0x18, 0x17};       // Power Control 1
41 static uint8_t cmd4[] = {0xC1, 0x41};             // Power Control 2
42 static uint8_t cmd5[] = {0xC5, 0x00, 0x1A, 0x80}; // Power Control 3
43 static uint8_t cmd6[] = {0x36, 0x48};
44 static uint8_t cmd7[] = {0x3A, 0x66}; // Interface Pixel Format //18bit
45 static uint8_t cmd8[] = {0XB0, 0x00};
46 static uint8_t cmd9[] = {0xB1, 0xA0};                    // Frame rate 60HZ
47 static uint8_t cmd10[] = {0xB4, 0x02};                   // Display Inversion Control //2-dot
48 static uint8_t cmd11[] = {0xB6, 0x02, 0x02};             // RGB/MCU Interface Control //MCU //Source,Gate scan dieection
49 static uint8_t cmd12[] = {0xE9, 0x00};                   // Set Image Function,0x00 disable 24 bit data input
50 static uint8_t cmd13[] = {0xF7, 0xA9, 0x51, 0x2C, 0x82}; // Adjust Control
51 static uint8_t cmd14[] = {0x21};                         // Normal Black
52 static uint8_t cmd15[] = {0x11};                         // Sleep out
53 static uint8_t cmd16[] = {0x29};                         // Display on
54 static uint8_t cmd17[] = {0x28};
55 static uint8_t cmd18[] = {0x10};
56 
57 static struct DsiCmdDesc g_OnCmd[] = {
58     {0x39, 0, sizeof(cmd0), cmd0},
59     {0x39, 0, sizeof(cmd1), cmd1},
60     {0x15, 0, sizeof(cmd2), cmd2},
61     {0x39, 0, sizeof(cmd3), cmd3},
62     {0x15, 0, sizeof(cmd4), cmd4},
63     {0x39, 0, sizeof(cmd5), cmd5},
64     {0x15, 0, sizeof(cmd6), cmd6},
65     {0x15, 0, sizeof(cmd7), cmd7},
66     {0x15, 0, sizeof(cmd8), cmd8},
67     {0x15, 0, sizeof(cmd9), cmd9},
68     {0x15, 0, sizeof(cmd10), cmd10},
69     {0x39, 0, sizeof(cmd11), cmd11},
70     {0x15, 0, sizeof(cmd12), cmd12},
71     {0x39, 0, sizeof(cmd13), cmd13},
72     {0x05, 0, sizeof(cmd14), cmd14},
73     {0x05, 150, sizeof(cmd15), cmd15},
74     {0x05, 50, sizeof(cmd16), cmd16},
75 };
76 
77 struct DsiCmdDesc g_offCmd[] = {
78     {0x05, 150, sizeof(cmd17), cmd17},
79     {0x05, 50, sizeof(cmd18), cmd18},
80 };
81 
82 struct PanelDevice {
83     struct PanelData panelData;
84     struct PanelInfo panelInfo;
85     struct PanelEsd panelEsd;
86     DevHandle mipiHandle;
87     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_rst;
88     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_te;
89     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_led;
90 };
91 
92 static struct PanelDevice priv = {
93     .panelInfo = {
94         .width = WIDTH,
95         .height = HEIGHT,
96         .hbp = 15,
97         .hfp = 15,
98         .hsw = 5,
99         .vbp = 8,
100         .vfp = 8,
101         .vsw = 4,
102         .frameRate = 60,
103         .intfType = MIPI_DSI,
104         .intfSync = OUTPUT_USER,
105         .mipi = {DSI_1_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT},
106     },
107     .panelEsd = {
108         .support = true,
109         .interval = 30 * 1000,
110         .recoveryNum = 5,
111         .checkFunc = PanelCheckStatus,
112     },
113     .pin_rst = {
114         HAL_GPIO_PIN_P2_0,
115         HAL_IOMUX_FUNC_AS_GPIO,
116         HAL_IOMUX_PIN_VOLTAGE_VIO,
117         HAL_IOMUX_PIN_NOPULL,
118     },
119     .pin_te = {
120         HAL_IOMUX_PIN_P2_1,
121         HAL_IOMUX_FUNC_DISPLAY_TE,
122         HAL_IOMUX_PIN_VOLTAGE_VIO,
123         HAL_IOMUX_PIN_NOPULL,
124     },
125     .pin_led = {
126         HAL_IOMUX_PIN_P0_3,
127         HAL_IOMUX_FUNC_AS_GPIO,
128         HAL_IOMUX_PIN_VOLTAGE_VIO,
129         HAL_IOMUX_PIN_NOPULL,
130     },
131 };
132 
PanelInit(struct PanelData * panel)133 static int32_t PanelInit(struct PanelData *panel)
134 {
135     if (panel == NULL || panel->info == NULL) {
136         return HDF_FAILURE;
137     }
138     priv.mipiHandle = MipiDsiOpen(0);
139     if (priv.mipiHandle == NULL) {
140         HDF_LOGE("%s: MipiDsiOpen failed", __func__);
141         return HDF_FAILURE;
142     }
143     HDF_LOGI("%s: width %d, height %d", __func__, WIDTH, HEIGHT);
144     PanelPowerControl(true);
145 
146     struct PanelInfo *panelInfo = panel->info;
147     struct MipiCfg cfg = {0};
148     cfg.lane = panelInfo->mipi.lane;
149     cfg.mode = panelInfo->mipi.mode;
150     cfg.format = panelInfo->mipi.format;
151     cfg.burstMode = panelInfo->mipi.burstMode;
152     cfg.timing.xPixels = panelInfo->width;
153     cfg.timing.hsaPixels = panelInfo->hsw;
154     cfg.timing.hbpPixels = panelInfo->hbp;
155     cfg.timing.hlinePixels = panelInfo->width + panelInfo->hbp + panelInfo->hfp + panelInfo->hsw;
156     cfg.timing.vsaLines = panelInfo->vsw;
157     cfg.timing.vbpLines = panelInfo->vbp;
158     cfg.timing.vfpLines = panelInfo->vfp;
159     cfg.timing.ylines = panelInfo->height;
160 
161     cfg.pixelClk = CalcPixelClk(panelInfo);
162     cfg.phyDataRate = CalcDataRate(panelInfo);
163     /* config mipi device */
164     if (MipiDsiSetCfg(priv.mipiHandle, &cfg) != HDF_SUCCESS) {
165         HDF_LOGE("%s: MipiDsiSetCfg failed", __func__);
166         return HDF_FAILURE;
167     }
168     PanelReadId();
169     return HDF_SUCCESS;
170 }
171 
PanelPowerControl(bool on)172 static void PanelPowerControl(bool on)
173 {
174     if (on) {
175         hal_iomux_init(&priv.pin_led, 1);
176         hal_iomux_init(&priv.pin_rst, 1);
177         hal_iomux_init(&priv.pin_te, 1);
178         hal_gpio_pin_set_dir(priv.pin_rst.pin, HAL_GPIO_DIR_OUT, 1);
179         osDelay(10);
180         hal_gpio_pin_clr(priv.pin_rst.pin);
181         osDelay(50);
182         hal_gpio_pin_set(priv.pin_rst.pin);
183         osDelay(150);
184     } else {
185         osDelay(50);
186         hal_gpio_pin_clr(priv.pin_rst.pin);
187         osDelay(150);
188         hal_gpio_pin_clr(priv.pin_led.pin);
189     }
190 }
191 
PanelReadId()192 static int32_t PanelReadId()
193 {
194     uint8_t read_id[3] = {0};
195     uint8_t payload[] = {0x04};
196     struct DsiCmdDesc cmd = {0x06, 0, sizeof(payload), payload};
197     int32_t ret = MipiDsiRx(priv.mipiHandle, &cmd, 3, read_id);
198     if (ret != HDF_SUCCESS) {
199         HDF_LOGE("%s: MipiDsiRx failed", __func__);
200         return HDF_FAILURE;
201     }
202     HDF_LOGI("%s: read id %02X-%02X-%02X", __func__, read_id[0], read_id[1], read_id[2]);
203     return HDF_SUCCESS;
204 }
205 #define DSI_INIT_DELAY 100
PanelCheckStatus(struct PanelData * panel)206 static int32_t PanelCheckStatus(struct PanelData *panel)
207 {
208     uint8_t powerMode = 0;
209     uint8_t payload[] = {0x0A};
210     struct DsiCmdDesc cmd = {0x06, 0, sizeof(payload), payload};
211     int64_t cnt = panel->esd->recoveryNum;
212     do {
213         int32_t ret = MipiDsiRx(priv.mipiHandle, &cmd, 1, &powerMode);
214         if (ret == HDF_SUCCESS) {
215             HDF_LOGD("%s: powerMode 0x%x ok", __func__, powerMode);
216             break;
217         }
218         HDF_LOGE("%s: reset", __func__);
219         hal_dsi_init(WIDTH, priv.panelInfo.mipi.lane);
220         osDelay(DSI_INIT_DELAY);
221         for (int32_t i = 0; i < sizeof(g_OnCmd) / sizeof(g_OnCmd[0]); i++) {
222             ret = MipiDsiTx(priv.mipiHandle, &(g_OnCmd[i]));
223             if (ret != HDF_SUCCESS) {
224                 HDF_LOGE("%s: MipiDsiTx failed", __func__);
225                 return HDF_FAILURE;
226             }
227         }
228     } while (--cnt > 0);
229     if (cnt < panel->esd->recoveryNum) {
230         hal_dsi_start();
231     }
232     return HDF_SUCCESS;
233 }
234 
PanelOn(struct PanelData * panel)235 static int32_t PanelOn(struct PanelData *panel)
236 {
237     /* send mipi power on code */
238     int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]);
239     int32_t i;
240     for (i = 0; i < count; i++) {
241         int32_t ret = MipiDsiTx(priv.mipiHandle, &(g_OnCmd[i]));
242         if (ret != HDF_SUCCESS) {
243             HDF_LOGE("%s: MipiDsiTx failed", __func__);
244             return HDF_FAILURE;
245         }
246     }
247     /* set mipi to hs mode */
248     MipiDsiSetHsMode(priv.mipiHandle);
249     PanelCheckStatus(panel);
250     hal_gpio_pin_set_dir(priv.pin_led.pin, HAL_GPIO_DIR_OUT, 1);
251     osDelay(100);
252     return HDF_SUCCESS;
253 }
254 
PanelOff(struct PanelData * panel)255 static int32_t PanelOff(struct PanelData *panel)
256 {
257     /* send mipi power off code */
258     int32_t count = sizeof(g_offCmd) / sizeof(g_offCmd[0]);
259     int32_t i;
260     for (i = 0; i < count; i++) {
261         int32_t ret = MipiDsiTx(priv.mipiHandle, &(g_offCmd[i]));
262         if (ret != HDF_SUCCESS) {
263             HDF_LOGE("%s: MipiDsiTx failed", __func__);
264             return HDF_FAILURE;
265         }
266     }
267     /* set mipi to lp mode */
268     MipiDsiSetLpMode(priv.mipiHandle);
269     return HDF_SUCCESS;
270 }
271 
PanelSetBacklight(struct PanelData * panel,uint32_t level)272 static int32_t PanelSetBacklight(struct PanelData *panel, uint32_t level)
273 {
274     (void)panel;
275     uint8_t payload[] = {0x51, level & 0xff};
276     struct DsiCmdDesc cmd = {0x15, 0, sizeof(payload), payload};
277     if (MipiDsiTx(priv.mipiHandle, &cmd) != HDF_SUCCESS) {
278         HDF_LOGE("%s: MipiDsiTx failed", __func__);
279         return HDF_FAILURE;
280     }
281     PanelCheckStatus(panel);
282     return HDF_SUCCESS;
283 }
284 #define REAL_PIN(n) (n / 10 * 8 + n % 10)
285 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
286 #define DISPLAY_PANEL_CONFIG HCS_NODE(HCS_NODE(HCS_NODE(HCS_ROOT, display), panel_config), a064_config)
PanelGetResource(struct PanelDevice * priv)287 static uint32_t PanelGetResource(struct PanelDevice *priv)
288 {
289     uint32_t temp;
290     temp = HCS_PROP(DISPLAY_PANEL_CONFIG, rst_pin);
291     priv->pin_rst.pin = REAL_PIN(temp);
292 
293     temp = HCS_PROP(DISPLAY_PANEL_CONFIG, te_pin);
294     priv->pin_te.pin = REAL_PIN(temp);
295 
296     temp = HCS_PROP(DISPLAY_PANEL_CONFIG, led_pin);
297     priv->pin_led.pin = REAL_PIN(temp);
298 
299     HDF_LOGD("%s: rst_pin=%d, te_pin=%d, led_pin=%d", __func__, priv->pin_rst.pin, priv->pin_te.pin, priv->pin_led.pin);
300     return HDF_SUCCESS;
301 }
302 #else
PanelGetResource(struct PanelDevice * priv,const struct DeviceResourceNode * resourceNode)303 static uint32_t PanelGetResource(struct PanelDevice *priv, const struct DeviceResourceNode *resourceNode)
304 {
305     struct DeviceResourceIface *res = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
306     if (res == NULL || res->GetUint32 == NULL) {
307         HDF_LOGE("DeviceResourceIface is invalid");
308         return HDF_FAILURE;
309     }
310     uint32_t temp = 0;
311     if (res->GetUint32(resourceNode, "rst_pin", &temp, 0) != HDF_SUCCESS) {
312         HDF_LOGE("%s: failed to get rst_pin", __func__);
313         return HDF_FAILURE;
314     }
315     priv->pin_rst.pin = REAL_PIN(temp);
316     if (res->GetUint32(resourceNode, "te_pin", &temp, 0) != HDF_SUCCESS) {
317         HDF_LOGE("%s: failed to get te_pin", __func__);
318         return HDF_FAILURE;
319     }
320     priv->pin_te.pin = REAL_PIN(temp);
321     if (res->GetUint32(resourceNode, "led_pin", &temp, 0) != HDF_SUCCESS) {
322         HDF_LOGE("%s: failed to get led_pin", __func__);
323         return HDF_FAILURE;
324     }
325     priv->pin_led.pin = REAL_PIN(temp);
326     HDF_LOGD("%s: rst_pin=%d, te_pin=%d, led_pin=%d", __func__, priv->pin_rst.pin, priv->pin_te.pin, priv->pin_led.pin);
327     return HDF_SUCCESS;
328 }
329 #endif
PanelDriverInit(struct HdfDeviceObject * object)330 static int32_t PanelDriverInit(struct HdfDeviceObject *object)
331 {
332     if (object == NULL) {
333         return HDF_FAILURE;
334     }
335 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
336     if (PanelGetResource(&priv) != HDF_SUCCESS) {
337         HDF_LOGE("%s: PanelGetResource failed", __func__);
338         return HDF_FAILURE;
339     }
340 #else
341     if (object->property) {
342         if (PanelGetResource(&priv, object->property) != HDF_SUCCESS) {
343             HDF_LOGE("%s: PanelGetResource failed", __func__);
344             return HDF_FAILURE;
345         }
346     }
347 #endif
348     priv.panelData.info = &priv.panelInfo;
349     priv.panelData.esd = &priv.panelEsd;
350     priv.panelData.init = PanelInit;
351     priv.panelData.on = PanelOn;
352     priv.panelData.off = PanelOff;
353     priv.panelData.setBacklight = PanelSetBacklight;
354     priv.panelData.object = object;
355     if (RegisterPanel(&priv.panelData) != HDF_SUCCESS) {
356         HDF_LOGE("%s: RegisterPanel failed", __func__);
357         return HDF_FAILURE;
358     }
359     return HDF_SUCCESS;
360 }
361 
PanelDriverBind(struct HdfDeviceObject * device)362 static int32_t PanelDriverBind(struct HdfDeviceObject *device)
363 {
364     (void)device;
365     return HDF_SUCCESS;
366 }
367 
PanelDriverRelease(struct HdfDeviceObject * device)368 static void PanelDriverRelease(struct HdfDeviceObject *device)
369 {
370     (void)device;
371 }
372 
373 static struct HdfDriverEntry g_ili9488DriverEntry = {
374     .moduleVersion = 1,
375     .moduleName = "HDF_PANEL_ILI9488",
376     .Bind = PanelDriverBind,
377     .Init = PanelDriverInit,
378     .Release = PanelDriverRelease,
379 };
380 
381 HDF_INIT(g_ili9488DriverEntry);
382 #endif