1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/device.h>
7#include <linux/delay.h>
8#include <linux/gpio/consumer.h>
9#include <linux/i2c.h>
10#include <linux/media-bus-format.h>
11#include <linux/regmap.h>
12
13#include <drm/drm_probe_helper.h>
14#include <drm/drm_atomic_helper.h>
15#include <drm/drm_edid.h>
16#include <drm/drm_mipi_dsi.h>
17#include <drm/drm_of.h>
18
19#include <video/videomode.h>
20
21#define I2C_MAIN 0
22#define I2C_ADDR_MAIN 0x48
23
24#define I2C_CEC_DSI 1
25#define I2C_ADDR_CEC_DSI 0x49
26
27#define I2C_MAX_IDX 2
28
29struct lt8912 {
30	struct device *dev;
31	struct drm_bridge bridge;
32	struct drm_connector connector;
33
34	struct i2c_client *i2c_client[I2C_MAX_IDX];
35	struct regmap *regmap[I2C_MAX_IDX];
36
37	struct device_node *host_node;
38	struct drm_bridge *hdmi_port;
39
40	struct mipi_dsi_device *dsi;
41
42	struct gpio_desc *gp_reset;
43
44	struct videomode mode;
45
46	struct regulator_bulk_data supplies[7];
47
48	u8 data_lanes;
49	bool is_power_on;
50};
51
52static int lt8912_write_init_config(struct lt8912 *lt)
53{
54	const struct reg_sequence seq[] = {
55		/* Digital clock en*/
56		{0x08, 0xff},
57		{0x09, 0xff},
58		{0x0a, 0xff},
59		{0x0b, 0x7c},
60		{0x0c, 0xff},
61		{0x42, 0x04},
62
63		/*Tx Analog*/
64		{0x31, 0xb1},
65		{0x32, 0xb1},
66		{0x33, 0x0e},
67		{0x37, 0x00},
68		{0x38, 0x22},
69		{0x60, 0x82},
70
71		/*Cbus Analog*/
72		{0x39, 0x45},
73		{0x3a, 0x00},
74		{0x3b, 0x00},
75
76		/*HDMI Pll Analog*/
77		{0x44, 0x31},
78		{0x55, 0x44},
79		{0x57, 0x01},
80		{0x5a, 0x02},
81
82		/*MIPI Analog*/
83		{0x3e, 0xd6},
84		{0x3f, 0xd4},
85		{0x41, 0x3c},
86		{0xB2, 0x00},
87	};
88
89	return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
90}
91
92static int lt8912_write_mipi_basic_config(struct lt8912 *lt)
93{
94	const struct reg_sequence seq[] = {
95		{0x12, 0x04},
96		{0x14, 0x00},
97		{0x15, 0x00},
98		{0x1a, 0x03},
99		{0x1b, 0x03},
100	};
101
102	return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
103};
104
105static int lt8912_write_dds_config(struct lt8912 *lt)
106{
107	const struct reg_sequence seq[] = {
108		{0x4e, 0xff},
109		{0x4f, 0x56},
110		{0x50, 0x69},
111		{0x51, 0x80},
112		{0x1f, 0x5e},
113		{0x20, 0x01},
114		{0x21, 0x2c},
115		{0x22, 0x01},
116		{0x23, 0xfa},
117		{0x24, 0x00},
118		{0x25, 0xc8},
119		{0x26, 0x00},
120		{0x27, 0x5e},
121		{0x28, 0x01},
122		{0x29, 0x2c},
123		{0x2a, 0x01},
124		{0x2b, 0xfa},
125		{0x2c, 0x00},
126		{0x2d, 0xc8},
127		{0x2e, 0x00},
128		{0x42, 0x64},
129		{0x43, 0x00},
130		{0x44, 0x04},
131		{0x45, 0x00},
132		{0x46, 0x59},
133		{0x47, 0x00},
134		{0x48, 0xf2},
135		{0x49, 0x06},
136		{0x4a, 0x00},
137		{0x4b, 0x72},
138		{0x4c, 0x45},
139		{0x4d, 0x00},
140		{0x52, 0x08},
141		{0x53, 0x00},
142		{0x54, 0xb2},
143		{0x55, 0x00},
144		{0x56, 0xe4},
145		{0x57, 0x0d},
146		{0x58, 0x00},
147		{0x59, 0xe4},
148		{0x5a, 0x8a},
149		{0x5b, 0x00},
150		{0x5c, 0x34},
151		{0x1e, 0x4f},
152		{0x51, 0x00},
153	};
154
155	return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
156}
157
158static int lt8912_write_rxlogicres_config(struct lt8912 *lt)
159{
160	int ret;
161
162	ret = regmap_write(lt->regmap[I2C_MAIN], 0x03, 0x7f);
163	usleep_range(10000, 20000);
164	ret |= regmap_write(lt->regmap[I2C_MAIN], 0x03, 0xff);
165
166	return ret;
167};
168
169/* enable LVDS output with some hardcoded configuration, not required for the HDMI output */
170static int lt8912_write_lvds_config(struct lt8912 *lt)
171{
172	const struct reg_sequence seq[] = {
173		// lvds power up
174		{0x44, 0x30},
175		{0x51, 0x05},
176
177		// core pll bypass
178		{0x50, 0x24}, // cp=50uA
179		{0x51, 0x2d}, // Pix_clk as reference, second order passive LPF PLL
180		{0x52, 0x04}, // loopdiv=0, use second-order PLL
181		{0x69, 0x0e}, // CP_PRESET_DIV_RATIO
182		{0x69, 0x8e},
183		{0x6a, 0x00},
184		{0x6c, 0xb8}, // RGD_CP_SOFT_K_EN,RGD_CP_SOFT_K[13:8]
185		{0x6b, 0x51},
186
187		{0x04, 0xfb}, // core pll reset
188		{0x04, 0xff},
189
190		// scaler bypass
191		{0x7f, 0x00}, // disable scaler
192		{0xa8, 0x13}, // 0x13: JEIDA, 0x33: VESA
193
194		{0x02, 0xf7}, // lvds pll reset
195		{0x02, 0xff},
196		{0x03, 0xcf},
197		{0x03, 0xff},
198	};
199
200	return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
201};
202
203static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
204{
205	return container_of(b, struct lt8912, bridge);
206}
207
208static inline struct lt8912 *connector_to_lt8912(struct drm_connector *c)
209{
210	return container_of(c, struct lt8912, connector);
211}
212
213static const struct regmap_config lt8912_regmap_config = {
214	.reg_bits = 8,
215	.val_bits = 8,
216	.max_register = 0xff,
217};
218
219static int lt8912_init_i2c(struct lt8912 *lt, struct i2c_client *client)
220{
221	unsigned int i;
222	/*
223	 * At this time we only initialize 2 chips, but the lt8912 provides
224	 * a third interface for the audio over HDMI configuration.
225	 */
226	struct i2c_board_info info[] = {
227		{ I2C_BOARD_INFO("lt8912p0", I2C_ADDR_MAIN), },
228		{ I2C_BOARD_INFO("lt8912p1", I2C_ADDR_CEC_DSI), },
229	};
230
231	if (!lt)
232		return -ENODEV;
233
234	for (i = 0; i < ARRAY_SIZE(info); i++) {
235		if (i > 0) {
236			lt->i2c_client[i] = i2c_new_dummy_device(client->adapter,
237								 info[i].addr);
238			if (IS_ERR(lt->i2c_client[i]))
239				return PTR_ERR(lt->i2c_client[i]);
240		}
241
242		lt->regmap[i] = devm_regmap_init_i2c(lt->i2c_client[i],
243						     &lt8912_regmap_config);
244		if (IS_ERR(lt->regmap[i]))
245			return PTR_ERR(lt->regmap[i]);
246	}
247	return 0;
248}
249
250static int lt8912_free_i2c(struct lt8912 *lt)
251{
252	unsigned int i;
253
254	for (i = 1; i < I2C_MAX_IDX; i++)
255		i2c_unregister_device(lt->i2c_client[i]);
256
257	return 0;
258}
259
260static int lt8912_hard_power_on(struct lt8912 *lt)
261{
262	int ret;
263
264	ret = regulator_bulk_enable(ARRAY_SIZE(lt->supplies), lt->supplies);
265	if (ret)
266		return ret;
267
268	gpiod_set_value_cansleep(lt->gp_reset, 0);
269	msleep(20);
270
271	return 0;
272}
273
274static void lt8912_hard_power_off(struct lt8912 *lt)
275{
276	gpiod_set_value_cansleep(lt->gp_reset, 1);
277	msleep(20);
278
279	regulator_bulk_disable(ARRAY_SIZE(lt->supplies), lt->supplies);
280
281	lt->is_power_on = false;
282}
283
284static int lt8912_video_setup(struct lt8912 *lt)
285{
286	u32 hactive, h_total, hpw, hfp, hbp;
287	u32 vactive, v_total, vpw, vfp, vbp;
288	u8 settle = 0x08;
289	int ret, hsync_activehigh, vsync_activehigh;
290
291	if (!lt)
292		return -EINVAL;
293
294	hactive = lt->mode.hactive;
295	hfp = lt->mode.hfront_porch;
296	hpw = lt->mode.hsync_len;
297	hbp = lt->mode.hback_porch;
298	h_total = hactive + hfp + hpw + hbp;
299	hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH;
300
301	vactive = lt->mode.vactive;
302	vfp = lt->mode.vfront_porch;
303	vpw = lt->mode.vsync_len;
304	vbp = lt->mode.vback_porch;
305	v_total = vactive + vfp + vpw + vbp;
306	vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH;
307
308	if (vactive <= 600)
309		settle = 0x04;
310	else if (vactive == 1080)
311		settle = 0x0a;
312
313	ret = regmap_write(lt->regmap[I2C_CEC_DSI], 0x10, 0x01);
314	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x11, settle);
315	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x18, hpw);
316	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x19, vpw);
317	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1c, hactive & 0xff);
318	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1d, hactive >> 8);
319
320	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x2f, 0x0c);
321
322	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x34, h_total & 0xff);
323	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x35, h_total >> 8);
324
325	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x36, v_total & 0xff);
326	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x37, v_total >> 8);
327
328	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x38, vbp & 0xff);
329	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x39, vbp >> 8);
330
331	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3a, vfp & 0xff);
332	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3b, vfp >> 8);
333
334	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3c, hbp & 0xff);
335	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3d, hbp >> 8);
336
337	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
338	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);
339
340	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0),
341				  vsync_activehigh ? BIT(0) : 0);
342	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
343				  hsync_activehigh ? BIT(1) : 0);
344	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0),
345				  lt->connector.display_info.is_hdmi ? BIT(0) : 0);
346
347	return ret;
348}
349
350static int lt8912_soft_power_on(struct lt8912 *lt)
351{
352	if (!lt->is_power_on) {
353		u32 lanes = lt->data_lanes;
354
355		lt8912_write_init_config(lt);
356		regmap_write(lt->regmap[I2C_CEC_DSI], 0x13, lanes & 3);
357
358		lt8912_write_mipi_basic_config(lt);
359
360		lt->is_power_on = true;
361	}
362
363	return 0;
364}
365
366static int lt8912_video_on(struct lt8912 *lt)
367{
368	int ret;
369
370	ret = lt8912_video_setup(lt);
371	if (ret < 0)
372		goto end;
373
374	ret = lt8912_write_dds_config(lt);
375	if (ret < 0)
376		goto end;
377
378	ret = lt8912_write_rxlogicres_config(lt);
379	if (ret < 0)
380		goto end;
381
382	ret = lt8912_write_lvds_config(lt);
383	if (ret < 0)
384		goto end;
385
386end:
387	return ret;
388}
389
390static enum drm_connector_status lt8912_check_cable_status(struct lt8912 *lt)
391{
392	int ret;
393	unsigned int reg_val;
394
395	ret = regmap_read(lt->regmap[I2C_MAIN], 0xC1, &reg_val);
396	if (ret)
397		return connector_status_unknown;
398
399	if (reg_val & BIT(7))
400		return connector_status_connected;
401
402	return connector_status_disconnected;
403}
404
405static enum drm_connector_status
406lt8912_connector_detect(struct drm_connector *connector, bool force)
407{
408	struct lt8912 *lt = connector_to_lt8912(connector);
409
410	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
411		return drm_bridge_detect(lt->hdmi_port);
412
413	return lt8912_check_cable_status(lt);
414}
415
416static const struct drm_connector_funcs lt8912_connector_funcs = {
417	.detect = lt8912_connector_detect,
418	.fill_modes = drm_helper_probe_single_connector_modes,
419	.destroy = drm_connector_cleanup,
420	.reset = drm_atomic_helper_connector_reset,
421	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
422	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
423};
424
425static enum drm_mode_status
426lt8912_connector_mode_valid(struct drm_connector *connector,
427			    struct drm_display_mode *mode)
428{
429	if (mode->clock > 150000)
430		return MODE_CLOCK_HIGH;
431
432	if (mode->hdisplay > 1920)
433		return MODE_BAD_HVALUE;
434
435	if (mode->vdisplay > 1080)
436		return MODE_BAD_VVALUE;
437
438	return MODE_OK;
439}
440
441static int lt8912_connector_get_modes(struct drm_connector *connector)
442{
443	const struct drm_edid *drm_edid;
444	struct lt8912 *lt = connector_to_lt8912(connector);
445	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
446	int ret, num;
447
448	drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector);
449	drm_edid_connector_update(connector, drm_edid);
450	if (!drm_edid)
451		return 0;
452
453	num = drm_edid_connector_add_modes(connector);
454
455	ret = drm_display_info_set_bus_formats(&connector->display_info,
456					       &bus_format, 1);
457	if (ret < 0)
458		num = 0;
459
460	drm_edid_free(drm_edid);
461	return num;
462}
463
464static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
465	.get_modes = lt8912_connector_get_modes,
466	.mode_valid = lt8912_connector_mode_valid,
467};
468
469static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
470				   const struct drm_display_mode *mode,
471				   const struct drm_display_mode *adj)
472{
473	struct lt8912 *lt = bridge_to_lt8912(bridge);
474
475	drm_display_mode_to_videomode(adj, &lt->mode);
476}
477
478static void lt8912_bridge_enable(struct drm_bridge *bridge)
479{
480	struct lt8912 *lt = bridge_to_lt8912(bridge);
481
482	lt8912_video_on(lt);
483}
484
485static int lt8912_attach_dsi(struct lt8912 *lt)
486{
487	struct device *dev = lt->dev;
488	struct mipi_dsi_host *host;
489	struct mipi_dsi_device *dsi;
490	int ret = -1;
491	const struct mipi_dsi_device_info info = { .type = "lt8912",
492						   .channel = 0,
493						   .node = NULL,
494						 };
495
496	host = of_find_mipi_dsi_host_by_node(lt->host_node);
497	if (!host)
498		return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n");
499
500	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
501	if (IS_ERR(dsi)) {
502		ret = PTR_ERR(dsi);
503		dev_err(dev, "failed to create dsi device (%d)\n", ret);
504		return ret;
505	}
506
507	lt->dsi = dsi;
508
509	dsi->lanes = lt->data_lanes;
510	dsi->format = MIPI_DSI_FMT_RGB888;
511
512	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
513			  MIPI_DSI_MODE_LPM |
514			  MIPI_DSI_MODE_NO_EOT_PACKET;
515
516	ret = devm_mipi_dsi_attach(dev, dsi);
517	if (ret < 0) {
518		dev_err(dev, "failed to attach dsi to host\n");
519		return ret;
520	}
521
522	return 0;
523}
524
525static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status)
526{
527	struct lt8912 *lt = data;
528
529	if (lt->bridge.dev)
530		drm_helper_hpd_irq_event(lt->bridge.dev);
531}
532
533static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
534{
535	int ret;
536	struct lt8912 *lt = bridge_to_lt8912(bridge);
537	struct drm_connector *connector = &lt->connector;
538
539	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) {
540		drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt);
541		connector->polled = DRM_CONNECTOR_POLL_HPD;
542	} else {
543		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
544				    DRM_CONNECTOR_POLL_DISCONNECT;
545	}
546
547	ret = drm_connector_init(bridge->dev, connector,
548				 &lt8912_connector_funcs,
549				 lt->hdmi_port->type);
550	if (ret)
551		goto exit;
552
553	drm_connector_helper_add(connector, &lt8912_connector_helper_funcs);
554
555	connector->dpms = DRM_MODE_DPMS_OFF;
556	drm_connector_attach_encoder(connector, bridge->encoder);
557
558exit:
559	return ret;
560}
561
562static int lt8912_bridge_attach(struct drm_bridge *bridge,
563				enum drm_bridge_attach_flags flags)
564{
565	struct lt8912 *lt = bridge_to_lt8912(bridge);
566	int ret;
567
568	ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge,
569				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
570	if (ret < 0) {
571		dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret);
572		return ret;
573	}
574
575	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
576		ret = lt8912_bridge_connector_init(bridge);
577		if (ret) {
578			dev_err(lt->dev, "Failed to init bridge ! (%d)\n", ret);
579			return ret;
580		}
581	}
582
583	ret = lt8912_hard_power_on(lt);
584	if (ret)
585		return ret;
586
587	ret = lt8912_soft_power_on(lt);
588	if (ret)
589		goto error;
590
591	return 0;
592
593error:
594	lt8912_hard_power_off(lt);
595	return ret;
596}
597
598static void lt8912_bridge_detach(struct drm_bridge *bridge)
599{
600	struct lt8912 *lt = bridge_to_lt8912(bridge);
601
602	lt8912_hard_power_off(lt);
603
604	if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
605		drm_bridge_hpd_disable(lt->hdmi_port);
606}
607
608static enum drm_connector_status
609lt8912_bridge_detect(struct drm_bridge *bridge)
610{
611	struct lt8912 *lt = bridge_to_lt8912(bridge);
612
613	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
614		return drm_bridge_detect(lt->hdmi_port);
615
616	return lt8912_check_cable_status(lt);
617}
618
619static const struct drm_edid *lt8912_bridge_edid_read(struct drm_bridge *bridge,
620						      struct drm_connector *connector)
621{
622	struct lt8912 *lt = bridge_to_lt8912(bridge);
623
624	/*
625	 * edid must be read through the ddc bus but it must be
626	 * given to the hdmi connector node.
627	 */
628	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID)
629		return drm_bridge_edid_read(lt->hdmi_port, connector);
630
631	dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n");
632	return NULL;
633}
634
635static const struct drm_bridge_funcs lt8912_bridge_funcs = {
636	.attach = lt8912_bridge_attach,
637	.detach = lt8912_bridge_detach,
638	.mode_set = lt8912_bridge_mode_set,
639	.enable = lt8912_bridge_enable,
640	.detect = lt8912_bridge_detect,
641	.edid_read = lt8912_bridge_edid_read,
642};
643
644static int lt8912_bridge_resume(struct device *dev)
645{
646	struct lt8912 *lt = dev_get_drvdata(dev);
647	int ret;
648
649	ret = lt8912_hard_power_on(lt);
650	if (ret)
651		return ret;
652
653	ret = lt8912_soft_power_on(lt);
654	if (ret)
655		return ret;
656
657	return lt8912_video_on(lt);
658}
659
660static int lt8912_bridge_suspend(struct device *dev)
661{
662	struct lt8912 *lt = dev_get_drvdata(dev);
663
664	lt8912_hard_power_off(lt);
665
666	return 0;
667}
668
669static DEFINE_SIMPLE_DEV_PM_OPS(lt8912_bridge_pm_ops, lt8912_bridge_suspend, lt8912_bridge_resume);
670
671static int lt8912_get_regulators(struct lt8912 *lt)
672{
673	unsigned int i;
674	const char * const supply_names[] = {
675		"vdd", "vccmipirx", "vccsysclk", "vcclvdstx",
676		"vcchdmitx", "vcclvdspll", "vcchdmipll"
677	};
678
679	for (i = 0; i < ARRAY_SIZE(lt->supplies); i++)
680		lt->supplies[i].supply = supply_names[i];
681
682	return devm_regulator_bulk_get(lt->dev, ARRAY_SIZE(lt->supplies),
683				       lt->supplies);
684}
685
686static int lt8912_parse_dt(struct lt8912 *lt)
687{
688	struct gpio_desc *gp_reset;
689	struct device *dev = lt->dev;
690	int ret;
691	int data_lanes;
692	struct device_node *port_node;
693
694	gp_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
695	if (IS_ERR(gp_reset)) {
696		ret = PTR_ERR(gp_reset);
697		if (ret != -EPROBE_DEFER)
698			dev_err(dev, "Failed to get reset gpio: %d\n", ret);
699		return ret;
700	}
701	lt->gp_reset = gp_reset;
702
703	data_lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, -1, 1, 4);
704	if (data_lanes < 0) {
705		dev_err(lt->dev, "%s: Bad data-lanes property\n", __func__);
706		return data_lanes;
707	}
708
709	lt->data_lanes = data_lanes;
710
711	lt->host_node = of_graph_get_remote_node(dev->of_node, 0, -1);
712	if (!lt->host_node) {
713		dev_err(lt->dev, "%s: Failed to get remote port\n", __func__);
714		return -ENODEV;
715	}
716
717	port_node = of_graph_get_remote_node(dev->of_node, 1, -1);
718	if (!port_node) {
719		dev_err(lt->dev, "%s: Failed to get connector port\n", __func__);
720		ret = -ENODEV;
721		goto err_free_host_node;
722	}
723
724	lt->hdmi_port = of_drm_find_bridge(port_node);
725	if (!lt->hdmi_port) {
726		ret = -EPROBE_DEFER;
727		dev_err_probe(lt->dev, ret, "%s: Failed to get hdmi port\n", __func__);
728		goto err_free_host_node;
729	}
730
731	if (!of_device_is_compatible(port_node, "hdmi-connector")) {
732		dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
733		ret = -EINVAL;
734		goto err_free_host_node;
735	}
736
737	ret = lt8912_get_regulators(lt);
738	if (ret)
739		goto err_free_host_node;
740
741	of_node_put(port_node);
742	return 0;
743
744err_free_host_node:
745	of_node_put(port_node);
746	of_node_put(lt->host_node);
747	return ret;
748}
749
750static int lt8912_put_dt(struct lt8912 *lt)
751{
752	of_node_put(lt->host_node);
753	return 0;
754}
755
756static int lt8912_probe(struct i2c_client *client)
757{
758	static struct lt8912 *lt;
759	int ret = 0;
760	struct device *dev = &client->dev;
761
762	lt = devm_kzalloc(dev, sizeof(struct lt8912), GFP_KERNEL);
763	if (!lt)
764		return -ENOMEM;
765
766	lt->dev = dev;
767	lt->i2c_client[0] = client;
768
769	ret = lt8912_parse_dt(lt);
770	if (ret)
771		goto err_dt_parse;
772
773	ret = lt8912_init_i2c(lt, client);
774	if (ret)
775		goto err_i2c;
776
777	i2c_set_clientdata(client, lt);
778
779	lt->bridge.funcs = &lt8912_bridge_funcs;
780	lt->bridge.of_node = dev->of_node;
781	lt->bridge.ops = (DRM_BRIDGE_OP_EDID |
782			  DRM_BRIDGE_OP_DETECT);
783
784	drm_bridge_add(&lt->bridge);
785
786	ret = lt8912_attach_dsi(lt);
787	if (ret)
788		goto err_attach;
789
790	return 0;
791
792err_attach:
793	drm_bridge_remove(&lt->bridge);
794	lt8912_free_i2c(lt);
795err_i2c:
796	lt8912_put_dt(lt);
797err_dt_parse:
798	return ret;
799}
800
801static void lt8912_remove(struct i2c_client *client)
802{
803	struct lt8912 *lt = i2c_get_clientdata(client);
804
805	drm_bridge_remove(&lt->bridge);
806	lt8912_free_i2c(lt);
807	lt8912_put_dt(lt);
808}
809
810static const struct of_device_id lt8912_dt_match[] = {
811	{.compatible = "lontium,lt8912b"},
812	{}
813};
814MODULE_DEVICE_TABLE(of, lt8912_dt_match);
815
816static const struct i2c_device_id lt8912_id[] = {
817	{"lt8912", 0},
818	{},
819};
820MODULE_DEVICE_TABLE(i2c, lt8912_id);
821
822static struct i2c_driver lt8912_i2c_driver = {
823	.driver = {
824		.name = "lt8912",
825		.of_match_table = lt8912_dt_match,
826		.pm = pm_sleep_ptr(&lt8912_bridge_pm_ops),
827	},
828	.probe = lt8912_probe,
829	.remove = lt8912_remove,
830	.id_table = lt8912_id,
831};
832module_i2c_driver(lt8912_i2c_driver);
833
834MODULE_AUTHOR("Adrien Grassein <adrien.grassein@gmail.com>");
835MODULE_DESCRIPTION("lt8912 drm driver");
836MODULE_LICENSE("GPL v2");
837