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