1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  */
5 
6 #include <linux/delay.h>
7 #include <linux/err.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/of_graph.h>
12 #include <linux/regulator/consumer.h>
13 
14 #include <drm/drm_bridge.h>
15 #include <drm/drm_mipi_dsi.h>
16 #include <drm/drm_of.h>
17 #include <drm/drm_panel.h>
18 #include <drm/drm_print.h>
19 
20 #define PAGE2_GPIO_H		0xa7
21 #define PS_GPIO9		BIT(1)
22 #define PAGE2_I2C_BYPASS	0xea
23 #define I2C_BYPASS_EN		0xd0
24 #define PAGE2_MCS_EN		0xf3
25 #define MCS_EN			BIT(0)
26 #define PAGE3_SET_ADD		0xfe
27 #define VDO_CTL_ADD		0x13
28 #define VDO_DIS			0x18
29 #define VDO_EN			0x1c
30 #define DP_NUM_LANES		4
31 
32 /*
33  * PS8640 uses multiple addresses:
34  * page[0]: for DP control
35  * page[1]: for VIDEO Bridge
36  * page[2]: for control top
37  * page[3]: for DSI Link Control1
38  * page[4]: for MIPI Phy
39  * page[5]: for VPLL
40  * page[6]: for DSI Link Control2
41  * page[7]: for SPI ROM mapping
42  */
43 enum page_addr_offset {
44 	PAGE0_DP_CNTL = 0,
45 	PAGE1_VDO_BDG,
46 	PAGE2_TOP_CNTL,
47 	PAGE3_DSI_CNTL1,
48 	PAGE4_MIPI_PHY,
49 	PAGE5_VPLL,
50 	PAGE6_DSI_CNTL2,
51 	PAGE7_SPI_CNTL,
52 	MAX_DEVS
53 };
54 
55 enum ps8640_vdo_control {
56 	DISABLE = VDO_DIS,
57 	ENABLE = VDO_EN,
58 };
59 
60 struct ps8640 {
61 	struct drm_bridge bridge;
62 	struct drm_bridge *panel_bridge;
63 	struct mipi_dsi_device *dsi;
64 	struct i2c_client *page[MAX_DEVS];
65 	struct regulator_bulk_data supplies[2];
66 	struct gpio_desc *gpio_reset;
67 	struct gpio_desc *gpio_powerdown;
68 };
69 
70 static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
71 {
72 	return container_of(e, struct ps8640, bridge);
73 }
74 
75 static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
76 				     const enum ps8640_vdo_control ctrl)
77 {
78 	struct i2c_client *client = ps_bridge->page[PAGE3_DSI_CNTL1];
79 	u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl };
80 	int ret;
81 
82 	ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD,
83 					     sizeof(vdo_ctrl_buf),
84 					     vdo_ctrl_buf);
85 	if (ret < 0) {
86 		DRM_ERROR("failed to %sable VDO: %d\n",
87 			  ctrl == ENABLE ? "en" : "dis", ret);
88 		return ret;
89 	}
90 
91 	return 0;
92 }
93 
94 static void ps8640_pre_enable(struct drm_bridge *bridge)
95 {
96 	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
97 	struct i2c_client *client = ps_bridge->page[PAGE2_TOP_CNTL];
98 	unsigned long timeout;
99 	int ret, status;
100 
101 	ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
102 				    ps_bridge->supplies);
103 	if (ret < 0) {
104 		DRM_ERROR("cannot enable regulators %d\n", ret);
105 		return;
106 	}
107 
108 	gpiod_set_value(ps_bridge->gpio_powerdown, 0);
109 	gpiod_set_value(ps_bridge->gpio_reset, 1);
110 	usleep_range(2000, 2500);
111 	gpiod_set_value(ps_bridge->gpio_reset, 0);
112 
113 	/*
114 	 * Wait for the ps8640 embedded MCU to be ready
115 	 * First wait 200ms and then check the MCU ready flag every 20ms
116 	 */
117 	msleep(200);
118 
119 	timeout = jiffies + msecs_to_jiffies(200) + 1;
120 
121 	while (time_is_after_jiffies(timeout)) {
122 		status = i2c_smbus_read_byte_data(client, PAGE2_GPIO_H);
123 		if (status < 0) {
124 			DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", status);
125 			goto err_regulators_disable;
126 		}
127 		if ((status & PS_GPIO9) == PS_GPIO9)
128 			break;
129 
130 		msleep(20);
131 	}
132 
133 	msleep(50);
134 
135 	/*
136 	 * The Manufacturer Command Set (MCS) is a device dependent interface
137 	 * intended for factory programming of the display module default
138 	 * parameters. Once the display module is configured, the MCS shall be
139 	 * disabled by the manufacturer. Once disabled, all MCS commands are
140 	 * ignored by the display interface.
141 	 */
142 	status = i2c_smbus_read_byte_data(client, PAGE2_MCS_EN);
143 	if (status < 0) {
144 		DRM_ERROR("failed read PAGE2_MCS_EN: %d\n", status);
145 		goto err_regulators_disable;
146 	}
147 
148 	ret = i2c_smbus_write_byte_data(client, PAGE2_MCS_EN,
149 					status & ~MCS_EN);
150 	if (ret < 0) {
151 		DRM_ERROR("failed write PAGE2_MCS_EN: %d\n", ret);
152 		goto err_regulators_disable;
153 	}
154 
155 	ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
156 	if (ret)
157 		goto err_regulators_disable;
158 
159 	/* Switch access edp panel's edid through i2c */
160 	ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS,
161 					I2C_BYPASS_EN);
162 	if (ret < 0) {
163 		DRM_ERROR("failed write PAGE2_I2C_BYPASS: %d\n", ret);
164 		goto err_regulators_disable;
165 	}
166 
167 	return;
168 
169 err_regulators_disable:
170 	regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
171 			       ps_bridge->supplies);
172 }
173 
174 static void ps8640_post_disable(struct drm_bridge *bridge)
175 {
176 	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
177 	int ret;
178 
179 	ps8640_bridge_vdo_control(ps_bridge, DISABLE);
180 
181 	gpiod_set_value(ps_bridge->gpio_reset, 1);
182 	gpiod_set_value(ps_bridge->gpio_powerdown, 1);
183 	ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
184 				     ps_bridge->supplies);
185 	if (ret < 0)
186 		DRM_ERROR("cannot disable regulators %d\n", ret);
187 }
188 
189 static int ps8640_bridge_attach(struct drm_bridge *bridge,
190 				enum drm_bridge_attach_flags flags)
191 {
192 	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
193 	struct device *dev = &ps_bridge->page[0]->dev;
194 	struct device_node *in_ep, *dsi_node;
195 	struct mipi_dsi_device *dsi;
196 	struct mipi_dsi_host *host;
197 	int ret;
198 	const struct mipi_dsi_device_info info = { .type = "ps8640",
199 						   .channel = 0,
200 						   .node = NULL,
201 						 };
202 
203 	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
204 		return -EINVAL;
205 
206 	/* port@0 is ps8640 dsi input port */
207 	in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
208 	if (!in_ep)
209 		return -ENODEV;
210 
211 	dsi_node = of_graph_get_remote_port_parent(in_ep);
212 	of_node_put(in_ep);
213 	if (!dsi_node)
214 		return -ENODEV;
215 
216 	host = of_find_mipi_dsi_host_by_node(dsi_node);
217 	of_node_put(dsi_node);
218 	if (!host)
219 		return -ENODEV;
220 
221 	dsi = mipi_dsi_device_register_full(host, &info);
222 	if (IS_ERR(dsi)) {
223 		dev_err(dev, "failed to create dsi device\n");
224 		ret = PTR_ERR(dsi);
225 		return ret;
226 	}
227 
228 	ps_bridge->dsi = dsi;
229 
230 	dsi->host = host;
231 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
232 			  MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
233 	dsi->format = MIPI_DSI_FMT_RGB888;
234 	dsi->lanes = DP_NUM_LANES;
235 	ret = mipi_dsi_attach(dsi);
236 	if (ret)
237 		goto err_dsi_attach;
238 
239 	/* Attach the panel-bridge to the dsi bridge */
240 	return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge,
241 				 &ps_bridge->bridge, flags);
242 
243 err_dsi_attach:
244 	mipi_dsi_device_unregister(dsi);
245 	return ret;
246 }
247 
248 static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
249 					   struct drm_connector *connector)
250 {
251 	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
252 
253 	return drm_get_edid(connector,
254 			    ps_bridge->page[PAGE0_DP_CNTL]->adapter);
255 }
256 
257 static const struct drm_bridge_funcs ps8640_bridge_funcs = {
258 	.attach = ps8640_bridge_attach,
259 	.get_edid = ps8640_bridge_get_edid,
260 	.post_disable = ps8640_post_disable,
261 	.pre_enable = ps8640_pre_enable,
262 };
263 
264 static int ps8640_probe(struct i2c_client *client)
265 {
266 	struct device *dev = &client->dev;
267 	struct device_node *np = dev->of_node;
268 	struct ps8640 *ps_bridge;
269 	struct drm_panel *panel;
270 	int ret;
271 	u32 i;
272 
273 	ps_bridge = devm_kzalloc(dev, sizeof(*ps_bridge), GFP_KERNEL);
274 	if (!ps_bridge)
275 		return -ENOMEM;
276 
277 	/* port@1 is ps8640 output port */
278 	ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
279 	if (ret < 0)
280 		return ret;
281 	if (!panel)
282 		return -ENODEV;
283 
284 	ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
285 	if (IS_ERR(ps_bridge->panel_bridge))
286 		return PTR_ERR(ps_bridge->panel_bridge);
287 
288 	ps_bridge->supplies[0].supply = "vdd33";
289 	ps_bridge->supplies[1].supply = "vdd12";
290 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
291 				      ps_bridge->supplies);
292 	if (ret)
293 		return ret;
294 
295 	ps_bridge->gpio_powerdown = devm_gpiod_get(&client->dev, "powerdown",
296 						   GPIOD_OUT_HIGH);
297 	if (IS_ERR(ps_bridge->gpio_powerdown))
298 		return PTR_ERR(ps_bridge->gpio_powerdown);
299 
300 	/*
301 	 * Assert the reset to avoid the bridge being initialized prematurely
302 	 */
303 	ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset",
304 					       GPIOD_OUT_HIGH);
305 	if (IS_ERR(ps_bridge->gpio_reset))
306 		return PTR_ERR(ps_bridge->gpio_reset);
307 
308 	ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
309 	ps_bridge->bridge.of_node = dev->of_node;
310 	ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
311 	ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
312 
313 	ps_bridge->page[PAGE0_DP_CNTL] = client;
314 
315 	for (i = 1; i < ARRAY_SIZE(ps_bridge->page); i++) {
316 		ps_bridge->page[i] = devm_i2c_new_dummy_device(&client->dev,
317 							     client->adapter,
318 							     client->addr + i);
319 		if (IS_ERR(ps_bridge->page[i])) {
320 			dev_err(dev, "failed i2c dummy device, address %02x\n",
321 				client->addr + i);
322 			return PTR_ERR(ps_bridge->page[i]);
323 		}
324 	}
325 
326 	i2c_set_clientdata(client, ps_bridge);
327 
328 	drm_bridge_add(&ps_bridge->bridge);
329 
330 	return 0;
331 }
332 
333 static int ps8640_remove(struct i2c_client *client)
334 {
335 	struct ps8640 *ps_bridge = i2c_get_clientdata(client);
336 
337 	drm_bridge_remove(&ps_bridge->bridge);
338 
339 	return 0;
340 }
341 
342 static const struct of_device_id ps8640_match[] = {
343 	{ .compatible = "parade,ps8640" },
344 	{ }
345 };
346 MODULE_DEVICE_TABLE(of, ps8640_match);
347 
348 static struct i2c_driver ps8640_driver = {
349 	.probe_new = ps8640_probe,
350 	.remove = ps8640_remove,
351 	.driver = {
352 		.name = "ps8640",
353 		.of_match_table = ps8640_match,
354 	},
355 };
356 module_i2c_driver(ps8640_driver);
357 
358 MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
359 MODULE_AUTHOR("CK Hu <ck.hu@mediatek.com>");
360 MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>");
361 MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");
362 MODULE_LICENSE("GPL v2");
363