1 /*
2  * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sub license,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the
12  * next paragraph) shall be included in all copies or substantial portions
13  * of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <linux/backlight.h>
25 #include <linux/gpio/consumer.h>
26 #include <linux/module.h>
27 #include <linux/of_platform.h>
28 #include <linux/platform_device.h>
29 #include <linux/regulator/consumer.h>
30 
31 #include <drm/drmP.h>
32 #include <drm/drm_crtc.h>
33 #include <drm/drm_mipi_dsi.h>
34 #include <drm/drm_panel.h>
35 
36 struct panel_desc {
37 	const struct drm_display_mode *modes;
38 	unsigned int num_modes;
39 
40 	struct {
41 		unsigned int width;
42 		unsigned int height;
43 	} size;
44 };
45 
46 struct panel_simple {
47 	struct drm_panel base;
48 	bool enabled;
49 
50 	const struct panel_desc *desc;
51 
52 	struct backlight_device *backlight;
53 	struct regulator *supply;
54 	struct i2c_adapter *ddc;
55 
56 	struct gpio_desc *enable_gpio;
57 };
58 
59 static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
60 {
61 	return container_of(panel, struct panel_simple, base);
62 }
63 
64 static int panel_simple_get_fixed_modes(struct panel_simple *panel)
65 {
66 	struct drm_connector *connector = panel->base.connector;
67 	struct drm_device *drm = panel->base.drm;
68 	struct drm_display_mode *mode;
69 	unsigned int i, num = 0;
70 
71 	if (!panel->desc)
72 		return 0;
73 
74 	for (i = 0; i < panel->desc->num_modes; i++) {
75 		const struct drm_display_mode *m = &panel->desc->modes[i];
76 
77 		mode = drm_mode_duplicate(drm, m);
78 		if (!mode) {
79 			dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
80 				m->hdisplay, m->vdisplay, m->vrefresh);
81 			continue;
82 		}
83 
84 		drm_mode_set_name(mode);
85 
86 		drm_mode_probed_add(connector, mode);
87 		num++;
88 	}
89 
90 	connector->display_info.width_mm = panel->desc->size.width;
91 	connector->display_info.height_mm = panel->desc->size.height;
92 
93 	return num;
94 }
95 
96 static int panel_simple_disable(struct drm_panel *panel)
97 {
98 	struct panel_simple *p = to_panel_simple(panel);
99 
100 	if (!p->enabled)
101 		return 0;
102 
103 	if (p->backlight) {
104 		p->backlight->props.power = FB_BLANK_POWERDOWN;
105 		backlight_update_status(p->backlight);
106 	}
107 
108 	if (p->enable_gpio)
109 		gpiod_set_value_cansleep(p->enable_gpio, 0);
110 
111 	regulator_disable(p->supply);
112 	p->enabled = false;
113 
114 	return 0;
115 }
116 
117 static int panel_simple_enable(struct drm_panel *panel)
118 {
119 	struct panel_simple *p = to_panel_simple(panel);
120 	int err;
121 
122 	if (p->enabled)
123 		return 0;
124 
125 	err = regulator_enable(p->supply);
126 	if (err < 0) {
127 		dev_err(panel->dev, "failed to enable supply: %d\n", err);
128 		return err;
129 	}
130 
131 	if (p->enable_gpio)
132 		gpiod_set_value_cansleep(p->enable_gpio, 1);
133 
134 	if (p->backlight) {
135 		p->backlight->props.power = FB_BLANK_UNBLANK;
136 		backlight_update_status(p->backlight);
137 	}
138 
139 	p->enabled = true;
140 
141 	return 0;
142 }
143 
144 static int panel_simple_get_modes(struct drm_panel *panel)
145 {
146 	struct panel_simple *p = to_panel_simple(panel);
147 	int num = 0;
148 
149 	/* probe EDID if a DDC bus is available */
150 	if (p->ddc) {
151 		struct edid *edid = drm_get_edid(panel->connector, p->ddc);
152 		drm_mode_connector_update_edid_property(panel->connector, edid);
153 		if (edid) {
154 			num += drm_add_edid_modes(panel->connector, edid);
155 			kfree(edid);
156 		}
157 	}
158 
159 	/* add hard-coded panel modes */
160 	num += panel_simple_get_fixed_modes(p);
161 
162 	return num;
163 }
164 
165 static const struct drm_panel_funcs panel_simple_funcs = {
166 	.disable = panel_simple_disable,
167 	.enable = panel_simple_enable,
168 	.get_modes = panel_simple_get_modes,
169 };
170 
171 static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
172 {
173 	struct device_node *backlight, *ddc;
174 	struct panel_simple *panel;
175 	int err;
176 
177 	panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
178 	if (!panel)
179 		return -ENOMEM;
180 
181 	panel->enabled = false;
182 	panel->desc = desc;
183 
184 	panel->supply = devm_regulator_get(dev, "power");
185 	if (IS_ERR(panel->supply))
186 		return PTR_ERR(panel->supply);
187 
188 	panel->enable_gpio = devm_gpiod_get(dev, "enable");
189 	if (IS_ERR(panel->enable_gpio)) {
190 		err = PTR_ERR(panel->enable_gpio);
191 		if (err != -ENOENT) {
192 			dev_err(dev, "failed to request GPIO: %d\n", err);
193 			return err;
194 		}
195 
196 		panel->enable_gpio = NULL;
197 	} else {
198 		err = gpiod_direction_output(panel->enable_gpio, 0);
199 		if (err < 0) {
200 			dev_err(dev, "failed to setup GPIO: %d\n", err);
201 			return err;
202 		}
203 	}
204 
205 	backlight = of_parse_phandle(dev->of_node, "backlight", 0);
206 	if (backlight) {
207 		panel->backlight = of_find_backlight_by_node(backlight);
208 		of_node_put(backlight);
209 
210 		if (!panel->backlight)
211 			return -EPROBE_DEFER;
212 	}
213 
214 	ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
215 	if (ddc) {
216 		panel->ddc = of_find_i2c_adapter_by_node(ddc);
217 		of_node_put(ddc);
218 
219 		if (!panel->ddc) {
220 			err = -EPROBE_DEFER;
221 			goto free_backlight;
222 		}
223 	}
224 
225 	drm_panel_init(&panel->base);
226 	panel->base.dev = dev;
227 	panel->base.funcs = &panel_simple_funcs;
228 
229 	err = drm_panel_add(&panel->base);
230 	if (err < 0)
231 		goto free_ddc;
232 
233 	dev_set_drvdata(dev, panel);
234 
235 	return 0;
236 
237 free_ddc:
238 	if (panel->ddc)
239 		put_device(&panel->ddc->dev);
240 free_backlight:
241 	if (panel->backlight)
242 		put_device(&panel->backlight->dev);
243 
244 	return err;
245 }
246 
247 static int panel_simple_remove(struct device *dev)
248 {
249 	struct panel_simple *panel = dev_get_drvdata(dev);
250 
251 	drm_panel_detach(&panel->base);
252 	drm_panel_remove(&panel->base);
253 
254 	panel_simple_disable(&panel->base);
255 
256 	if (panel->ddc)
257 		put_device(&panel->ddc->dev);
258 
259 	if (panel->backlight)
260 		put_device(&panel->backlight->dev);
261 
262 	return 0;
263 }
264 
265 static const struct drm_display_mode auo_b101aw03_mode = {
266 	.clock = 51450,
267 	.hdisplay = 1024,
268 	.hsync_start = 1024 + 156,
269 	.hsync_end = 1024 + 156 + 8,
270 	.htotal = 1024 + 156 + 8 + 156,
271 	.vdisplay = 600,
272 	.vsync_start = 600 + 16,
273 	.vsync_end = 600 + 16 + 6,
274 	.vtotal = 600 + 16 + 6 + 16,
275 	.vrefresh = 60,
276 };
277 
278 static const struct panel_desc auo_b101aw03 = {
279 	.modes = &auo_b101aw03_mode,
280 	.num_modes = 1,
281 	.size = {
282 		.width = 223,
283 		.height = 125,
284 	},
285 };
286 
287 static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
288 	.clock = 72070,
289 	.hdisplay = 1366,
290 	.hsync_start = 1366 + 58,
291 	.hsync_end = 1366 + 58 + 58,
292 	.htotal = 1366 + 58 + 58 + 58,
293 	.vdisplay = 768,
294 	.vsync_start = 768 + 4,
295 	.vsync_end = 768 + 4 + 4,
296 	.vtotal = 768 + 4 + 4 + 4,
297 	.vrefresh = 60,
298 };
299 
300 static const struct panel_desc chunghwa_claa101wa01a = {
301 	.modes = &chunghwa_claa101wa01a_mode,
302 	.num_modes = 1,
303 	.size = {
304 		.width = 220,
305 		.height = 120,
306 	},
307 };
308 
309 static const struct drm_display_mode chunghwa_claa101wb01_mode = {
310 	.clock = 69300,
311 	.hdisplay = 1366,
312 	.hsync_start = 1366 + 48,
313 	.hsync_end = 1366 + 48 + 32,
314 	.htotal = 1366 + 48 + 32 + 20,
315 	.vdisplay = 768,
316 	.vsync_start = 768 + 16,
317 	.vsync_end = 768 + 16 + 8,
318 	.vtotal = 768 + 16 + 8 + 16,
319 	.vrefresh = 60,
320 };
321 
322 static const struct panel_desc chunghwa_claa101wb01 = {
323 	.modes = &chunghwa_claa101wb01_mode,
324 	.num_modes = 1,
325 	.size = {
326 		.width = 223,
327 		.height = 125,
328 	},
329 };
330 
331 static const struct drm_display_mode lg_lp129qe_mode = {
332 	.clock = 285250,
333 	.hdisplay = 2560,
334 	.hsync_start = 2560 + 48,
335 	.hsync_end = 2560 + 48 + 32,
336 	.htotal = 2560 + 48 + 32 + 80,
337 	.vdisplay = 1700,
338 	.vsync_start = 1700 + 3,
339 	.vsync_end = 1700 + 3 + 10,
340 	.vtotal = 1700 + 3 + 10 + 36,
341 	.vrefresh = 60,
342 };
343 
344 static const struct panel_desc lg_lp129qe = {
345 	.modes = &lg_lp129qe_mode,
346 	.num_modes = 1,
347 	.size = {
348 		.width = 272,
349 		.height = 181,
350 	},
351 };
352 
353 static const struct drm_display_mode samsung_ltn101nt05_mode = {
354 	.clock = 54030,
355 	.hdisplay = 1024,
356 	.hsync_start = 1024 + 24,
357 	.hsync_end = 1024 + 24 + 136,
358 	.htotal = 1024 + 24 + 136 + 160,
359 	.vdisplay = 600,
360 	.vsync_start = 600 + 3,
361 	.vsync_end = 600 + 3 + 6,
362 	.vtotal = 600 + 3 + 6 + 61,
363 	.vrefresh = 60,
364 };
365 
366 static const struct panel_desc samsung_ltn101nt05 = {
367 	.modes = &samsung_ltn101nt05_mode,
368 	.num_modes = 1,
369 	.size = {
370 		.width = 1024,
371 		.height = 600,
372 	},
373 };
374 
375 static const struct of_device_id platform_of_match[] = {
376 	{
377 		.compatible = "auo,b101aw03",
378 		.data = &auo_b101aw03,
379 	}, {
380 		.compatible = "chunghwa,claa101wa01a",
381 		.data = &chunghwa_claa101wa01a
382 	}, {
383 		.compatible = "chunghwa,claa101wb01",
384 		.data = &chunghwa_claa101wb01
385 	}, {
386 		.compatible = "lg,lp129qe",
387 		.data = &lg_lp129qe,
388 	}, {
389 		.compatible = "samsung,ltn101nt05",
390 		.data = &samsung_ltn101nt05,
391 	}, {
392 		.compatible = "simple-panel",
393 	}, {
394 		/* sentinel */
395 	}
396 };
397 MODULE_DEVICE_TABLE(of, platform_of_match);
398 
399 static int panel_simple_platform_probe(struct platform_device *pdev)
400 {
401 	const struct of_device_id *id;
402 
403 	id = of_match_node(platform_of_match, pdev->dev.of_node);
404 	if (!id)
405 		return -ENODEV;
406 
407 	return panel_simple_probe(&pdev->dev, id->data);
408 }
409 
410 static int panel_simple_platform_remove(struct platform_device *pdev)
411 {
412 	return panel_simple_remove(&pdev->dev);
413 }
414 
415 static struct platform_driver panel_simple_platform_driver = {
416 	.driver = {
417 		.name = "panel-simple",
418 		.owner = THIS_MODULE,
419 		.of_match_table = platform_of_match,
420 	},
421 	.probe = panel_simple_platform_probe,
422 	.remove = panel_simple_platform_remove,
423 };
424 
425 struct panel_desc_dsi {
426 	struct panel_desc desc;
427 
428 	unsigned long flags;
429 	enum mipi_dsi_pixel_format format;
430 	unsigned int lanes;
431 };
432 
433 static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
434 	.clock = 71000,
435 	.hdisplay = 800,
436 	.hsync_start = 800 + 32,
437 	.hsync_end = 800 + 32 + 1,
438 	.htotal = 800 + 32 + 1 + 57,
439 	.vdisplay = 1280,
440 	.vsync_start = 1280 + 28,
441 	.vsync_end = 1280 + 28 + 1,
442 	.vtotal = 1280 + 28 + 1 + 14,
443 	.vrefresh = 60,
444 };
445 
446 static const struct panel_desc_dsi lg_ld070wx3_sl01 = {
447 	.desc = {
448 		.modes = &lg_ld070wx3_sl01_mode,
449 		.num_modes = 1,
450 		.size = {
451 			.width = 94,
452 			.height = 151,
453 		},
454 	},
455 	.flags = MIPI_DSI_MODE_VIDEO,
456 	.format = MIPI_DSI_FMT_RGB888,
457 	.lanes = 4,
458 };
459 
460 static const struct drm_display_mode lg_lh500wx1_sd03_mode = {
461 	.clock = 67000,
462 	.hdisplay = 720,
463 	.hsync_start = 720 + 12,
464 	.hsync_end = 720 + 12 + 4,
465 	.htotal = 720 + 12 + 4 + 112,
466 	.vdisplay = 1280,
467 	.vsync_start = 1280 + 8,
468 	.vsync_end = 1280 + 8 + 4,
469 	.vtotal = 1280 + 8 + 4 + 12,
470 	.vrefresh = 60,
471 };
472 
473 static const struct panel_desc_dsi lg_lh500wx1_sd03 = {
474 	.desc = {
475 		.modes = &lg_lh500wx1_sd03_mode,
476 		.num_modes = 1,
477 		.size = {
478 			.width = 62,
479 			.height = 110,
480 		},
481 	},
482 	.flags = MIPI_DSI_MODE_VIDEO,
483 	.format = MIPI_DSI_FMT_RGB888,
484 	.lanes = 4,
485 };
486 
487 static const struct drm_display_mode panasonic_vvx10f004b00_mode = {
488 	.clock = 157200,
489 	.hdisplay = 1920,
490 	.hsync_start = 1920 + 154,
491 	.hsync_end = 1920 + 154 + 16,
492 	.htotal = 1920 + 154 + 16 + 32,
493 	.vdisplay = 1200,
494 	.vsync_start = 1200 + 17,
495 	.vsync_end = 1200 + 17 + 2,
496 	.vtotal = 1200 + 17 + 2 + 16,
497 	.vrefresh = 60,
498 };
499 
500 static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
501 	.desc = {
502 		.modes = &panasonic_vvx10f004b00_mode,
503 		.num_modes = 1,
504 		.size = {
505 			.width = 217,
506 			.height = 136,
507 		},
508 	},
509 	.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
510 	.format = MIPI_DSI_FMT_RGB888,
511 	.lanes = 4,
512 };
513 
514 static const struct of_device_id dsi_of_match[] = {
515 	{
516 		.compatible = "lg,ld070wx3-sl01",
517 		.data = &lg_ld070wx3_sl01
518 	}, {
519 		.compatible = "lg,lh500wx1-sd03",
520 		.data = &lg_lh500wx1_sd03
521 	}, {
522 		.compatible = "panasonic,vvx10f004b00",
523 		.data = &panasonic_vvx10f004b00
524 	}, {
525 		/* sentinel */
526 	}
527 };
528 MODULE_DEVICE_TABLE(of, dsi_of_match);
529 
530 static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
531 {
532 	const struct panel_desc_dsi *desc;
533 	const struct of_device_id *id;
534 	int err;
535 
536 	id = of_match_node(dsi_of_match, dsi->dev.of_node);
537 	if (!id)
538 		return -ENODEV;
539 
540 	desc = id->data;
541 
542 	err = panel_simple_probe(&dsi->dev, &desc->desc);
543 	if (err < 0)
544 		return err;
545 
546 	dsi->mode_flags = desc->flags;
547 	dsi->format = desc->format;
548 	dsi->lanes = desc->lanes;
549 
550 	return mipi_dsi_attach(dsi);
551 }
552 
553 static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
554 {
555 	int err;
556 
557 	err = mipi_dsi_detach(dsi);
558 	if (err < 0)
559 		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
560 
561 	return panel_simple_remove(&dsi->dev);
562 }
563 
564 static struct mipi_dsi_driver panel_simple_dsi_driver = {
565 	.driver = {
566 		.name = "panel-simple-dsi",
567 		.owner = THIS_MODULE,
568 		.of_match_table = dsi_of_match,
569 	},
570 	.probe = panel_simple_dsi_probe,
571 	.remove = panel_simple_dsi_remove,
572 };
573 
574 static int __init panel_simple_init(void)
575 {
576 	int err;
577 
578 	err = platform_driver_register(&panel_simple_platform_driver);
579 	if (err < 0)
580 		return err;
581 
582 	if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
583 		err = mipi_dsi_driver_register(&panel_simple_dsi_driver);
584 		if (err < 0)
585 			return err;
586 	}
587 
588 	return 0;
589 }
590 module_init(panel_simple_init);
591 
592 static void __exit panel_simple_exit(void)
593 {
594 	if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
595 		mipi_dsi_driver_unregister(&panel_simple_dsi_driver);
596 
597 	platform_driver_unregister(&panel_simple_platform_driver);
598 }
599 module_exit(panel_simple_exit);
600 
601 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
602 MODULE_DESCRIPTION("DRM Driver for Simple Panels");
603 MODULE_LICENSE("GPL and additional rights");
604