• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "gpio_if.h"
10 #include "hdf_disp.h"
11 #include "hdf_log.h"
12 #include "mipi_dsi_if.h"
13 #include "osal.h"
14 #include "pwm_if.h"
15 
16 #define RESET_GPIO                5
17 #define MIPI_DSI0                 0
18 #define BLK_PWM1                  1
19 #define PWM_MAX_PERIOD            100000
20 /* backlight setting */
21 #define MIN_LEVEL                 0
22 #define MAX_LEVEL                 255
23 #define DEFAULT_LEVEL             100
24 
25 #define WIDTH                     480
26 #define HEIGHT                    960
27 #define HORIZONTAL_BACK_PORCH     20
28 #define HORIZONTAL_FRONT_PORCH    20
29 #define HORIZONTAL_SYNC_WIDTH     10
30 #define VERTICAL_BACK_PORCH       14
31 #define VERTICAL_FRONT_PORCH      16
32 #define VERTICAL_SYNC_WIDTH       2
33 #define FRAME_RATE                60
34 
35 /* panel on command payload */
36 static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A };
37 static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 };
38 static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B };
39 static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A };
40 static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C };
41 static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C };
42 static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 };
43 static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 };
44 static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 };
45 static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 };
46 static uint8_t g_payLoad10[] = { 0xb7, 0x41 };
47 static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 };
48 static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 };
49 static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 };
50 static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF };
51 static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 };
52 static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 };
53 static uint8_t g_payLoad17[] = { 0xc7, 0x04 };
54 static uint8_t g_payLoad18[] = {
55     0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40,
56     0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52,
57     0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06
58 };
59 static uint8_t g_payLoad19[] = { 0x11 };
60 static uint8_t g_payLoad20[] = { 0x29 };
61 
62 struct DsiCmdDesc g_OnCmd[] = {
63     { 0x29, 0, sizeof(g_payLoad0), g_payLoad0 },
64     { 0x29, 0, sizeof(g_payLoad1), g_payLoad1 },
65     { 0x29, 0, sizeof(g_payLoad2), g_payLoad2 },
66     { 0x29, 0, sizeof(g_payLoad3), g_payLoad3 },
67     { 0x29, 0, sizeof(g_payLoad4), g_payLoad4 },
68     { 0x29, 0, sizeof(g_payLoad5), g_payLoad5 },
69     { 0x29, 0, sizeof(g_payLoad6), g_payLoad6 },
70     { 0x29, 0, sizeof(g_payLoad7), g_payLoad7 },
71     { 0x29, 0, sizeof(g_payLoad8), g_payLoad8 },
72     { 0x29, 0, sizeof(g_payLoad9), g_payLoad9 },
73     { 0x23, 0, sizeof(g_payLoad10), g_payLoad10 },
74     { 0x29, 0, sizeof(g_payLoad11), g_payLoad11 },
75     { 0x29, 0, sizeof(g_payLoad12), g_payLoad12 },
76     { 0x29, 0, sizeof(g_payLoad13), g_payLoad13 },
77     { 0x29, 0, sizeof(g_payLoad14), g_payLoad14 },
78     { 0x29, 0, sizeof(g_payLoad15), g_payLoad15 },
79     { 0x29, 0, sizeof(g_payLoad16), g_payLoad16 },
80     { 0x23, 0, sizeof(g_payLoad17), g_payLoad17 },
81     { 0x29, 1, sizeof(g_payLoad18), g_payLoad18 },
82     { 0x05, 120, sizeof(g_payLoad19), g_payLoad19 },
83     { 0x05, 120, sizeof(g_payLoad20), g_payLoad20 },
84 };
85 
86 /* panel off command payload */
87 static uint8_t g_offPayLoad0[] = { 0x28 };
88 static uint8_t g_offPayLoad1[] = { 0x10 };
89 struct DsiCmdDesc g_offCmd[] = {
90     { 0x05, 20, sizeof(g_offPayLoad0), g_offPayLoad0 },
91     { 0x05, 120, sizeof(g_offPayLoad1), g_offPayLoad1 },
92 };
93 
94 struct Icn9700Dev {
95     struct PanelData panel;
96     DevHandle mipiHandle;
97     uint16_t reset_gpio;
98     uint16_t reset_delay;
99 };
100 
LcdResetOn(struct Icn9700Dev * icn9700)101 static int32_t LcdResetOn(struct Icn9700Dev *icn9700)
102 {
103     int32_t ret;
104 
105     ret = GpioSetDir(icn9700->reset_gpio, GPIO_DIR_OUT);
106     if (ret != HDF_SUCCESS) {
107         HDF_LOGE("GpioSetDir failed, ret:%d", ret);
108         return HDF_FAILURE;
109     }
110     ret = GpioWrite(icn9700->reset_gpio, GPIO_VAL_HIGH);
111     if (ret != HDF_SUCCESS) {
112         HDF_LOGE("GpioWrite failed, ret:%d", ret);
113         return HDF_FAILURE;
114     }
115     /* delay 20ms */
116     OsalMSleep(icn9700->reset_delay);
117     return HDF_SUCCESS;
118 }
119 
LcdResetOff(struct Icn9700Dev * icn9700)120 static int32_t LcdResetOff(struct Icn9700Dev *icn9700)
121 {
122     int32_t ret;
123 
124     ret = GpioSetDir(icn9700->reset_gpio, GPIO_DIR_OUT);
125     if (ret != HDF_SUCCESS) {
126         HDF_LOGE("GpioSetDir failed, ret:%d", ret);
127         return HDF_FAILURE;
128     }
129     ret = GpioWrite(icn9700->reset_gpio, GPIO_VAL_LOW);
130     if (ret != HDF_SUCCESS) {
131         HDF_LOGE("GpioWrite failed, ret:%d", ret);
132         return HDF_FAILURE;
133     }
134     /* delay 20ms */
135     OsalMSleep(icn9700->reset_delay);
136     return HDF_SUCCESS;
137 }
138 
PanelToIcn9700Dev(const struct PanelData * panel)139 static struct Icn9700Dev *PanelToIcn9700Dev(const struct PanelData *panel)
140 {
141     struct Icn9700Dev *icn9700 = NULL;
142 
143     if (panel == NULL) {
144         HDF_LOGE("%s: panel is null", __func__);
145         return NULL;
146     }
147     if (panel->object == NULL) {
148         HDF_LOGE("%s: object is null", __func__);
149         return NULL;
150     }
151     icn9700 = (struct Icn9700Dev *)panel->object->priv;
152     return icn9700;
153 }
154 
Icn9700Init(struct PanelData * panel)155 static int32_t Icn9700Init(struct PanelData *panel)
156 {
157     struct Icn9700Dev *icn9700 = NULL;
158 
159     icn9700 = PanelToIcn9700Dev(panel);
160     if (icn9700 == NULL) {
161         HDF_LOGE("%s: icn9700 is null", __func__);
162         return HDF_FAILURE;
163     }
164     icn9700->mipiHandle = MipiDsiOpen(MIPI_DSI0);
165     if (icn9700->mipiHandle == NULL) {
166         HDF_LOGE("%s: MipiDsiOpen failed", __func__);
167         return HDF_FAILURE;
168     }
169     return HDF_SUCCESS;
170 }
171 
Icn9700On(struct PanelData * panel)172 static int32_t Icn9700On(struct PanelData *panel)
173 {
174     int32_t ret;
175     struct Icn9700Dev *icn9700 = NULL;
176 
177     icn9700 = PanelToIcn9700Dev(panel);
178     if (icn9700 == NULL) {
179         HDF_LOGE("%s: icn9700 is null", __func__);
180         return HDF_FAILURE;
181     }
182     /* lcd reset power on */
183     ret = LcdResetOn(icn9700);
184     if (ret != HDF_SUCCESS) {
185         HDF_LOGE("%s: LcdResetOn failed", __func__);
186         return HDF_FAILURE;
187     }
188     if (icn9700->mipiHandle == NULL) {
189         HDF_LOGE("%s: mipiHandle is null", __func__);
190         return HDF_FAILURE;
191     }
192     /* send mipi init code */
193     int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]);
194     int32_t i;
195     for (i = 0; i < count; i++) {
196         ret = MipiDsiTx(icn9700->mipiHandle, &(g_OnCmd[i]));
197         if (ret != HDF_SUCCESS) {
198             HDF_LOGE("%s: MipiDsiTx failed", __func__);
199             return HDF_FAILURE;
200         }
201     }
202     /* set mipi to hs mode */
203     MipiDsiSetHsMode(icn9700->mipiHandle);
204     return HDF_SUCCESS;
205 }
206 
Icn9700Off(struct PanelData * panel)207 static int32_t Icn9700Off(struct PanelData *panel)
208 {
209     int32_t ret;
210     struct Icn9700Dev *icn9700 = NULL;
211 
212     icn9700 = PanelToIcn9700Dev(panel);
213     if (icn9700 == NULL) {
214         HDF_LOGE("%s: icn9700 is null", __func__);
215         return HDF_FAILURE;
216     }
217     if (icn9700->mipiHandle == NULL) {
218         HDF_LOGE("%s: mipiHandle is null", __func__);
219         return HDF_FAILURE;
220     }
221     /* send mipi init code */
222     int32_t count = sizeof(g_offCmd) / sizeof(g_offCmd[0]);
223     int32_t i;
224     for (i = 0; i < count; i++) {
225         ret = MipiDsiTx(icn9700->mipiHandle, &(g_offCmd[i]));
226         if (ret != HDF_SUCCESS) {
227             HDF_LOGE("%s: MipiDsiTx failed", __func__);
228             return HDF_FAILURE;
229         }
230     }
231     /* set mipi to lp mode */
232     MipiDsiSetLpMode(icn9700->mipiHandle);
233     /* lcd reset power off */
234     ret = LcdResetOff(icn9700);
235     if (ret != HDF_SUCCESS) {
236         HDF_LOGE("%s: LcdResetOff failed", __func__);
237         return HDF_FAILURE;
238     }
239     return HDF_SUCCESS;
240 }
241 
Icn9700EsdCheckFunc(struct PanelData * panel)242 static int32_t Icn9700EsdCheckFunc(struct PanelData *panel)
243 {
244     struct Icn9700Dev *icn9700 = NULL;
245 
246     icn9700 = PanelToIcn9700Dev(panel);
247     if (icn9700 == NULL) {
248         HDF_LOGE("%s: icn9700 is null", __func__);
249         return HDF_FAILURE;
250     }
251     HDF_LOGE("%s: enter", __func__);
252     return HDF_SUCCESS;
253 }
254 
255 #define OUTPUT_USER 0 /* output timing type */
256 static struct PanelInfo g_panelInfo = {
257     .width = WIDTH,                     /* width */
258     .height = HEIGHT,                   /* height */
259     .hbp = HORIZONTAL_BACK_PORCH,       /* horizontal back porch */
260     .hfp = HORIZONTAL_FRONT_PORCH,      /* horizontal front porch */
261     .hsw = HORIZONTAL_SYNC_WIDTH,       /* horizontal sync width */
262     .vbp = VERTICAL_BACK_PORCH,         /* vertical back porch */
263     .vfp = VERTICAL_FRONT_PORCH,        /* vertical front porch */
264     .vsw = VERTICAL_SYNC_WIDTH,         /* vertical sync width */
265     .frameRate = FRAME_RATE,            /* frame rate */
266     .intfType = MIPI_DSI,               /* panel interface type */
267     .intfSync = OUTPUT_USER,
268     /* mipi config info */
269     .mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT },
270     /* backlight config info */
271     .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL },
272     .pwm = { BLK_PWM1, PWM_MAX_PERIOD },
273 };
274 
275 static struct PanelEsd g_panelEsd = {
276     .support = false,
277     .checkFunc = Icn9700EsdCheckFunc,
278 };
279 
Icn9700PanelInit(struct PanelData * panel)280 static void Icn9700PanelInit(struct PanelData *panel)
281 {
282     panel->info = &g_panelInfo;
283     panel->esd = &g_panelEsd;
284     panel->init = Icn9700Init;
285     panel->on = Icn9700On;
286     panel->off = Icn9700Off;
287 }
288 
Icn9700EntryInit(struct HdfDeviceObject * object)289 int32_t Icn9700EntryInit(struct HdfDeviceObject *object)
290 {
291     struct Icn9700Dev *icn9700 = NULL;
292 
293     if (object == NULL) {
294         HDF_LOGE("%s: object is null", __func__);
295         return HDF_FAILURE;
296     }
297     icn9700 = (struct Icn9700Dev *)OsalMemCalloc(sizeof(struct Icn9700Dev));
298     if (icn9700 == NULL) {
299         HDF_LOGE("%s icn9700 malloc fail", __func__);
300         return HDF_FAILURE;
301     }
302     Icn9700PanelInit(&icn9700->panel);
303     icn9700->panel.object = object;
304     icn9700->reset_gpio = RESET_GPIO;
305     icn9700->reset_delay = 20; // delay 20ms
306     object->priv = (void *)icn9700;
307     icn9700->panel.blDev = GetBacklightDev("hdf_pwm");
308     if (icn9700->panel.blDev == NULL) {
309         HDF_LOGE("%s GetBacklightDev fail", __func__);
310         return HDF_FAILURE;
311     }
312     if (RegisterPanel(&icn9700->panel) != HDF_SUCCESS) {
313         HDF_LOGE("%s: RegisterPanel failed", __func__);
314         return HDF_FAILURE;
315     }
316     HDF_LOGI("%s: exit succ", __func__);
317     return HDF_SUCCESS;
318 }
319 
320 struct HdfDriverEntry g_icn9700DevEntry = {
321     .moduleVersion = 1,
322     .moduleName = "LCD_ICN9700",
323     .Init = Icn9700EntryInit,
324 };
325 
326 HDF_INIT(g_icn9700DevEntry);
327