• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "mipi_jdi_gt911.h"
10 #include "gpio_if.h"
11 #include "hdf_bl.h"
12 #include "hdf_disp.h"
13 #include "osal.h"
14 
15 struct panel_jdi_gt911_dev *g_panel_jdi_gt911_dev = NULL;
16 
17 static struct panel_jdi_gt911_dev *
ToPanelSimpleDev(const struct PanelData * panel)18 ToPanelSimpleDev(const struct PanelData *panel)
19 {
20     return (struct panel_jdi_gt911_dev *)panel->object->priv;
21 }
22 
panel_simple_regulator_enable(void)23 static int32_t panel_simple_regulator_enable(void)
24 {
25     int32_t err;
26     HDF_LOGI("%s enter", __func__);
27     if (g_panel_jdi_gt911_dev == NULL) {
28         return -1;
29     }
30     err = regulator_enable(g_panel_jdi_gt911_dev->supply);
31     if (err < 0) {
32         HDF_LOGE("regulator_enable failed");
33         return err;
34     }
35     return 0;
36 }
panel_simple_regulator_disable(void)37 static int32_t panel_simple_regulator_disable(void)
38 {
39     int32_t err;
40     HDF_LOGI("%s enter", __func__);
41     if (g_panel_jdi_gt911_dev == NULL) {
42         return -1;
43     }
44     regulator_disable(g_panel_jdi_gt911_dev->supply);
45     return 0;
46 }
47 
panel_simple_loader_protect(struct drm_panel * panel)48 int panel_simple_loader_protect(struct drm_panel *panel)
49 {
50     int err;
51     (void)panel;
52     HDF_LOGI("%s enter", __func__);
53     err = panel_simple_regulator_enable();
54     if (err < 0) {
55         HDF_LOGE("failed to enable supply: %d\n", err);
56         return err;
57     }
58     return 0;
59 }
60 EXPORT_SYMBOL(panel_simple_loader_protect);
61 
PanelSendCmds(struct mipi_dsi_device * dsi,const struct DsiCmdDesc * cmds,int size)62 static int32_t PanelSendCmds(struct mipi_dsi_device *dsi,
63                              const struct DsiCmdDesc *cmds, int size)
64 {
65     int32_t i = 0;
66 
67     HDF_LOGI("%s enter", __func__);
68     if (dsi == NULL) {
69         HDF_LOGE("dsi is NULL");
70         return -EINVAL;
71     }
72     for (i = 0; i < size; i++) {
73         mipi_dsi_dcs_write_buffer(dsi, cmds[i].payload, cmds[i].dataLen);
74         if (cmds[i].delay) {
75             OsalMSleep(cmds[i].delay);
76         }
77     }
78     return HDF_SUCCESS;
79 }
80 
PanelOn(struct PanelData * panel)81 static int32_t PanelOn(struct PanelData *panel)
82 {
83     struct panel_jdi_gt911_dev *panel_dev = NULL;
84 
85     HDF_LOGI("%s enter", __func__);
86     panel_dev = ToPanelSimpleDev(panel);
87     if (panel_dev->hw_delay.enable_delay) {
88         OsalMSleep(panel_dev->hw_delay.enable_delay);
89     }
90     return HDF_SUCCESS;
91 }
92 
PanelOff(struct PanelData * panel)93 static int32_t PanelOff(struct PanelData *panel)
94 {
95     struct panel_jdi_gt911_dev *panel_dev = NULL;
96     HDF_LOGI("%s enter", __func__);
97     panel_dev = ToPanelSimpleDev(panel);
98     if (panel_dev->hw_delay.disable_delay) {
99         OsalMSleep(panel_dev->hw_delay.disable_delay);
100     }
101     return HDF_SUCCESS;
102 }
103 
PanelPrepare(struct PanelData * panel)104 static int32_t PanelPrepare(struct PanelData *panel)
105 {
106     int32_t ret;
107     struct panel_jdi_gt911_dev *panel_dev = NULL;
108 
109     HDF_LOGI("%s enter", __func__);
110 
111     panel_dev = ToPanelSimpleDev(panel);
112     if (panel_dev->prepared) {
113         return 0;
114     }
115 
116     ret = regulator_enable(panel_dev->supply);
117     if (ret < 0) {
118         HDF_LOGE("failed to enable supply: %d\n", ret);
119         return ret;
120     }
121     gpiod_set_value_cansleep(panel_dev->enable_gpio, 1);
122 
123     if (panel_dev->hw_delay.reset_delay > 0) {
124         OsalMSleep(panel_dev->hw_delay.reset_delay);
125     }
126 
127     gpiod_set_value_cansleep(panel_dev->reset_gpio, 1);
128 
129     if (panel_dev->hw_delay.reset_delay > 0) {
130         OsalMSleep(panel_dev->hw_delay.reset_delay);
131     }
132 
133     gpiod_set_value_cansleep(panel_dev->reset_gpio, 0);
134 
135     if (panel_dev->hw_delay.prepare_delay > 0) {
136         OsalMSleep(panel_dev->hw_delay.prepare_delay);
137     }
138 
139     ret = PanelSendCmds(panel_dev->dsiDev, g_panelOnCode,
140                         sizeof(g_panelOnCode) / sizeof(g_panelOnCode[0]));
141     if (ret != HDF_SUCCESS) {
142         HDF_LOGE("%s PanelSendCmds failed", __func__);
143         return HDF_FAILURE;
144     }
145     if (panel_dev->hw_delay.init_delay > 0) {
146         OsalMSleep(panel_dev->hw_delay.init_delay);
147     }
148 
149     panel_dev->prepared = true;
150 
151     return HDF_SUCCESS;
152 }
153 
PanelUnprepare(struct PanelData * panel)154 static int32_t PanelUnprepare(struct PanelData *panel)
155 {
156     int32_t ret;
157     struct panel_jdi_gt911_dev *panel_dev = NULL;
158     HDF_LOGI("%s enter", __func__);
159     panel_dev = ToPanelSimpleDev(panel);
160 
161     if (!panel_dev->prepared) {
162         return 0;
163     }
164 
165     ret = PanelSendCmds(panel_dev->dsiDev, g_panelOffCode,
166                         sizeof(g_panelOffCode) / sizeof(g_panelOffCode[0]));
167     if (ret != HDF_SUCCESS) {
168         HDF_LOGE("%s PanelSendCmds failed", __func__);
169         return HDF_FAILURE;
170     }
171     gpiod_set_value_cansleep(panel_dev->reset_gpio, 1);
172     gpiod_set_value_cansleep(panel_dev->enable_gpio, 1);
173     regulator_disable(panel_dev->supply);
174 
175     if (panel_dev->hw_delay.unprepare_delay) {
176         OsalMSleep(panel_dev->hw_delay.unprepare_delay);
177     }
178 
179     panel_dev->prepared = false;
180 
181     return HDF_SUCCESS;
182 }
183 
PanelInit(struct PanelData * panel)184 static int32_t PanelInit(struct PanelData *panel)
185 {
186     struct panel_jdi_gt911_dev *panel_dev = NULL;
187 
188     HDF_LOGI("%s enter", __func__);
189 
190     panel_dev = ToPanelSimpleDev(panel);
191     panel_dev->prepared = false;
192     return 0;
193 }
194 
195 #define BLK_PWM_INDEX 4
196 #define PWM_MAX_PERIOD 25000
197 /* backlight setting */
198 #define MIN_LEVEL 0
199 #define MAX_LEVEL 255
200 #define DEFAULT_LEVEL 200
201 
202 static struct PanelInfo g_panelInfo = {
203     .width = 1920,                           /* width */
204     .height = 1200,                          /* height */
205     .hbp = 60,                               /* horizontal back porch */
206     .hfp = 16,                               /* horizontal front porch */
207     .hsw = 20,                               /* horizontal sync width */
208     .vbp = 23,                               /* vertical back porch */
209     .vfp = 12,                               /* vertical front porch */
210     .vsw = 3,                                /* vertical sync width */
211     .clockFreq = 140000000,                  /* clock */
212     .pWidth = 2700,                          /* physical width */
213     .pHeight = 1600,                         /* physical height */
214     .connectorType = DRM_MODE_CONNECTOR_DPI, /* DRM_MODE_CONNECTOR_DPI=17 */
215     .blk = {BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL},
216 };
217 
PanelResInit(struct panel_jdi_gt911_dev * panel_dev)218 static void PanelResInit(struct panel_jdi_gt911_dev *panel_dev)
219 {
220     panel_dev->dsiDev->lanes =
221         4; /* 4: dsi,lanes ,number of active data lanes */
222     panel_dev->dsiDev->format =
223         MIPI_DSI_FMT_RGB888; // dsi,format pixel format for video mode
224                              // MIPI_DSI_FMT_RGB888
225     panel_dev->dsiDev->mode_flags =
226         (MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM |
227          MIPI_DSI_MODE_EOT_PACKET);
228     panel_dev->panel.info = &g_panelInfo;
229     panel_dev->panel.init = PanelInit;
230     panel_dev->panel.on = PanelOn;
231     panel_dev->panel.off = PanelOff;
232     panel_dev->panel.prepare = PanelPrepare;
233     panel_dev->panel.unprepare = PanelUnprepare;
234     panel_dev->panel.priv = panel_dev->dsiDev;
235     panel_dev->hw_delay.disable_delay = 0;   /* 50:disable_delay time */
236     panel_dev->hw_delay.enable_delay = 0x78;  /* 120:enable_delay */
237     panel_dev->hw_delay.init_delay = 0x78;    /* 20:init_delay */
238     panel_dev->hw_delay.prepare_delay = 0x78; /* 2:prepare_delay */
239     panel_dev->hw_delay.reset_delay = 0x78;   /* 100:reset_delay */
240     panel_dev->hw_delay.unprepare_delay = 0; /* 20:unprepare_delay */
241 }
242 
PanelEntryInit(struct HdfDeviceObject * object)243 int32_t PanelEntryInit(struct HdfDeviceObject *object)
244 {
245     struct device_node *panelNode = NULL;
246     struct panel_jdi_gt911_dev *panel_dev = NULL;
247     HDF_LOGI("%s enter", __func__);
248     panel_dev = (struct panel_jdi_gt911_dev *)OsalMemCalloc(
249         sizeof(struct panel_jdi_gt911_dev));
250     if (panel_dev == NULL) {
251         HDF_LOGE("%s panel_dev malloc fail", __func__);
252         return HDF_FAILURE;
253     }
254     g_panel_jdi_gt911_dev = panel_dev;
255     panelNode = of_find_compatible_node(NULL, NULL, "simple-panel-dsi");
256     if (panelNode == NULL) {
257         HDF_LOGE("%s of_find_compatible_node fail", __func__);
258         goto FAIL;
259     }
260     panel_dev->dsiDev = of_find_mipi_dsi_device_by_node(panelNode);
261     if (panel_dev->dsiDev == NULL) {
262         HDF_LOGE("%s of_find_mipi_dsi_device_by_node fail", __func__);
263         goto FAIL;
264     }
265     panel_dev->supply = devm_regulator_get(&panel_dev->dsiDev->dev, "power");
266     if (panel_dev->supply == NULL) {
267         HDF_LOGE("Get regulator fail");
268         goto FAIL;
269     }
270 
271     panel_dev->enable_gpio =
272         devm_gpiod_get_optional(&panel_dev->dsiDev->dev, "enable", GPIOD_ASIS);
273     if (IS_ERR(panel_dev->enable_gpio)) {
274         HDF_LOGE("get enable_gpio fail");
275         goto FAIL;
276     }
277     panel_dev->hpd_gpio =
278         devm_gpiod_get_optional(&panel_dev->dsiDev->dev, "hpd", GPIOD_IN);
279     if (IS_ERR(panel_dev->hpd_gpio)) {
280         HDF_LOGE("get hpd_gpio fail");
281         goto FAIL;
282     }
283     panel_dev->reset_gpio =
284         devm_gpiod_get_optional(&panel_dev->dsiDev->dev, "reset", GPIOD_ASIS);
285     if (IS_ERR(panel_dev->reset_gpio)) {
286         HDF_LOGE("get reset_gpio fail");
287         goto FAIL;
288     }
289 
290     PanelResInit(panel_dev);
291 
292     panel_dev->panel.object = object;
293     object->priv = panel_dev;
294 
295     if (RegisterPanel(&panel_dev->panel) != HDF_SUCCESS) {
296         HDF_LOGE("RegisterPanel fail");
297         goto FAIL;
298     }
299     HDF_LOGI("%s success", __func__);
300     return HDF_SUCCESS;
301 FAIL:
302     OsalMemFree(panel_dev);
303     return HDF_FAILURE;
304 }
305 
306 struct HdfDriverEntry PanelDevEntry = {
307     .moduleVersion = 1,
308     .moduleName = "LCD_MIPI_JDI_GT911",
309     .Init = PanelEntryInit,
310 };
311 
312 HDF_INIT(PanelDevEntry);
313