• 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 "device_resource_if.h"
20 #include "hal_gpio.h"
21 #include "hal_iomux.h"
22 
23 #ifdef CONFIG_DISPLAY_ICNA3311
24 #define WIDTH 280
25 #define HEIGHT 456
26 
27 static uint8_t g_payLoad0[] = {0xfe, 0x00};
28 static uint8_t g_payLoad1[] = {0x35, 0x00};
29 static uint8_t g_payLoad2[] = {0x36, 0x08};
30 static uint8_t g_payLoad3[] = {0x53, 0x20};
31 static uint8_t g_payLoad4[] = {0x51, 0xff};
32 static uint8_t g_payLoad5[] = {0x63, 0xff};
33 static uint8_t g_payLoad6[] = {0x2a, 0x00, 0x14, 0x01, 0x2B};
34 static uint8_t g_payLoad7[] = {0x2b, 0x00, 0x00, 0x01, 0xC7};
35 static uint8_t g_payLoad8[] = {0x11};
36 static uint8_t g_payLoad9[] = {0x29};
37 static uint8_t g_payLoad10[] = {0x28};
38 static uint8_t g_payLoad11[] = {0x10};
39 
40 static struct DsiCmdDesc g_OnCmd[] = {
41     {0x15, 0, sizeof(g_payLoad0), g_payLoad0},
42     {0x15, 0, sizeof(g_payLoad1), g_payLoad1},
43     {0x15, 0, sizeof(g_payLoad2), g_payLoad2},
44     {0x15, 0, sizeof(g_payLoad3), g_payLoad3},
45     {0x15, 0, sizeof(g_payLoad4), g_payLoad4},
46     {0x15, 0, sizeof(g_payLoad5), g_payLoad5},
47     {0x39, 0, sizeof(g_payLoad6), g_payLoad6},
48     {0x39, 0, sizeof(g_payLoad7), g_payLoad7},
49     {0x05, 120, sizeof(g_payLoad8), g_payLoad8},
50     {0x05, 120, sizeof(g_payLoad9), g_payLoad9},
51 };
52 
53 static struct DsiCmdDesc g_offCmd[] = {
54     {0x15, 0, sizeof(g_payLoad0), g_payLoad0},
55     {0x05, 20, sizeof(g_payLoad10), g_payLoad10},
56     {0x05, 120, sizeof(g_payLoad11), g_payLoad11},
57 };
58 
59 struct PanelDevice {
60     struct PanelData panelData;
61     struct PanelInfo panelInfo;
62     DevHandle mipiHandle;
63     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_rst;
64     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_te;
65     struct HAL_IOMUX_PIN_FUNCTION_MAP pin_vci;
66 };
67 
68 static struct PanelDevice priv = {
69     .panelInfo = {
70         .width = WIDTH,
71         .height = HEIGHT,
72         .hbp = 8,
73         .hfp = 8,
74         .hsw = 2,
75         .vbp = 8,
76         .vfp = 8,
77         .vsw = 2,
78         .frameRate = 60,
79         .intfType = MIPI_DSI,
80         .intfSync = OUTPUT_USER,
81         .mipi = {DSI_1_LANES, DSI_CMD_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT},
82     },
83     .pin_rst = {
84         HAL_GPIO_PIN_P0_3,
85         HAL_IOMUX_FUNC_AS_GPIO,
86         HAL_IOMUX_PIN_VOLTAGE_VIO,
87         HAL_IOMUX_PIN_NOPULL,
88     },
89     .pin_te = {
90         HAL_IOMUX_PIN_P2_1,
91         HAL_IOMUX_FUNC_DISPLAY_TE,
92         HAL_IOMUX_PIN_VOLTAGE_VIO,
93         HAL_IOMUX_PIN_NOPULL,
94     },
95     .pin_vci = {
96         HAL_IOMUX_PIN_P0_2,
97         HAL_IOMUX_FUNC_AS_GPIO,
98         HAL_IOMUX_PIN_VOLTAGE_VIO,
99         HAL_IOMUX_PIN_NOPULL,
100     },
101 };
102 
PanelInit(struct PanelData * panel)103 static int32_t PanelInit(struct PanelData *panel)
104 {
105     if (panel == NULL || panel->info == NULL) {
106         return HDF_FAILURE;
107     }
108     priv.mipiHandle = MipiDsiOpen(0);
109     if (priv.mipiHandle == NULL) {
110         HDF_LOGE("%s: MipiDsiOpen failed", __func__);
111         return HDF_FAILURE;
112     }
113     HDF_LOGI("%s: width %d, height %d", __func__, WIDTH, HEIGHT);
114 
115     struct PanelInfo *panelInfo = panel->info;
116     struct MipiCfg cfg = {0};
117     cfg.lane = panelInfo->mipi.lane;
118     cfg.mode = panelInfo->mipi.mode;
119     cfg.format = panelInfo->mipi.format;
120     cfg.burstMode = panelInfo->mipi.burstMode;
121     cfg.timing.xPixels = panelInfo->width;
122     cfg.timing.hsaPixels = panelInfo->hsw;
123     cfg.timing.hbpPixels = panelInfo->hbp;
124     cfg.timing.hlinePixels = panelInfo->width + panelInfo->hbp + panelInfo->hfp + panelInfo->hsw;
125     cfg.timing.vsaLines = panelInfo->vsw;
126     cfg.timing.vbpLines = panelInfo->vbp;
127     cfg.timing.vfpLines = panelInfo->vfp;
128     cfg.timing.ylines = panelInfo->height;
129 
130     cfg.pixelClk = CalcPixelClk(panelInfo);
131     cfg.phyDataRate = CalcDataRate(panelInfo);
132     /* config mipi device */
133     if (MipiDsiSetCfg(priv.mipiHandle, &cfg) != HDF_SUCCESS) {
134         HDF_LOGE("%s: MipiDsiSetCfg failed", __func__);
135         return HDF_FAILURE;
136     }
137     return HDF_SUCCESS;
138 }
139 
PanelPowerControl(bool on)140 static void PanelPowerControl(bool on)
141 {
142     if (on) {
143         hal_iomux_init(&priv.pin_vci, 1);
144         hal_iomux_init(&priv.pin_rst, 1);
145         hal_iomux_init(&priv.pin_te, 1);
146         hal_gpio_pin_set_dir(priv.pin_rst.pin, HAL_GPIO_DIR_OUT, 0);
147         hal_gpio_pin_set_dir(priv.pin_vci.pin, HAL_GPIO_DIR_OUT, 0);
148         hal_gpio_pin_set(priv.pin_vci.pin);
149         osDelay(20);
150         hal_gpio_pin_set(priv.pin_rst.pin);
151         osDelay(20);
152     } else {
153         osDelay(120);
154         hal_gpio_pin_clr(priv.pin_rst.pin);
155         osDelay(20);
156         hal_gpio_pin_clr(priv.pin_vci.pin);
157     }
158 }
159 
PanelOn(struct PanelData * panel)160 static int32_t PanelOn(struct PanelData *panel)
161 {
162     (void)panel;
163     PanelPowerControl(true);
164     /* send mipi power on code */
165     int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]);
166     int32_t i;
167     for (i = 0; i < count; i++) {
168         int32_t ret = MipiDsiTx(priv.mipiHandle, &(g_OnCmd[i]));
169         if (ret != HDF_SUCCESS) {
170             HDF_LOGE("%s: MipiDsiTx failed", __func__);
171             return HDF_FAILURE;
172         }
173     }
174     /* set mipi to hs mode */
175     MipiDsiSetHsMode(priv.mipiHandle);
176     return HDF_SUCCESS;
177 }
178 
PanelOff(struct PanelData * panel)179 static int32_t PanelOff(struct PanelData *panel)
180 {
181     (void)panel;
182     /* send mipi power off code */
183     int32_t count = sizeof(g_offCmd) / sizeof(g_offCmd[0]);
184     int32_t i;
185     for (i = 0; i < count; i++) {
186         int32_t ret = MipiDsiTx(priv.mipiHandle, &(g_offCmd[i]));
187         if (ret != HDF_SUCCESS) {
188             HDF_LOGE("%s: MipiDsiTx failed", __func__);
189             return HDF_FAILURE;
190         }
191     }
192     /* set mipi to lp mode */
193     MipiDsiSetLpMode(priv.mipiHandle);
194     PanelPowerControl(false);
195     return HDF_SUCCESS;
196 }
197 
PanelSetBacklight(struct PanelData * panel,uint32_t level)198 static int32_t PanelSetBacklight(struct PanelData *panel, uint32_t level)
199 {
200     (void)panel;
201     uint8_t payload[] = {0x51, level & 0xff};
202     struct DsiCmdDesc cmd = {0x15, 0, sizeof(payload), payload};
203     if (MipiDsiTx(priv.mipiHandle, &cmd) != HDF_SUCCESS) {
204         HDF_LOGE("%s: MipiDsiTx failed", __func__);
205         return HDF_FAILURE;
206     }
207     return HDF_SUCCESS;
208 }
209 
210 #define REAL_PIN(n) (n / 10 * 8 + n % 10)
PanelGetResource(struct PanelDevice * priv,const struct DeviceResourceNode * resourceNode)211 static uint32_t PanelGetResource(struct PanelDevice *priv, const struct DeviceResourceNode *resourceNode)
212 {
213     struct DeviceResourceIface *res = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
214     if (res == NULL || res->GetUint32 == NULL) {
215         HDF_LOGE("DeviceResourceIface is invalid");
216         return HDF_FAILURE;
217     }
218     uint32_t temp = 0;
219     if (res->GetUint32(resourceNode, "rst_pin", &temp, 0) != HDF_SUCCESS) {
220         HDF_LOGE("%s: failed to get rst_pin", __func__);
221         return HDF_FAILURE;
222     }
223     priv->pin_rst.pin = REAL_PIN(temp);
224     if (res->GetUint32(resourceNode, "te_pin", &temp, 0) != HDF_SUCCESS) {
225         HDF_LOGE("%s: failed to get te_pin", __func__);
226         return HDF_FAILURE;
227     }
228     priv->pin_te.pin = REAL_PIN(temp);
229     if (res->GetUint32(resourceNode, "vci_pin", &temp, 0) != HDF_SUCCESS) {
230         HDF_LOGE("%s: failed to get vci_pin", __func__);
231         return HDF_FAILURE;
232     }
233     priv->pin_vci.pin = REAL_PIN(temp);
234     HDF_LOGD("%s: rst_pin=%d, te_pin=%d, vci_pin=%d", __func__, priv->pin_rst.pin, priv->pin_te.pin, priv->pin_vci.pin);
235     return HDF_SUCCESS;
236 }
237 
PanelDriverInit(struct HdfDeviceObject * object)238 static int32_t PanelDriverInit(struct HdfDeviceObject *object)
239 {
240     if (object == NULL) {
241         return HDF_FAILURE;
242     }
243     if (object->property) {
244         if (PanelGetResource(&priv, object->property) != HDF_SUCCESS) {
245             HDF_LOGE("%s: PanelGetResource failed", __func__);
246             return HDF_FAILURE;
247         }
248     }
249     priv.panelData.info = &priv.panelInfo;
250     priv.panelData.init = PanelInit;
251     priv.panelData.on = PanelOn;
252     priv.panelData.off = PanelOff;
253     priv.panelData.setBacklight = PanelSetBacklight;
254     priv.panelData.object = object;
255     if (RegisterPanel(&priv.panelData) != HDF_SUCCESS) {
256         HDF_LOGE("%s: RegisterPanel failed", __func__);
257         return HDF_FAILURE;
258     }
259     return HDF_SUCCESS;
260 }
261 
PanelDriverBind(struct HdfDeviceObject * device)262 static int32_t PanelDriverBind(struct HdfDeviceObject *device)
263 {
264     (void)device;
265     return HDF_SUCCESS;
266 }
267 
PanelDriverRelease(struct HdfDeviceObject * device)268 static void PanelDriverRelease(struct HdfDeviceObject *device)
269 {
270     (void)device;
271 }
272 
273 static struct HdfDriverEntry g_ICNA3311DriverEntry = {
274     .moduleVersion = 1,
275     .moduleName = "HDF_PANEL_ICNA3311",
276     .Bind = PanelDriverBind,
277     .Init = PanelDriverInit,
278     .Release = PanelDriverRelease,
279 };
280 
281 HDF_INIT(g_ICNA3311DriverEntry);
282 #endif