xref: /linux/drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c (revision face6a3615a649456eb4549f6d474221d877d604)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016 XiaoMi, Inc.
4  * Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
5  */
6 
7 #include <linux/delay.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/of_graph.h>
12 #include <linux/regulator/consumer.h>
13 
14 #include <video/mipi_display.h>
15 
16 #include <drm/drm_connector.h>
17 #include <drm/drm_crtc.h>
18 #include <drm/drm_device.h>
19 #include <drm/drm_mipi_dsi.h>
20 #include <drm/drm_modes.h>
21 #include <drm/drm_panel.h>
22 #include <drm/drm_probe_helper.h>
23 
24 static const struct regulator_bulk_data sharp_supplies[] = {
25 	{ .supply = "avdd" }, { .supply = "vddio" },
26 	{ .supply = "vsp" }, { .supply = "vsn" },
27 };
28 
29 struct sharp_panel {
30 	struct drm_panel panel;
31 	struct mipi_dsi_device *dsi[2];
32 
33 	struct gpio_desc *reset_gpio;
34 	struct regulator_bulk_data *supplies;
35 
36 	const struct drm_display_mode *mode;
37 };
38 
39 static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
40 {
41 	return container_of(panel, struct sharp_panel, panel);
42 }
43 
44 static void sharp_panel_reset(struct sharp_panel *sharp)
45 {
46 	gpiod_set_value_cansleep(sharp->reset_gpio, 1);
47 	usleep_range(2000, 3000);
48 	gpiod_set_value_cansleep(sharp->reset_gpio, 0);
49 	usleep_range(2000, 3000);
50 }
51 
52 static int sharp_panel_prepare(struct drm_panel *panel)
53 {
54 	struct sharp_panel *sharp = to_sharp_panel(panel);
55 	struct device *dev = panel->dev;
56 	struct mipi_dsi_device *dsi0 = sharp->dsi[0];
57 	struct mipi_dsi_device *dsi1 = sharp->dsi[1];
58 	struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL };
59 	int ret;
60 
61 	ret = regulator_bulk_enable(ARRAY_SIZE(sharp_supplies), sharp->supplies);
62 	if (ret) {
63 		dev_err(dev, "error enabling regulators (%d)\n", ret);
64 		return ret;
65 	}
66 
67 	msleep(24);
68 
69 	if (sharp->reset_gpio)
70 		sharp_panel_reset(sharp);
71 
72 	msleep(32);
73 
74 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_EXIT_SLEEP_MODE);
75 	mipi_dsi_msleep(&dsi_ctx, 120);
76 
77 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
78 					  MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff);
79 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
80 					  MIPI_DCS_WRITE_POWER_SAVE, 0x01);
81 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
82 					  MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c);
83 
84 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_ON);
85 
86 	return 0;
87 }
88 
89 static int sharp_panel_unprepare(struct drm_panel *panel)
90 {
91 	struct sharp_panel *sharp = to_sharp_panel(panel);
92 	struct mipi_dsi_device *dsi0 = sharp->dsi[0];
93 	struct mipi_dsi_device *dsi1 = sharp->dsi[1];
94 	struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL };
95 
96 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_OFF);
97 	mipi_dsi_msleep(&dsi_ctx, 100);
98 	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_ENTER_SLEEP_MODE);
99 	mipi_dsi_msleep(&dsi_ctx, 150);
100 
101 	if (sharp->reset_gpio)
102 		gpiod_set_value_cansleep(sharp->reset_gpio, 1);
103 
104 	return regulator_bulk_disable(ARRAY_SIZE(sharp_supplies), sharp->supplies);
105 }
106 
107 static const struct drm_display_mode default_mode = {
108 	.clock = (1536 + 136 + 28 + 28) * (2048 + 14 + 8 + 2) * 60 / 1000,
109 	.hdisplay = 1536,
110 	.hsync_start = 1536 + 136,
111 	.hsync_end = 1536 + 136 + 28,
112 	.htotal = 1536 + 136 + 28 + 28,
113 	.vdisplay = 2048,
114 	.vsync_start = 2048 + 14,
115 	.vsync_end = 2048 + 14 + 8,
116 	.vtotal = 2048 + 14 + 8 + 2,
117 	.width_mm = 120,
118 	.height_mm = 160,
119 	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
120 };
121 
122 static int sharp_panel_get_modes(struct drm_panel *panel,
123 				 struct drm_connector *connector)
124 {
125 	return drm_connector_helper_get_modes_fixed(connector, &default_mode);
126 }
127 
128 static const struct drm_panel_funcs sharp_panel_funcs = {
129 	.unprepare = sharp_panel_unprepare,
130 	.prepare = sharp_panel_prepare,
131 	.get_modes = sharp_panel_get_modes,
132 };
133 
134 static int sharp_panel_probe(struct mipi_dsi_device *dsi)
135 {
136 	const struct mipi_dsi_device_info info = { "sharp-link1", 0, NULL };
137 	struct device *dev = &dsi->dev;
138 	struct device_node *dsi_r;
139 	struct mipi_dsi_host *dsi_r_host;
140 	struct sharp_panel *sharp;
141 	int i, ret;
142 
143 	sharp = devm_drm_panel_alloc(dev, struct sharp_panel, panel,
144 				     &sharp_panel_funcs, DRM_MODE_CONNECTOR_DSI);
145 	if (IS_ERR(sharp))
146 		return PTR_ERR(sharp);
147 
148 	ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(sharp_supplies),
149 					    sharp_supplies, &sharp->supplies);
150 	if (ret)
151 		return dev_err_probe(dev, ret, "failed to get supplies\n");
152 
153 	sharp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
154 	if (IS_ERR(sharp->reset_gpio))
155 		return dev_err_probe(dev, PTR_ERR(sharp->reset_gpio),
156 				     "failed to get reset GPIO\n");
157 
158 	/* Panel is always connected to two DSI hosts, DSI0 is left, DSI1 is right */
159 	dsi_r = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
160 	if (!dsi_r)
161 		return dev_err_probe(dev, -ENODEV, "failed to find second DSI host node\n");
162 
163 	dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r);
164 	of_node_put(dsi_r);
165 	if (!dsi_r_host)
166 		return dev_err_probe(dev, -EPROBE_DEFER, "cannot get secondary DSI host\n");
167 
168 	sharp->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi_r_host, &info);
169 	if (IS_ERR(sharp->dsi[1]))
170 		return dev_err_probe(dev, PTR_ERR(sharp->dsi[1]),
171 				     "second link registration failed\n");
172 
173 	sharp->dsi[0] = dsi;
174 	mipi_dsi_set_drvdata(dsi, sharp);
175 
176 	ret = drm_panel_of_backlight(&sharp->panel);
177 	if (ret)
178 		return dev_err_probe(dev, ret, "Failed to get backlight\n");
179 
180 	drm_panel_add(&sharp->panel);
181 
182 	for (i = 0; i < ARRAY_SIZE(sharp->dsi); i++) {
183 		if (!sharp->dsi[i])
184 			continue;
185 
186 		sharp->dsi[i]->lanes = 4;
187 		sharp->dsi[i]->format = MIPI_DSI_FMT_RGB888;
188 		sharp->dsi[i]->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
189 
190 		ret = devm_mipi_dsi_attach(dev, sharp->dsi[i]);
191 		if (ret < 0) {
192 			drm_panel_remove(&sharp->panel);
193 			return dev_err_probe(dev, ret, "failed to attach to DSI%d\n", i);
194 		}
195 	}
196 
197 	return 0;
198 }
199 
200 static void sharp_panel_remove(struct mipi_dsi_device *dsi)
201 {
202 	struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
203 
204 	drm_panel_remove(&sharp->panel);
205 }
206 
207 static const struct of_device_id sharp_of_match[] = {
208 	{ .compatible = "sharp,lq079l1sx01" },
209 	{ }
210 };
211 MODULE_DEVICE_TABLE(of, sharp_of_match);
212 
213 static struct mipi_dsi_driver sharp_panel_driver = {
214 	.driver = {
215 		.name = "panel-sharp-lq079l1sx01",
216 		.of_match_table = sharp_of_match,
217 	},
218 	.probe = sharp_panel_probe,
219 	.remove = sharp_panel_remove,
220 };
221 module_mipi_dsi_driver(sharp_panel_driver);
222 
223 MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
224 MODULE_DESCRIPTION("Sharp LQ079L1SX01 panel driver");
225 MODULE_LICENSE("GPL");
226