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