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