xref: /rk3399_rockchip-uboot/drivers/video/drm/panel-maxim-max96752f.c (revision f03ca6ff4608138e19593643a7f840541cb1b34f)
156e08688SWyon Bi // SPDX-License-Identifier: GPL-2.0+
256e08688SWyon Bi /*
356e08688SWyon Bi  * Maxim MAX96752F GMSL2 Deserializer
456e08688SWyon Bi  *
556e08688SWyon Bi  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
656e08688SWyon Bi  */
756e08688SWyon Bi 
856e08688SWyon Bi #include <config.h>
956e08688SWyon Bi #include <common.h>
1056e08688SWyon Bi #include <backlight.h>
1156e08688SWyon Bi #include <errno.h>
1256e08688SWyon Bi #include <malloc.h>
1356e08688SWyon Bi #include <video.h>
1456e08688SWyon Bi 
1556e08688SWyon Bi #include <asm/gpio.h>
1656e08688SWyon Bi #include <dm/device.h>
1756e08688SWyon Bi #include <dm/read.h>
1856e08688SWyon Bi #include <dm/pinctrl.h>
1956e08688SWyon Bi #include <dm/uclass-id.h>
2056e08688SWyon Bi #include <linux/media-bus-format.h>
2156e08688SWyon Bi 
2256e08688SWyon Bi #include "rockchip_display.h"
2356e08688SWyon Bi #include "rockchip_panel.h"
2456e08688SWyon Bi 
2556e08688SWyon Bi struct max96752f;
2656e08688SWyon Bi 
2756e08688SWyon Bi struct panel_desc {
2856e08688SWyon Bi 	const char *name;
2956e08688SWyon Bi 	int (*prepare)(struct max96752f *max96752f);
3056e08688SWyon Bi 	int (*unprepare)(struct max96752f *max96752f);
3156e08688SWyon Bi 	int (*enable)(struct max96752f *max96752f);
3256e08688SWyon Bi 	int (*disable)(struct max96752f *max96752f);
3356e08688SWyon Bi 	int (*backlight_enable)(struct max96752f *max96752f);
3456e08688SWyon Bi 	int (*backlight_disable)(struct max96752f *max96752f);
3556e08688SWyon Bi };
3656e08688SWyon Bi 
3756e08688SWyon Bi struct max96752f {
3856e08688SWyon Bi 	struct udevice *dev;
3956e08688SWyon Bi 	struct udevice *serializer;
4056e08688SWyon Bi 	struct udevice *backlight;
4156e08688SWyon Bi 
4256e08688SWyon Bi 	const struct panel_desc *desc;
4356e08688SWyon Bi };
4456e08688SWyon Bi 
max96752f_panel_prepare(struct rockchip_panel * panel)4556e08688SWyon Bi static void max96752f_panel_prepare(struct rockchip_panel *panel)
4656e08688SWyon Bi {
4756e08688SWyon Bi 	struct max96752f *max96752f = dev_get_priv(panel->dev);
4856e08688SWyon Bi 	const struct panel_desc *desc = max96752f->desc;
4956e08688SWyon Bi 
5056e08688SWyon Bi 	if (desc->prepare)
5156e08688SWyon Bi 		desc->prepare(max96752f);
5256e08688SWyon Bi }
5356e08688SWyon Bi 
max96752f_panel_unprepare(struct rockchip_panel * panel)5456e08688SWyon Bi static void max96752f_panel_unprepare(struct rockchip_panel *panel)
5556e08688SWyon Bi {
5656e08688SWyon Bi 	struct max96752f *max96752f = dev_get_priv(panel->dev);
5756e08688SWyon Bi 	const struct panel_desc *desc = max96752f->desc;
5856e08688SWyon Bi 
5956e08688SWyon Bi 	if (desc->unprepare)
6056e08688SWyon Bi 		desc->unprepare(max96752f);
6156e08688SWyon Bi }
6256e08688SWyon Bi 
max96752f_panel_enable(struct rockchip_panel * panel)6356e08688SWyon Bi static void max96752f_panel_enable(struct rockchip_panel *panel)
6456e08688SWyon Bi {
6556e08688SWyon Bi 	struct max96752f *max96752f = dev_get_priv(panel->dev);
6656e08688SWyon Bi 	const struct panel_desc *desc = max96752f->desc;
6756e08688SWyon Bi 
6856e08688SWyon Bi 	if (desc->enable)
6956e08688SWyon Bi 		desc->enable(max96752f);
7056e08688SWyon Bi 
7156e08688SWyon Bi 	if (max96752f->backlight)
7256e08688SWyon Bi 		backlight_enable(max96752f->backlight);
7356e08688SWyon Bi 
7456e08688SWyon Bi 	if (desc->backlight_enable)
7556e08688SWyon Bi 		desc->backlight_enable(max96752f);
7656e08688SWyon Bi }
7756e08688SWyon Bi 
max96752f_panel_disable(struct rockchip_panel * panel)7856e08688SWyon Bi static void max96752f_panel_disable(struct rockchip_panel *panel)
7956e08688SWyon Bi {
8056e08688SWyon Bi 	struct max96752f *max96752f = dev_get_priv(panel->dev);
8156e08688SWyon Bi 	const struct panel_desc *desc = max96752f->desc;
8256e08688SWyon Bi 
8356e08688SWyon Bi 	if (desc->backlight_disable)
8456e08688SWyon Bi 		desc->backlight_disable(max96752f);
8556e08688SWyon Bi 
8656e08688SWyon Bi 	if (max96752f->backlight)
8756e08688SWyon Bi 		backlight_disable(max96752f->backlight);
8856e08688SWyon Bi 
8956e08688SWyon Bi 	if (desc->disable)
9056e08688SWyon Bi 		desc->disable(max96752f);
9156e08688SWyon Bi }
9256e08688SWyon Bi 
9356e08688SWyon Bi static const struct rockchip_panel_funcs max96752f_panel_funcs = {
9456e08688SWyon Bi 	.prepare = max96752f_panel_prepare,
9556e08688SWyon Bi 	.unprepare = max96752f_panel_unprepare,
9656e08688SWyon Bi 	.enable = max96752f_panel_enable,
9756e08688SWyon Bi 	.disable = max96752f_panel_disable,
9856e08688SWyon Bi };
9956e08688SWyon Bi 
max96752f_probe(struct udevice * dev)10056e08688SWyon Bi static int max96752f_probe(struct udevice *dev)
10156e08688SWyon Bi {
10256e08688SWyon Bi 	struct max96752f *max96752f = dev_get_priv(dev);
10356e08688SWyon Bi 	struct rockchip_panel *panel;
10456e08688SWyon Bi 	int ret;
10556e08688SWyon Bi 
10656e08688SWyon Bi 	ret = i2c_set_chip_offset_len(dev, 2);
10756e08688SWyon Bi 	if (ret)
10856e08688SWyon Bi 		return ret;
10956e08688SWyon Bi 
11056e08688SWyon Bi 	max96752f->dev = dev;
11156e08688SWyon Bi 	max96752f->serializer = dev->parent->parent;
11256e08688SWyon Bi 	max96752f->desc = (const struct panel_desc *)dev_get_driver_data(dev);
11356e08688SWyon Bi 
11456e08688SWyon Bi 	ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
11556e08688SWyon Bi 					   "backlight", &max96752f->backlight);
11656e08688SWyon Bi 	if (ret && ret != -ENOENT) {
11756e08688SWyon Bi 		dev_err(dev, "%s: Cannot get backlight: %d\n", __func__, ret);
11856e08688SWyon Bi 		return ret;
11956e08688SWyon Bi 	}
12056e08688SWyon Bi 
12156e08688SWyon Bi 	panel = calloc(1, sizeof(*panel));
12256e08688SWyon Bi 	if (!panel)
12356e08688SWyon Bi 		return -ENOMEM;
12456e08688SWyon Bi 
12556e08688SWyon Bi 	dev->driver_data = (ulong)panel;
12656e08688SWyon Bi 	panel->dev = dev;
12756e08688SWyon Bi 	panel->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
12856e08688SWyon Bi 	panel->funcs = &max96752f_panel_funcs;
12956e08688SWyon Bi 
13056e08688SWyon Bi 	return 0;
13156e08688SWyon Bi }
13256e08688SWyon Bi 
13356e08688SWyon Bi #define maxim_serializer_write(max96752f, reg, val) do {	\
13456e08688SWyon Bi 		int ret;					\
13556e08688SWyon Bi 		ret = dm_i2c_reg_write(max96752f->serializer,	\
13656e08688SWyon Bi 				       reg, val);		\
13756e08688SWyon Bi 		if (ret)					\
13856e08688SWyon Bi 			return ret;				\
13956e08688SWyon Bi 	} while (0)
14056e08688SWyon Bi 
14156e08688SWyon Bi #define maxim_deserializer_write(max96752f, reg, val) do {	\
14256e08688SWyon Bi 		int ret;					\
14356e08688SWyon Bi 		ret = dm_i2c_reg_write(max96752f->dev,		\
14456e08688SWyon Bi 				       reg, val);		\
14556e08688SWyon Bi 		if (ret)					\
14656e08688SWyon Bi 			return ret;				\
14756e08688SWyon Bi 	} while (0)
14856e08688SWyon Bi 
boe_av156fht_l83_panel_prepare(struct max96752f * max96752f)14956e08688SWyon Bi static int boe_av156fht_l83_panel_prepare(struct max96752f *max96752f)
15056e08688SWyon Bi {
15156e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0002, 0x43);
15256e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0140, 0x20);
15356e08688SWyon Bi 
15456e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);	/* oldi */
15556e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x020c, 0x84);	/* bl_pwm */
15656e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0206, 0x83);	/* tp_int */
15756e08688SWyon Bi 
15856e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0215, 0x90);	/* lcd_en */
15956e08688SWyon Bi 	mdelay(20);
16056e08688SWyon Bi 
16156e08688SWyon Bi 	return 0;
16256e08688SWyon Bi }
16356e08688SWyon Bi 
boe_av156fht_l83_panel_unprepare(struct max96752f * max96752f)16456e08688SWyon Bi static int boe_av156fht_l83_panel_unprepare(struct max96752f *max96752f)
16556e08688SWyon Bi {
16656e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0215, 0x80);	/* lcd_en */
16756e08688SWyon Bi 
16856e08688SWyon Bi 	return 0;
16956e08688SWyon Bi }
17056e08688SWyon Bi 
boe_av156fht_l83_panel_enable(struct max96752f * max96752f)17156e08688SWyon Bi static int boe_av156fht_l83_panel_enable(struct max96752f *max96752f)
17256e08688SWyon Bi {
17356e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0227, 0x90);	/* lcd_rst */
17456e08688SWyon Bi 	mdelay(20);
17556e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x020f, 0x90);	/* tp_rst */
17656e08688SWyon Bi 	mdelay(100);
17756e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0221, 0x90);	/* lcd_stb */
17856e08688SWyon Bi 	mdelay(60);
17956e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0212, 0x90);	/* bl_current_ctl */
18056e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0209, 0x90);	/* bl_en */
18156e08688SWyon Bi 
18256e08688SWyon Bi 	return 0;
18356e08688SWyon Bi }
18456e08688SWyon Bi 
boe_av156fht_l83_panel_disable(struct max96752f * max96752f)18556e08688SWyon Bi static int boe_av156fht_l83_panel_disable(struct max96752f *max96752f)
18656e08688SWyon Bi {
18756e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0209, 0x80);	/* bl_en */
18856e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0212, 0x80);	/* bl_current_ctl */
18956e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0221, 0x80);	/* lcd_stb */
19056e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x020f, 0x80);	/* tp_rst */
19156e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0227, 0x80);	/* lcd_rst */
19256e08688SWyon Bi 
19356e08688SWyon Bi 	return 0;
19456e08688SWyon Bi }
19556e08688SWyon Bi 
boe_av156fht_l83_panel_backlight_enable(struct max96752f * max96752f)19656e08688SWyon Bi static int boe_av156fht_l83_panel_backlight_enable(struct max96752f *max96752f)
19756e08688SWyon Bi {
19856e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0212, 0x90);	/* bl_current_ctl */
19956e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0209, 0x90);	/* bl_en */
20056e08688SWyon Bi 
20156e08688SWyon Bi 	return 0;
20256e08688SWyon Bi }
20356e08688SWyon Bi 
boe_av156fht_l83_panel_backlight_disable(struct max96752f * max96752f)20456e08688SWyon Bi static int boe_av156fht_l83_panel_backlight_disable(struct max96752f *max96752f)
20556e08688SWyon Bi {
20656e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0209, 0x80);	/* bl_en */
20756e08688SWyon Bi 	maxim_deserializer_write(max96752f, 0x0212, 0x80);	/* bl_current_ctl */
20856e08688SWyon Bi 
20956e08688SWyon Bi 	return 0;
21056e08688SWyon Bi }
21156e08688SWyon Bi 
21256e08688SWyon Bi static const struct panel_desc boe_av156fht_l83 = {
21356e08688SWyon Bi 	.name			= "boe-av156fht-l83",
21456e08688SWyon Bi 	.prepare		= boe_av156fht_l83_panel_prepare,
21556e08688SWyon Bi 	.unprepare		= boe_av156fht_l83_panel_unprepare,
21656e08688SWyon Bi 	.enable			= boe_av156fht_l83_panel_enable,
21756e08688SWyon Bi 	.disable		= boe_av156fht_l83_panel_disable,
21856e08688SWyon Bi 	.backlight_enable	= boe_av156fht_l83_panel_backlight_enable,
21956e08688SWyon Bi 	.backlight_disable	= boe_av156fht_l83_panel_backlight_disable,
22056e08688SWyon Bi };
22156e08688SWyon Bi 
hannstar_hsd123jpw3_a15_prepare(struct max96752f * max96752f)222*f03ca6ffSWyon Bi static int hannstar_hsd123jpw3_a15_prepare(struct max96752f *max96752f)
223*f03ca6ffSWyon Bi {
224*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0002, 0x43);
225*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0140, 0x20);
226*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);
227*f03ca6ffSWyon Bi 
228*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0203, 0x83);	/* GPIO1  <- TP_INT */
229*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0206, 0x84);      /* GPIO2  -> TP_RST */
230*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0224, 0x84);	/* GPIO12 -> LCD_BL_PWM */
231*f03ca6ffSWyon Bi 
232*f03ca6ffSWyon Bi 	return 0;
233*f03ca6ffSWyon Bi }
234*f03ca6ffSWyon Bi 
hannstar_hsd123jpw3_a15_unprepare(struct max96752f * max96752f)235*f03ca6ffSWyon Bi static int hannstar_hsd123jpw3_a15_unprepare(struct max96752f *max96752f)
236*f03ca6ffSWyon Bi {
237*f03ca6ffSWyon Bi 	return 0;
238*f03ca6ffSWyon Bi }
239*f03ca6ffSWyon Bi 
hannstar_hsd123jpw3_a15_enable(struct max96752f * max96752f)240*f03ca6ffSWyon Bi static int hannstar_hsd123jpw3_a15_enable(struct max96752f *max96752f)
241*f03ca6ffSWyon Bi {
242*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0221, 0x10);	/* GPIO11 -> LCD_RESET */
243*f03ca6ffSWyon Bi 	mdelay(20);
244*f03ca6ffSWyon Bi 
245*f03ca6ffSWyon Bi 	return 0;
246*f03ca6ffSWyon Bi }
247*f03ca6ffSWyon Bi 
hannstar_hsd123jpw3_a15_disable(struct max96752f * max96752f)248*f03ca6ffSWyon Bi static int hannstar_hsd123jpw3_a15_disable(struct max96752f *max96752f)
249*f03ca6ffSWyon Bi {
250*f03ca6ffSWyon Bi 	maxim_deserializer_write(max96752f, 0x0221, 0x00);	/* GPIO11 -> LCD_RESET */
251*f03ca6ffSWyon Bi 	mdelay(20);
252*f03ca6ffSWyon Bi 
253*f03ca6ffSWyon Bi 	return 0;
254*f03ca6ffSWyon Bi }
255*f03ca6ffSWyon Bi 
256*f03ca6ffSWyon Bi static const struct panel_desc hannstar_hsd123jpw3_a15 = {
257*f03ca6ffSWyon Bi 	.name			= "hannstar,hsd123jpw3-a15",
258*f03ca6ffSWyon Bi 	.prepare		= hannstar_hsd123jpw3_a15_prepare,
259*f03ca6ffSWyon Bi 	.unprepare		= hannstar_hsd123jpw3_a15_unprepare,
260*f03ca6ffSWyon Bi 	.enable			= hannstar_hsd123jpw3_a15_enable,
261*f03ca6ffSWyon Bi 	.disable		= hannstar_hsd123jpw3_a15_disable,
262*f03ca6ffSWyon Bi };
263*f03ca6ffSWyon Bi 
ogm_101fhbllm01_prepare(struct max96752f * max96752f)2645202c1e0SWyon Bi static int ogm_101fhbllm01_prepare(struct max96752f *max96752f)
2655202c1e0SWyon Bi {
2665202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x01ce, 0x5e);
2675202c1e0SWyon Bi 
2685202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x0203, 0x84);	/* GPIO1 -> BL_PWM */
2695202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x0206, 0x84);	/* GPIO2 -> TP_RST */
2705202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x0209, 0x83);	/* GPIO3 <- TP_INT */
2715202c1e0SWyon Bi 
2725202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x0001, 0x02);
2735202c1e0SWyon Bi 
2745202c1e0SWyon Bi 	return 0;
2755202c1e0SWyon Bi }
2765202c1e0SWyon Bi 
ogm_101fhbllm01_unprepare(struct max96752f * max96752f)2775202c1e0SWyon Bi static int ogm_101fhbllm01_unprepare(struct max96752f *max96752f)
2785202c1e0SWyon Bi {
2795202c1e0SWyon Bi 	maxim_deserializer_write(max96752f, 0x0001, 0x01);
2805202c1e0SWyon Bi 
2815202c1e0SWyon Bi 	return 0;
2825202c1e0SWyon Bi }
2835202c1e0SWyon Bi 
2845202c1e0SWyon Bi static const struct panel_desc ogm_101fhbllm01 = {
2855202c1e0SWyon Bi 	.name			= "ogm,101fhbllm01",
2865202c1e0SWyon Bi 	.prepare		= ogm_101fhbllm01_prepare,
2875202c1e0SWyon Bi 	.unprepare		= ogm_101fhbllm01_unprepare,
2885202c1e0SWyon Bi };
2895202c1e0SWyon Bi 
29056e08688SWyon Bi static const struct udevice_id max96752f_of_match[] = {
29156e08688SWyon Bi 	{ .compatible = "boe,av156fht-l83", .data = (ulong)&boe_av156fht_l83 },
292*f03ca6ffSWyon Bi 	{ .compatible = "hannstar,hsd123jpw3-a15", .data = (ulong)&hannstar_hsd123jpw3_a15 },
2935202c1e0SWyon Bi 	{ .compatible = "ogm,101fhbllm01", .data = (ulong)&ogm_101fhbllm01 },
29456e08688SWyon Bi 	{}
29556e08688SWyon Bi };
29656e08688SWyon Bi 
29756e08688SWyon Bi U_BOOT_DRIVER(max96752f) = {
29856e08688SWyon Bi 	.name = "max96752f",
29956e08688SWyon Bi 	.id = UCLASS_PANEL,
30056e08688SWyon Bi 	.of_match = max96752f_of_match,
30156e08688SWyon Bi 	.probe = max96752f_probe,
30256e08688SWyon Bi 	.priv_auto_alloc_size = sizeof(struct max96752f),
30356e08688SWyon Bi };
304