1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2016 InforceComputing
4  * Author: Vinay Simha BN <simhavcs@gmail.com>
5  *
6  * Copyright (C) 2016 Linaro Ltd
7  * Author: Sumit Semwal <sumit.semwal@linaro.org>
8  *
9  * From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a
10  * JDI model LT070ME05000, and its data sheet is at:
11  * http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet
12  */
13 
14 #include <linux/backlight.h>
15 #include <linux/delay.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/regulator/consumer.h>
20 
21 #include <video/mipi_display.h>
22 
23 #include <drm/drm_crtc.h>
24 #include <drm/drm_mipi_dsi.h>
25 #include <drm/drm_modes.h>
26 #include <drm/drm_panel.h>
27 
28 static const char * const regulator_names[] = {
29 	"vddp",
30 	"iovcc"
31 };
32 
33 struct jdi_panel {
34 	struct drm_panel base;
35 	struct mipi_dsi_device *dsi;
36 
37 	struct regulator_bulk_data supplies[ARRAY_SIZE(regulator_names)];
38 
39 	struct gpio_desc *enable_gpio;
40 	struct gpio_desc *reset_gpio;
41 	struct gpio_desc *dcdc_en_gpio;
42 	struct backlight_device *backlight;
43 
44 	bool prepared;
45 	bool enabled;
46 
47 	const struct drm_display_mode *mode;
48 };
49 
50 static inline struct jdi_panel *to_jdi_panel(struct drm_panel *panel)
51 {
52 	return container_of(panel, struct jdi_panel, base);
53 }
54 
55 static int jdi_panel_init(struct jdi_panel *jdi)
56 {
57 	struct mipi_dsi_device *dsi = jdi->dsi;
58 	struct device *dev = &jdi->dsi->dev;
59 	int ret;
60 
61 	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
62 
63 	ret = mipi_dsi_dcs_soft_reset(dsi);
64 	if (ret < 0)
65 		return ret;
66 
67 	usleep_range(10000, 20000);
68 
69 	ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT << 4);
70 	if (ret < 0) {
71 		dev_err(dev, "failed to set pixel format: %d\n", ret);
72 		return ret;
73 	}
74 
75 	ret = mipi_dsi_dcs_set_column_address(dsi, 0, jdi->mode->hdisplay - 1);
76 	if (ret < 0) {
77 		dev_err(dev, "failed to set column address: %d\n", ret);
78 		return ret;
79 	}
80 
81 	ret = mipi_dsi_dcs_set_page_address(dsi, 0, jdi->mode->vdisplay - 1);
82 	if (ret < 0) {
83 		dev_err(dev, "failed to set page address: %d\n", ret);
84 		return ret;
85 	}
86 
87 	/*
88 	 * BIT(5) BCTRL = 1 Backlight Control Block On, Brightness registers
89 	 *                  are active
90 	 * BIT(3) BL = 1    Backlight Control On
91 	 * BIT(2) DD = 0    Display Dimming is Off
92 	 */
93 	ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
94 				 (u8[]){ 0x24 }, 1);
95 	if (ret < 0) {
96 		dev_err(dev, "failed to write control display: %d\n", ret);
97 		return ret;
98 	}
99 
100 	/* CABC off */
101 	ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_POWER_SAVE,
102 				 (u8[]){ 0x00 }, 1);
103 	if (ret < 0) {
104 		dev_err(dev, "failed to set cabc off: %d\n", ret);
105 		return ret;
106 	}
107 
108 	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
109 	if (ret < 0) {
110 		dev_err(dev, "failed to set exit sleep mode: %d\n", ret);
111 		return ret;
112 	}
113 
114 	msleep(120);
115 
116 	ret = mipi_dsi_generic_write(dsi, (u8[]){0xB0, 0x00}, 2);
117 	if (ret < 0) {
118 		dev_err(dev, "failed to set mcap: %d\n", ret);
119 		return ret;
120 	}
121 
122 	mdelay(10);
123 
124 	/* Interface setting, video mode */
125 	ret = mipi_dsi_generic_write(dsi, (u8[])
126 				     {0xB3, 0x26, 0x08, 0x00, 0x20, 0x00}, 6);
127 	if (ret < 0) {
128 		dev_err(dev, "failed to set display interface setting: %d\n"
129 			, ret);
130 		return ret;
131 	}
132 
133 	mdelay(20);
134 
135 	ret = mipi_dsi_generic_write(dsi, (u8[]){0xB0, 0x03}, 2);
136 	if (ret < 0) {
137 		dev_err(dev, "failed to set default values for mcap: %d\n"
138 			, ret);
139 		return ret;
140 	}
141 
142 	return 0;
143 }
144 
145 static int jdi_panel_on(struct jdi_panel *jdi)
146 {
147 	struct mipi_dsi_device *dsi = jdi->dsi;
148 	struct device *dev = &jdi->dsi->dev;
149 	int ret;
150 
151 	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
152 
153 	ret = mipi_dsi_dcs_set_display_on(dsi);
154 	if (ret < 0)
155 		dev_err(dev, "failed to set display on: %d\n", ret);
156 
157 	return ret;
158 }
159 
160 static void jdi_panel_off(struct jdi_panel *jdi)
161 {
162 	struct mipi_dsi_device *dsi = jdi->dsi;
163 	struct device *dev = &jdi->dsi->dev;
164 	int ret;
165 
166 	dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
167 
168 	ret = mipi_dsi_dcs_set_display_off(dsi);
169 	if (ret < 0)
170 		dev_err(dev, "failed to set display off: %d\n", ret);
171 
172 	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
173 	if (ret < 0)
174 		dev_err(dev, "failed to enter sleep mode: %d\n", ret);
175 
176 	msleep(100);
177 }
178 
179 static int jdi_panel_disable(struct drm_panel *panel)
180 {
181 	struct jdi_panel *jdi = to_jdi_panel(panel);
182 
183 	if (!jdi->enabled)
184 		return 0;
185 
186 	backlight_disable(jdi->backlight);
187 
188 	jdi->enabled = false;
189 
190 	return 0;
191 }
192 
193 static int jdi_panel_unprepare(struct drm_panel *panel)
194 {
195 	struct jdi_panel *jdi = to_jdi_panel(panel);
196 	struct device *dev = &jdi->dsi->dev;
197 	int ret;
198 
199 	if (!jdi->prepared)
200 		return 0;
201 
202 	jdi_panel_off(jdi);
203 
204 	ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
205 	if (ret < 0)
206 		dev_err(dev, "regulator disable failed, %d\n", ret);
207 
208 	gpiod_set_value(jdi->enable_gpio, 0);
209 
210 	gpiod_set_value(jdi->reset_gpio, 1);
211 
212 	gpiod_set_value(jdi->dcdc_en_gpio, 0);
213 
214 	jdi->prepared = false;
215 
216 	return 0;
217 }
218 
219 static int jdi_panel_prepare(struct drm_panel *panel)
220 {
221 	struct jdi_panel *jdi = to_jdi_panel(panel);
222 	struct device *dev = &jdi->dsi->dev;
223 	int ret;
224 
225 	if (jdi->prepared)
226 		return 0;
227 
228 	ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
229 	if (ret < 0) {
230 		dev_err(dev, "regulator enable failed, %d\n", ret);
231 		return ret;
232 	}
233 
234 	msleep(20);
235 
236 	gpiod_set_value(jdi->dcdc_en_gpio, 1);
237 	usleep_range(10, 20);
238 
239 	gpiod_set_value(jdi->reset_gpio, 0);
240 	usleep_range(10, 20);
241 
242 	gpiod_set_value(jdi->enable_gpio, 1);
243 	usleep_range(10, 20);
244 
245 	ret = jdi_panel_init(jdi);
246 	if (ret < 0) {
247 		dev_err(dev, "failed to init panel: %d\n", ret);
248 		goto poweroff;
249 	}
250 
251 	ret = jdi_panel_on(jdi);
252 	if (ret < 0) {
253 		dev_err(dev, "failed to set panel on: %d\n", ret);
254 		goto poweroff;
255 	}
256 
257 	jdi->prepared = true;
258 
259 	return 0;
260 
261 poweroff:
262 	ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
263 	if (ret < 0)
264 		dev_err(dev, "regulator disable failed, %d\n", ret);
265 
266 	gpiod_set_value(jdi->enable_gpio, 0);
267 
268 	gpiod_set_value(jdi->reset_gpio, 1);
269 
270 	gpiod_set_value(jdi->dcdc_en_gpio, 0);
271 
272 	return ret;
273 }
274 
275 static int jdi_panel_enable(struct drm_panel *panel)
276 {
277 	struct jdi_panel *jdi = to_jdi_panel(panel);
278 
279 	if (jdi->enabled)
280 		return 0;
281 
282 	backlight_enable(jdi->backlight);
283 
284 	jdi->enabled = true;
285 
286 	return 0;
287 }
288 
289 static const struct drm_display_mode default_mode = {
290 		.clock = 155493,
291 		.hdisplay = 1200,
292 		.hsync_start = 1200 + 48,
293 		.hsync_end = 1200 + 48 + 32,
294 		.htotal = 1200 + 48 + 32 + 60,
295 		.vdisplay = 1920,
296 		.vsync_start = 1920 + 3,
297 		.vsync_end = 1920 + 3 + 5,
298 		.vtotal = 1920 + 3 + 5 + 6,
299 		.vrefresh = 60,
300 		.flags = 0,
301 };
302 
303 static int jdi_panel_get_modes(struct drm_panel *panel,
304 			       struct drm_connector *connector)
305 {
306 	struct drm_display_mode *mode;
307 	struct jdi_panel *jdi = to_jdi_panel(panel);
308 	struct device *dev = &jdi->dsi->dev;
309 
310 	mode = drm_mode_duplicate(connector->dev, &default_mode);
311 	if (!mode) {
312 		dev_err(dev, "failed to add mode %ux%ux@%u\n",
313 			default_mode.hdisplay, default_mode.vdisplay,
314 			default_mode.vrefresh);
315 		return -ENOMEM;
316 	}
317 
318 	drm_mode_set_name(mode);
319 
320 	drm_mode_probed_add(connector, mode);
321 
322 	connector->display_info.width_mm = 95;
323 	connector->display_info.height_mm = 151;
324 
325 	return 1;
326 }
327 
328 static int dsi_dcs_bl_get_brightness(struct backlight_device *bl)
329 {
330 	struct mipi_dsi_device *dsi = bl_get_data(bl);
331 	int ret;
332 	u16 brightness = bl->props.brightness;
333 
334 	dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
335 
336 	ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
337 	if (ret < 0)
338 		return ret;
339 
340 	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
341 
342 	return brightness & 0xff;
343 }
344 
345 static int dsi_dcs_bl_update_status(struct backlight_device *bl)
346 {
347 	struct mipi_dsi_device *dsi = bl_get_data(bl);
348 	int ret;
349 
350 	dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
351 
352 	ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness);
353 	if (ret < 0)
354 		return ret;
355 
356 	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
357 
358 	return 0;
359 }
360 
361 static const struct backlight_ops dsi_bl_ops = {
362 	.update_status = dsi_dcs_bl_update_status,
363 	.get_brightness = dsi_dcs_bl_get_brightness,
364 };
365 
366 static struct backlight_device *
367 drm_panel_create_dsi_backlight(struct mipi_dsi_device *dsi)
368 {
369 	struct device *dev = &dsi->dev;
370 	struct backlight_properties props;
371 
372 	memset(&props, 0, sizeof(props));
373 	props.type = BACKLIGHT_RAW;
374 	props.brightness = 255;
375 	props.max_brightness = 255;
376 
377 	return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
378 					      &dsi_bl_ops, &props);
379 }
380 
381 static const struct drm_panel_funcs jdi_panel_funcs = {
382 	.disable = jdi_panel_disable,
383 	.unprepare = jdi_panel_unprepare,
384 	.prepare = jdi_panel_prepare,
385 	.enable = jdi_panel_enable,
386 	.get_modes = jdi_panel_get_modes,
387 };
388 
389 static const struct of_device_id jdi_of_match[] = {
390 	{ .compatible = "jdi,lt070me05000", },
391 	{ }
392 };
393 MODULE_DEVICE_TABLE(of, jdi_of_match);
394 
395 static int jdi_panel_add(struct jdi_panel *jdi)
396 {
397 	struct device *dev = &jdi->dsi->dev;
398 	int ret;
399 	unsigned int i;
400 
401 	jdi->mode = &default_mode;
402 
403 	for (i = 0; i < ARRAY_SIZE(jdi->supplies); i++)
404 		jdi->supplies[i].supply = regulator_names[i];
405 
406 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies),
407 				      jdi->supplies);
408 	if (ret < 0) {
409 		dev_err(dev, "failed to init regulator, ret=%d\n", ret);
410 		return ret;
411 	}
412 
413 	jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
414 	if (IS_ERR(jdi->enable_gpio)) {
415 		ret = PTR_ERR(jdi->enable_gpio);
416 		dev_err(dev, "cannot get enable-gpio %d\n", ret);
417 		return ret;
418 	}
419 
420 	jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
421 	if (IS_ERR(jdi->reset_gpio)) {
422 		ret = PTR_ERR(jdi->reset_gpio);
423 		dev_err(dev, "cannot get reset-gpios %d\n", ret);
424 		return ret;
425 	}
426 
427 	jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW);
428 	if (IS_ERR(jdi->dcdc_en_gpio)) {
429 		ret = PTR_ERR(jdi->dcdc_en_gpio);
430 		dev_err(dev, "cannot get dcdc-en-gpio %d\n", ret);
431 		return ret;
432 	}
433 
434 	jdi->backlight = drm_panel_create_dsi_backlight(jdi->dsi);
435 	if (IS_ERR(jdi->backlight)) {
436 		ret = PTR_ERR(jdi->backlight);
437 		dev_err(dev, "failed to register backlight %d\n", ret);
438 		return ret;
439 	}
440 
441 	drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,
442 		       DRM_MODE_CONNECTOR_DSI);
443 
444 	ret = drm_panel_add(&jdi->base);
445 
446 	return ret;
447 }
448 
449 static void jdi_panel_del(struct jdi_panel *jdi)
450 {
451 	if (jdi->base.dev)
452 		drm_panel_remove(&jdi->base);
453 }
454 
455 static int jdi_panel_probe(struct mipi_dsi_device *dsi)
456 {
457 	struct jdi_panel *jdi;
458 	int ret;
459 
460 	dsi->lanes = 4;
461 	dsi->format = MIPI_DSI_FMT_RGB888;
462 	dsi->mode_flags =  MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
463 			   MIPI_DSI_CLOCK_NON_CONTINUOUS;
464 
465 	jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL);
466 	if (!jdi)
467 		return -ENOMEM;
468 
469 	mipi_dsi_set_drvdata(dsi, jdi);
470 
471 	jdi->dsi = dsi;
472 
473 	ret = jdi_panel_add(jdi);
474 	if (ret < 0)
475 		return ret;
476 
477 	return mipi_dsi_attach(dsi);
478 }
479 
480 static int jdi_panel_remove(struct mipi_dsi_device *dsi)
481 {
482 	struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
483 	int ret;
484 
485 	ret = jdi_panel_disable(&jdi->base);
486 	if (ret < 0)
487 		dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
488 
489 	ret = mipi_dsi_detach(dsi);
490 	if (ret < 0)
491 		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n",
492 			ret);
493 
494 	jdi_panel_del(jdi);
495 
496 	return 0;
497 }
498 
499 static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
500 {
501 	struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
502 
503 	jdi_panel_disable(&jdi->base);
504 }
505 
506 static struct mipi_dsi_driver jdi_panel_driver = {
507 	.driver = {
508 		.name = "panel-jdi-lt070me05000",
509 		.of_match_table = jdi_of_match,
510 	},
511 	.probe = jdi_panel_probe,
512 	.remove = jdi_panel_remove,
513 	.shutdown = jdi_panel_shutdown,
514 };
515 module_mipi_dsi_driver(jdi_panel_driver);
516 
517 MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
518 MODULE_AUTHOR("Vinay Simha BN <simhavcs@gmail.com>");
519 MODULE_DESCRIPTION("JDI LT070ME05000 WUXGA");
520 MODULE_LICENSE("GPL v2");
521