xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/panel/panel-maxim-max96752f.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Maxim MAX96752F GMSL2 Deserializer
4  *
5  * Copyright (C) 2022 Rockchip Electronics Co. Ltd.
6  */
7 
8 #include <linux/backlight.h>
9 #include <linux/delay.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/of_platform.h>
12 #include <linux/pinctrl/consumer.h>
13 #include <linux/i2c.h>
14 #include <linux/module.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/of.h>
18 
19 #include <video/videomode.h>
20 #include <video/of_display_timing.h>
21 #include <video/display_timing.h>
22 #include <uapi/linux/media-bus-format.h>
23 
24 #include <drm/drm_device.h>
25 #include <drm/drm_modes.h>
26 #include <drm/drm_panel.h>
27 
28 struct max96752f;
29 
30 struct panel_desc {
31 	const char *name;
32 	u32 width_mm;
33 	u32 height_mm;
34 
35 	int (*prepare)(struct max96752f *max96752f);
36 	int (*unprepare)(struct max96752f *max96752f);
37 	int (*enable)(struct max96752f *max96752f);
38 	int (*disable)(struct max96752f *max96752f);
39 	int (*backlight_enable)(struct max96752f *max96752f);
40 	int (*backlight_disable)(struct max96752f *max96752f);
41 };
42 
43 struct max96752f {
44 	struct drm_panel panel;
45 	struct device *dev;
46 	struct {
47 		struct regmap *serializer;
48 		struct regmap *deserializer;
49 	} regmap;
50 	struct regulator *supply;
51 	struct backlight_device *backlight;
52 	struct drm_display_mode mode;
53 	const struct panel_desc *desc;
54 };
55 
to_max96752f(struct drm_panel * panel)56 static inline struct max96752f *to_max96752f(struct drm_panel *panel)
57 {
58 	return container_of(panel, struct max96752f, panel);
59 }
60 
max96752f_panel_disable(struct drm_panel * panel)61 static int max96752f_panel_disable(struct drm_panel *panel)
62 {
63 	struct max96752f *max96752f = to_max96752f(panel);
64 	const struct panel_desc *desc = max96752f->desc;
65 
66 	if (desc->backlight_disable)
67 		desc->backlight_disable(max96752f);
68 
69 	backlight_disable(max96752f->backlight);
70 
71 	if (desc->disable)
72 		desc->disable(max96752f);
73 
74 	return 0;
75 }
76 
max96752f_panel_enable(struct drm_panel * panel)77 static int max96752f_panel_enable(struct drm_panel *panel)
78 {
79 	struct max96752f *max96752f = to_max96752f(panel);
80 	const struct panel_desc *desc = max96752f->desc;
81 
82 	if (desc->enable)
83 		desc->enable(max96752f);
84 
85 	backlight_enable(max96752f->backlight);
86 
87 	if (desc->backlight_enable)
88 		desc->backlight_enable(max96752f);
89 
90 	return 0;
91 }
92 
max96752f_panel_unprepare(struct drm_panel * panel)93 static int max96752f_panel_unprepare(struct drm_panel *panel)
94 {
95 	struct max96752f *max96752f = to_max96752f(panel);
96 	const struct panel_desc *desc = max96752f->desc;
97 
98 	if (desc->unprepare)
99 		desc->unprepare(max96752f);
100 
101 	pinctrl_pm_select_sleep_state(max96752f->dev);
102 
103 	return 0;
104 }
105 
max96752f_panel_prepare(struct drm_panel * panel)106 static int max96752f_panel_prepare(struct drm_panel *panel)
107 {
108 	struct max96752f *max96752f = to_max96752f(panel);
109 	const struct panel_desc *desc = max96752f->desc;
110 
111 	pinctrl_pm_select_default_state(max96752f->dev);
112 
113 	if (desc->prepare)
114 		desc->prepare(max96752f);
115 
116 	return 0;
117 }
118 
max96752f_panel_get_modes(struct drm_panel * panel,struct drm_connector * connector)119 static int max96752f_panel_get_modes(struct drm_panel *panel,
120 				     struct drm_connector *connector)
121 {
122 	struct max96752f *max96752f = to_max96752f(panel);
123 	const struct panel_desc *desc = max96752f->desc;
124 	struct drm_display_mode *mode;
125 	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
126 
127 	connector->display_info.width_mm = desc->width_mm;
128 	connector->display_info.height_mm = desc->height_mm;
129 	drm_display_info_set_bus_formats(&connector->display_info, &bus_format, 1);
130 
131 	mode = drm_mode_duplicate(connector->dev, &max96752f->mode);
132 	mode->width_mm = desc->width_mm;
133 	mode->height_mm = desc->height_mm;
134 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
135 
136 	drm_mode_set_name(mode);
137 	drm_mode_probed_add(connector, mode);
138 
139 	return 1;
140 }
141 
142 static const struct drm_panel_funcs max96752f_panel_funcs = {
143 	.disable = max96752f_panel_disable,
144 	.unprepare = max96752f_panel_unprepare,
145 	.prepare = max96752f_panel_prepare,
146 	.enable = max96752f_panel_enable,
147 	.get_modes = max96752f_panel_get_modes,
148 };
149 
max96752f_parse_dt(struct max96752f * max96752f)150 static int max96752f_parse_dt(struct max96752f *max96752f)
151 {
152 	struct device *dev = max96752f->dev;
153 	struct display_timing dt;
154 	struct videomode vm;
155 	int ret;
156 
157 	ret = of_get_display_timing(dev->of_node, "panel-timing", &dt);
158 	if (ret < 0) {
159 		dev_err(dev, "%pOF: no panel-timing node found\n", dev->of_node);
160 		return ret;
161 	}
162 
163 	videomode_from_timing(&dt, &vm);
164 	drm_display_mode_from_videomode(&vm, &max96752f->mode);
165 
166 	return 0;
167 }
168 
169 static const struct regmap_range max96752f_readable_ranges[] = {
170 	regmap_reg_range(0x0000, 0x0600),
171 };
172 
173 static const struct regmap_access_table max96752f_readable_table = {
174 	.yes_ranges = max96752f_readable_ranges,
175 	.n_yes_ranges = ARRAY_SIZE(max96752f_readable_ranges),
176 };
177 
178 static const struct regmap_config max96752f_regmap_config = {
179 	.name = "max96752f",
180 	.reg_bits = 16,
181 	.val_bits = 8,
182 	.max_register = 0xffff,
183 	.rd_table = &max96752f_readable_table,
184 };
185 
max96752f_power_off(void * data)186 static void max96752f_power_off(void *data)
187 {
188 	struct max96752f *max96752f = data;
189 
190 	if (max96752f->supply)
191 		regulator_disable(max96752f->supply);
192 }
193 
max96752f_power_on(struct max96752f * max96752f)194 static void max96752f_power_on(struct max96752f *max96752f)
195 {
196 	int ret;
197 
198 	if (max96752f->supply) {
199 		ret = regulator_enable(max96752f->supply);
200 		if (ret)
201 			dev_err(max96752f->dev,
202 				"failed to enable power supply: %d\n", ret);
203 	}
204 }
205 
max96752f_probe(struct i2c_client * client)206 static int max96752f_probe(struct i2c_client *client)
207 {
208 	struct device *dev = &client->dev;
209 	struct max96752f *max96752f;
210 	struct i2c_client *parent;
211 	int ret;
212 
213 	max96752f = devm_kzalloc(dev, sizeof(*max96752f), GFP_KERNEL);
214 	if (!max96752f)
215 		return -ENOMEM;
216 
217 	max96752f->dev = dev;
218 	max96752f->desc = of_device_get_match_data(dev);
219 	i2c_set_clientdata(client, max96752f);
220 
221 	max96752f->supply = devm_regulator_get_optional(dev, "power");
222 	if (IS_ERR(max96752f->supply)) {
223 		if (PTR_ERR(max96752f->supply) != -ENODEV)
224 			return dev_err_probe(dev, PTR_ERR(max96752f->supply),
225 					     "failed to get regulator\n");
226 
227 		max96752f->supply = NULL;
228 	} else {
229 		ret = regulator_enable(max96752f->supply);
230 		if (ret) {
231 			dev_err(dev, "failed to enable power supply: %d\n", ret);
232 			return ret;
233 		}
234 
235 		ret = devm_add_action_or_reset(dev, max96752f_power_off, max96752f);
236 		if (ret) {
237 			regulator_disable(max96752f->supply);
238 			return ret;
239 		}
240 	}
241 
242 	max96752f->regmap.deserializer =
243 			devm_regmap_init_i2c(client, &max96752f_regmap_config);
244 	if (IS_ERR(max96752f->regmap.deserializer))
245 		return dev_err_probe(dev, PTR_ERR(max96752f->regmap.deserializer),
246 				     "failed to initialize deserializer regmap\n");
247 
248 	parent = of_find_i2c_device_by_node(dev->of_node->parent->parent);
249 	if (!parent)
250 		return dev_err_probe(dev, -ENODEV, "failed to find parent\n");
251 
252 	max96752f->regmap.serializer = dev_get_regmap(&parent->dev, NULL);
253 	if (!max96752f->regmap.serializer)
254 		return dev_err_probe(dev, -ENODEV,
255 				     "failed to initialize serializer regmap\n");
256 
257 	ret = max96752f_parse_dt(max96752f);
258 	if (ret)
259 		return dev_err_probe(dev, ret, "failed to parse DT\n");
260 
261 	max96752f->backlight = devm_of_find_backlight(dev);
262 	if (IS_ERR(max96752f->backlight))
263 		return dev_err_probe(dev, PTR_ERR(max96752f->backlight),
264 				     "failed to get backlight\n");
265 
266 	drm_panel_init(&max96752f->panel, dev, &max96752f_panel_funcs,
267 		       DRM_MODE_CONNECTOR_LVDS);
268 	drm_panel_add(&max96752f->panel);
269 
270 	return 0;
271 }
272 
max96752f_remove(struct i2c_client * client)273 static int max96752f_remove(struct i2c_client *client)
274 {
275 	struct max96752f *max96752f = i2c_get_clientdata(client);
276 
277 	drm_panel_remove(&max96752f->panel);
278 
279 	return 0;
280 }
281 
max96752f_suspend(struct device * dev)282 static int __maybe_unused max96752f_suspend(struct device *dev)
283 {
284 	struct max96752f *max96752f = dev_get_drvdata(dev);
285 
286 	max96752f_power_off(max96752f);
287 
288 	return 0;
289 }
290 
max96752f_resume(struct device * dev)291 static int __maybe_unused max96752f_resume(struct device *dev)
292 {
293 	struct max96752f *max96752f = dev_get_drvdata(dev);
294 
295 	max96752f_power_on(max96752f);
296 
297 	return 0;
298 }
299 
300 static SIMPLE_DEV_PM_OPS(max96752f_pm_ops, max96752f_suspend, max96752f_resume);
301 
302 #define maxim_serializer_write(max96752f, reg, val) do {		\
303 		int ret;						\
304 		ret = regmap_write(max96752f->regmap.serializer,	\
305 				   reg, val);				\
306 		if (ret)						\
307 			return ret;					\
308 	} while (0)
309 
310 #define maxim_serializer_read(max96752f, reg, val) do {			\
311 		int ret;						\
312 		ret = regmap_read(max96752f->regmap.serializer,		\
313 				  reg, val);				\
314 		if (ret)                                                \
315 			return ret;                                     \
316 	} while (0)
317 
318 #define maxim_deserializer_write(max96752f, reg, val) do {		\
319 		int ret;						\
320 		ret = regmap_write(max96752f->regmap.deserializer,	\
321 				   reg, val);				\
322 		if (ret)						\
323 			return ret;					\
324 	} while (0)
325 
326 #define maxim_deserializer_read(max96752f, reg, val) do {		\
327 		int ret;						\
328 		ret = regmap_read(max96752f->regmap.deserializer,	\
329 				  reg, val);				\
330 		if (ret)                                                \
331 			return ret;                                     \
332 	} while (0)
333 
boe_av156fht_l83_prepare(struct max96752f * max96752f)334 static int boe_av156fht_l83_prepare(struct max96752f *max96752f)
335 {
336 	maxim_deserializer_write(max96752f, 0x0002, 0x43);
337 	maxim_deserializer_write(max96752f, 0x0140, 0x20);
338 
339 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);	/* oldi */
340 	maxim_deserializer_write(max96752f, 0x020e, 0x40);	/* bl_pwm */
341 	maxim_deserializer_write(max96752f, 0x020c, 0x84);
342 	maxim_deserializer_write(max96752f, 0x0207, 0xa1);	/* tp_int */
343 	maxim_deserializer_write(max96752f, 0x0206, 0x83);
344 
345 	maxim_deserializer_write(max96752f, 0x0215, 0x90);	/* lcd_en */
346 	msleep(20);
347 
348 	return 0;
349 }
350 
boe_av156fht_l83_unprepare(struct max96752f * max96752f)351 static int boe_av156fht_l83_unprepare(struct max96752f *max96752f)
352 {
353 	maxim_deserializer_write(max96752f, 0x0215, 0x80);	/* lcd_en */
354 
355 	return 0;
356 }
357 
boe_av156fht_l83_enable(struct max96752f * max96752f)358 static int boe_av156fht_l83_enable(struct max96752f *max96752f)
359 {
360 	maxim_deserializer_write(max96752f, 0x0227, 0x90);	/* lcd_rst */
361 	msleep(20);
362 	maxim_deserializer_write(max96752f, 0x020f, 0x90);	/* tp_rst */
363 	msleep(100);
364 	maxim_deserializer_write(max96752f, 0x0221, 0x90);	/* lcd_stb */
365 	msleep(60);
366 
367 	return 0;
368 }
369 
boe_av156fht_l83_disable(struct max96752f * max96752f)370 static int boe_av156fht_l83_disable(struct max96752f *max96752f)
371 {
372 	maxim_deserializer_write(max96752f, 0x0221, 0x80);	/* lcd_stb */
373 	maxim_deserializer_write(max96752f, 0x020f, 0x80);	/* tp_rst */
374 	maxim_deserializer_write(max96752f, 0x0227, 0x80);	/* lcd_rst */
375 
376 	return 0;
377 }
378 
boe_av156fht_l83_backlight_enable(struct max96752f * max96752f)379 static int boe_av156fht_l83_backlight_enable(struct max96752f *max96752f)
380 {
381 	maxim_deserializer_write(max96752f, 0x0212, 0x90);	/* bl_current_ctl */
382 	maxim_deserializer_write(max96752f, 0x0209, 0x90);	/* bl_en */
383 
384 	return 0;
385 }
386 
boe_av156fht_l83_backlight_disable(struct max96752f * max96752f)387 static int boe_av156fht_l83_backlight_disable(struct max96752f *max96752f)
388 {
389 	maxim_deserializer_write(max96752f, 0x0209, 0x80);	/* bl_en */
390 	maxim_deserializer_write(max96752f, 0x0212, 0x80);	/* bl_current_ctl */
391 
392 	return 0;
393 }
394 
395 static const struct panel_desc boe_av156fht_l83 = {
396 	.name			= "boe-av156fht-l83",
397 	.width_mm		= 346,
398 	.height_mm		= 194,
399 	.prepare		= boe_av156fht_l83_prepare,
400 	.unprepare		= boe_av156fht_l83_unprepare,
401 	.enable			= boe_av156fht_l83_enable,
402 	.disable		= boe_av156fht_l83_disable,
403 	.backlight_enable	= boe_av156fht_l83_backlight_enable,
404 	.backlight_disable	= boe_av156fht_l83_backlight_disable,
405 };
406 
hannstar_hsd123jpw3_a15_prepare(struct max96752f * max96752f)407 static int hannstar_hsd123jpw3_a15_prepare(struct max96752f *max96752f)
408 {
409 	maxim_deserializer_write(max96752f, 0x0002, 0x43);
410 	maxim_deserializer_write(max96752f, 0x0140, 0x20);
411 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);
412 
413 	maxim_deserializer_write(max96752f, 0x0203, 0x83);	/* GPIO1  <- TP_INT */
414 	maxim_deserializer_write(max96752f, 0x0206, 0x84);      /* GPIO2  -> TP_RST */
415 	maxim_deserializer_write(max96752f, 0x0224, 0x84);	/* GPIO12 -> LCD_BL_PWM */
416 
417 	return 0;
418 }
419 
hannstar_hsd123jpw3_a15_unprepare(struct max96752f * max96752f)420 static int hannstar_hsd123jpw3_a15_unprepare(struct max96752f *max96752f)
421 {
422 	return 0;
423 }
424 
hannstar_hsd123jpw3_a15_enable(struct max96752f * max96752f)425 static int hannstar_hsd123jpw3_a15_enable(struct max96752f *max96752f)
426 {
427 	maxim_deserializer_write(max96752f, 0x0221, 0x90);	/* GPIO11 -> LCD_RESET */
428 	msleep(20);
429 
430 	return 0;
431 }
432 
hannstar_hsd123jpw3_a15_disable(struct max96752f * max96752f)433 static int hannstar_hsd123jpw3_a15_disable(struct max96752f *max96752f)
434 {
435 	maxim_deserializer_write(max96752f, 0x0221, 0x80);	/* GPIO11 -> LCD_RESET */
436 	msleep(20);
437 
438 	return 0;
439 }
440 
441 static const struct panel_desc hannstar_hsd123jpw3_a15 = {
442 	.name			= "hannstar,hsd123jpw3-a15",
443 	.width_mm		= 292,
444 	.height_mm		= 110,
445 	.prepare		= hannstar_hsd123jpw3_a15_prepare,
446 	.unprepare		= hannstar_hsd123jpw3_a15_unprepare,
447 	.enable			= hannstar_hsd123jpw3_a15_enable,
448 	.disable		= hannstar_hsd123jpw3_a15_disable,
449 };
450 
ogm_101fhbllm01_prepare(struct max96752f * max96752f)451 static int ogm_101fhbllm01_prepare(struct max96752f *max96752f)
452 {
453 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);
454 
455 	maxim_deserializer_write(max96752f, 0x0203, 0x84);	/* GPIO1 -> BL_PWM */
456 	maxim_deserializer_write(max96752f, 0x0206, 0x84);	/* GPIO2 -> TP_RST */
457 	maxim_deserializer_write(max96752f, 0x0209, 0x83);	/* GPIO3 <- TP_INT */
458 
459 	maxim_deserializer_write(max96752f, 0x0001, 0x02);
460 
461 	return 0;
462 }
463 
ogm_101fhbllm01_unprepare(struct max96752f * max96752f)464 static int ogm_101fhbllm01_unprepare(struct max96752f *max96752f)
465 {
466 	maxim_deserializer_write(max96752f, 0x0001, 0x01);
467 
468 	return 0;
469 }
470 
471 static const struct panel_desc ogm_101fhbllm01 = {
472 	.name			= "ogm,101fhbllm01",
473 	.width_mm		= 126,
474 	.height_mm		= 223,
475 	.prepare		= ogm_101fhbllm01_prepare,
476 	.unprepare		= ogm_101fhbllm01_unprepare,
477 };
478 
479 static const struct of_device_id max96752f_of_match[] = {
480 	{ .compatible = "boe,av156fht-l83", &boe_av156fht_l83 },
481 	{ .compatible = "hannstar,hsd123jpw3-a15", &hannstar_hsd123jpw3_a15 },
482 	{ .compatible = "ogm,101fhbllm01", &ogm_101fhbllm01 },
483 	{ }
484 };
485 MODULE_DEVICE_TABLE(of, max96752f_of_match);
486 
487 static struct i2c_driver max96752f_driver = {
488 	.driver = {
489 		.name = "panel-maxim-max96752f",
490 		.of_match_table = max96752f_of_match,
491 		.pm = &max96752f_pm_ops,
492 	},
493 	.probe_new = max96752f_probe,
494 	.remove = max96752f_remove,
495 };
496 
497 module_i2c_driver(max96752f_driver);
498 
499 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
500 MODULE_DESCRIPTION("Maxim MAX96752F based panel driver");
501 MODULE_LICENSE("GPL");
502