// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 */

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/regmap.h>

#include <drm/drm_probe_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>

#include <video/videomode.h>

#define I2C_MAIN 0
#define I2C_ADDR_MAIN 0x48

#define I2C_CEC_DSI 1
#define I2C_ADDR_CEC_DSI 0x49

#define I2C_MAX_IDX 2

struct lt8912 {
	struct device *dev;
	struct drm_bridge bridge;
	struct drm_connector connector;

	struct i2c_client *i2c_client[I2C_MAX_IDX];
	struct regmap *regmap[I2C_MAX_IDX];

	struct device_node *host_node;
	struct drm_bridge *hdmi_port;

	struct mipi_dsi_device *dsi;

	struct gpio_desc *gp_reset;

	struct videomode mode;

	struct regulator_bulk_data supplies[7];

	u8 data_lanes;
	bool is_power_on;
};

static int lt8912_write_init_config(struct lt8912 *lt)
{
	const struct reg_sequence seq[] = {
		/* Digital clock en*/
		{0x08, 0xff},
		{0x09, 0xff},
		{0x0a, 0xff},
		{0x0b, 0x7c},
		{0x0c, 0xff},
		{0x42, 0x04},

		/*Tx Analog*/
		{0x31, 0xb1},
		{0x32, 0xb1},
		{0x33, 0x0e},
		{0x37, 0x00},
		{0x38, 0x22},
		{0x60, 0x82},

		/*Cbus Analog*/
		{0x39, 0x45},
		{0x3a, 0x00},
		{0x3b, 0x00},

		/*HDMI Pll Analog*/
		{0x44, 0x31},
		{0x55, 0x44},
		{0x57, 0x01},
		{0x5a, 0x02},

		/*MIPI Analog*/
		{0x3e, 0xd6},
		{0x3f, 0xd4},
		{0x41, 0x3c},
		{0xB2, 0x00},
	};

	return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
}

static int lt8912_write_mipi_basic_config(struct lt8912 *lt)
{
	const struct reg_sequence seq[] = {
		{0x12, 0x04},
		{0x14, 0x00},
		{0x15, 0x00},
		{0x1a, 0x03},
		{0x1b, 0x03},
	};

	return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
};

static int lt8912_write_dds_config(struct lt8912 *lt)
{
	const struct reg_sequence seq[] = {
		{0x4e, 0xff},
		{0x4f, 0x56},
		{0x50, 0x69},
		{0x51, 0x80},
		{0x1f, 0x5e},
		{0x20, 0x01},
		{0x21, 0x2c},
		{0x22, 0x01},
		{0x23, 0xfa},
		{0x24, 0x00},
		{0x25, 0xc8},
		{0x26, 0x00},
		{0x27, 0x5e},
		{0x28, 0x01},
		{0x29, 0x2c},
		{0x2a, 0x01},
		{0x2b, 0xfa},
		{0x2c, 0x00},
		{0x2d, 0xc8},
		{0x2e, 0x00},
		{0x42, 0x64},
		{0x43, 0x00},
		{0x44, 0x04},
		{0x45, 0x00},
		{0x46, 0x59},
		{0x47, 0x00},
		{0x48, 0xf2},
		{0x49, 0x06},
		{0x4a, 0x00},
		{0x4b, 0x72},
		{0x4c, 0x45},
		{0x4d, 0x00},
		{0x52, 0x08},
		{0x53, 0x00},
		{0x54, 0xb2},
		{0x55, 0x00},
		{0x56, 0xe4},
		{0x57, 0x0d},
		{0x58, 0x00},
		{0x59, 0xe4},
		{0x5a, 0x8a},
		{0x5b, 0x00},
		{0x5c, 0x34},
		{0x1e, 0x4f},
		{0x51, 0x00},
	};

	return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
}

static int lt8912_write_rxlogicres_config(struct lt8912 *lt)
{
	int ret;

	ret = regmap_write(lt->regmap[I2C_MAIN], 0x03, 0x7f);
	usleep_range(10000, 20000);
	ret |= regmap_write(lt->regmap[I2C_MAIN], 0x03, 0xff);

	return ret;
};

/* enable LVDS output with some hardcoded configuration, not required for the HDMI output */
static int lt8912_write_lvds_config(struct lt8912 *lt)
{
	const struct reg_sequence seq[] = {
		// lvds power up
		{0x44, 0x30},
		{0x51, 0x05},

		// core pll bypass
		{0x50, 0x24}, // cp=50uA
		{0x51, 0x2d}, // Pix_clk as reference, second order passive LPF PLL
		{0x52, 0x04}, // loopdiv=0, use second-order PLL
		{0x69, 0x0e}, // CP_PRESET_DIV_RATIO
		{0x69, 0x8e},
		{0x6a, 0x00},
		{0x6c, 0xb8}, // RGD_CP_SOFT_K_EN,RGD_CP_SOFT_K[13:8]
		{0x6b, 0x51},

		{0x04, 0xfb}, // core pll reset
		{0x04, 0xff},

		// scaler bypass
		{0x7f, 0x00}, // disable scaler
		{0xa8, 0x13}, // 0x13: JEIDA, 0x33: VESA

		{0x02, 0xf7}, // lvds pll reset
		{0x02, 0xff},
		{0x03, 0xcf},
		{0x03, 0xff},
	};

	return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
};

static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
{
	return container_of(b, struct lt8912, bridge);
}

static inline struct lt8912 *connector_to_lt8912(struct drm_connector *c)
{
	return container_of(c, struct lt8912, connector);
}

static const struct regmap_config lt8912_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0xff,
};

static int lt8912_init_i2c(struct lt8912 *lt, struct i2c_client *client)
{
	unsigned int i;
	/*
	 * At this time we only initialize 2 chips, but the lt8912 provides
	 * a third interface for the audio over HDMI configuration.
	 */
	struct i2c_board_info info[] = {
		{ I2C_BOARD_INFO("lt8912p0", I2C_ADDR_MAIN), },
		{ I2C_BOARD_INFO("lt8912p1", I2C_ADDR_CEC_DSI), },
	};

	if (!lt)
		return -ENODEV;

	for (i = 0; i < ARRAY_SIZE(info); i++) {
		if (i > 0) {
			lt->i2c_client[i] = i2c_new_dummy_device(client->adapter,
								 info[i].addr);
			if (IS_ERR(lt->i2c_client[i]))
				return PTR_ERR(lt->i2c_client[i]);
		}

		lt->regmap[i] = devm_regmap_init_i2c(lt->i2c_client[i],
						     &lt8912_regmap_config);
		if (IS_ERR(lt->regmap[i]))
			return PTR_ERR(lt->regmap[i]);
	}
	return 0;
}

static int lt8912_free_i2c(struct lt8912 *lt)
{
	unsigned int i;

	for (i = 1; i < I2C_MAX_IDX; i++)
		i2c_unregister_device(lt->i2c_client[i]);

	return 0;
}

static int lt8912_hard_power_on(struct lt8912 *lt)
{
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(lt->supplies), lt->supplies);
	if (ret)
		return ret;

	gpiod_set_value_cansleep(lt->gp_reset, 0);
	msleep(20);

	return 0;
}

static void lt8912_hard_power_off(struct lt8912 *lt)
{
	gpiod_set_value_cansleep(lt->gp_reset, 1);
	msleep(20);

	regulator_bulk_disable(ARRAY_SIZE(lt->supplies), lt->supplies);

	lt->is_power_on = false;
}

static int lt8912_video_setup(struct lt8912 *lt)
{
	u32 hactive, h_total, hpw, hfp, hbp;
	u32 vactive, v_total, vpw, vfp, vbp;
	u8 settle = 0x08;
	int ret, hsync_activehigh, vsync_activehigh;

	if (!lt)
		return -EINVAL;

	hactive = lt->mode.hactive;
	hfp = lt->mode.hfront_porch;
	hpw = lt->mode.hsync_len;
	hbp = lt->mode.hback_porch;
	h_total = hactive + hfp + hpw + hbp;
	hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH;

	vactive = lt->mode.vactive;
	vfp = lt->mode.vfront_porch;
	vpw = lt->mode.vsync_len;
	vbp = lt->mode.vback_porch;
	v_total = vactive + vfp + vpw + vbp;
	vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH;

	if (vactive <= 600)
		settle = 0x04;
	else if (vactive == 1080)
		settle = 0x0a;

	ret = regmap_write(lt->regmap[I2C_CEC_DSI], 0x10, 0x01);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x11, settle);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x18, hpw);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x19, vpw);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1c, hactive & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1d, hactive >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x2f, 0x0c);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x34, h_total & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x35, h_total >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x36, v_total & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x37, v_total >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x38, vbp & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x39, vbp >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3a, vfp & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3b, vfp >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3c, hbp & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3d, hbp >> 8);

	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
	ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);

	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0),
				  vsync_activehigh ? BIT(0) : 0);
	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
				  hsync_activehigh ? BIT(1) : 0);
	ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0),
				  lt->connector.display_info.is_hdmi ? BIT(0) : 0);

	return ret;
}

static int lt8912_soft_power_on(struct lt8912 *lt)
{
	if (!lt->is_power_on) {
		u32 lanes = lt->data_lanes;

		lt8912_write_init_config(lt);
		regmap_write(lt->regmap[I2C_CEC_DSI], 0x13, lanes & 3);

		lt8912_write_mipi_basic_config(lt);

		lt->is_power_on = true;
	}

	return 0;
}

static int lt8912_video_on(struct lt8912 *lt)
{
	int ret;

	ret = lt8912_video_setup(lt);
	if (ret < 0)
		goto end;

	ret = lt8912_write_dds_config(lt);
	if (ret < 0)
		goto end;

	ret = lt8912_write_rxlogicres_config(lt);
	if (ret < 0)
		goto end;

	ret = lt8912_write_lvds_config(lt);
	if (ret < 0)
		goto end;

end:
	return ret;
}

static enum drm_connector_status lt8912_check_cable_status(struct lt8912 *lt)
{
	int ret;
	unsigned int reg_val;

	ret = regmap_read(lt->regmap[I2C_MAIN], 0xC1, &reg_val);
	if (ret)
		return connector_status_unknown;

	if (reg_val & BIT(7))
		return connector_status_connected;

	return connector_status_disconnected;
}

static enum drm_connector_status
lt8912_connector_detect(struct drm_connector *connector, bool force)
{
	struct lt8912 *lt = connector_to_lt8912(connector);

	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
		return drm_bridge_detect(lt->hdmi_port);

	return lt8912_check_cable_status(lt);
}

static const struct drm_connector_funcs lt8912_connector_funcs = {
	.detect = lt8912_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static enum drm_mode_status
lt8912_connector_mode_valid(struct drm_connector *connector,
			    struct drm_display_mode *mode)
{
	if (mode->clock > 150000)
		return MODE_CLOCK_HIGH;

	if (mode->hdisplay > 1920)
		return MODE_BAD_HVALUE;

	if (mode->vdisplay > 1080)
		return MODE_BAD_VVALUE;

	return MODE_OK;
}

static int lt8912_connector_get_modes(struct drm_connector *connector)
{
	const struct drm_edid *drm_edid;
	struct lt8912 *lt = connector_to_lt8912(connector);
	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
	int ret, num;

	drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector);
	drm_edid_connector_update(connector, drm_edid);
	if (!drm_edid)
		return 0;

	num = drm_edid_connector_add_modes(connector);

	ret = drm_display_info_set_bus_formats(&connector->display_info,
					       &bus_format, 1);
	if (ret < 0)
		num = 0;

	drm_edid_free(drm_edid);
	return num;
}

static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
	.get_modes = lt8912_connector_get_modes,
	.mode_valid = lt8912_connector_mode_valid,
};

static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
				   const struct drm_display_mode *mode,
				   const struct drm_display_mode *adj)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);

	drm_display_mode_to_videomode(adj, &lt->mode);
}

static void lt8912_bridge_enable(struct drm_bridge *bridge)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);

	lt8912_video_on(lt);
}

static int lt8912_attach_dsi(struct lt8912 *lt)
{
	struct device *dev = lt->dev;
	struct mipi_dsi_host *host;
	struct mipi_dsi_device *dsi;
	int ret = -1;
	const struct mipi_dsi_device_info info = { .type = "lt8912",
						   .channel = 0,
						   .node = NULL,
						 };

	host = of_find_mipi_dsi_host_by_node(lt->host_node);
	if (!host) {
		dev_err(dev, "failed to find dsi host\n");
		return -EPROBE_DEFER;
	}

	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
	if (IS_ERR(dsi)) {
		ret = PTR_ERR(dsi);
		dev_err(dev, "failed to create dsi device (%d)\n", ret);
		return ret;
	}

	lt->dsi = dsi;

	dsi->lanes = lt->data_lanes;
	dsi->format = MIPI_DSI_FMT_RGB888;

	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
			  MIPI_DSI_MODE_LPM |
			  MIPI_DSI_MODE_NO_EOT_PACKET;

	ret = devm_mipi_dsi_attach(dev, dsi);
	if (ret < 0) {
		dev_err(dev, "failed to attach dsi to host\n");
		return ret;
	}

	return 0;
}

static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status)
{
	struct lt8912 *lt = data;

	if (lt->bridge.dev)
		drm_helper_hpd_irq_event(lt->bridge.dev);
}

static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
{
	int ret;
	struct lt8912 *lt = bridge_to_lt8912(bridge);
	struct drm_connector *connector = &lt->connector;

	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) {
		drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt);
		connector->polled = DRM_CONNECTOR_POLL_HPD;
	} else {
		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
				    DRM_CONNECTOR_POLL_DISCONNECT;
	}

	ret = drm_connector_init(bridge->dev, connector,
				 &lt8912_connector_funcs,
				 lt->hdmi_port->type);
	if (ret)
		goto exit;

	drm_connector_helper_add(connector, &lt8912_connector_helper_funcs);

	connector->dpms = DRM_MODE_DPMS_OFF;
	drm_connector_attach_encoder(connector, bridge->encoder);

exit:
	return ret;
}

static int lt8912_bridge_attach(struct drm_bridge *bridge,
				enum drm_bridge_attach_flags flags)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);
	int ret;

	ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge,
				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
	if (ret < 0) {
		dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret);
		return ret;
	}

	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
		ret = lt8912_bridge_connector_init(bridge);
		if (ret) {
			dev_err(lt->dev, "Failed to init bridge ! (%d)\n", ret);
			return ret;
		}
	}

	ret = lt8912_hard_power_on(lt);
	if (ret)
		return ret;

	ret = lt8912_soft_power_on(lt);
	if (ret)
		goto error;

	return 0;

error:
	lt8912_hard_power_off(lt);
	return ret;
}

static void lt8912_bridge_detach(struct drm_bridge *bridge)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);

	lt8912_hard_power_off(lt);

	if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
		drm_bridge_hpd_disable(lt->hdmi_port);
}

static enum drm_connector_status
lt8912_bridge_detect(struct drm_bridge *bridge)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);

	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
		return drm_bridge_detect(lt->hdmi_port);

	return lt8912_check_cable_status(lt);
}

static const struct drm_edid *lt8912_bridge_edid_read(struct drm_bridge *bridge,
						      struct drm_connector *connector)
{
	struct lt8912 *lt = bridge_to_lt8912(bridge);

	/*
	 * edid must be read through the ddc bus but it must be
	 * given to the hdmi connector node.
	 */
	if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID)
		return drm_bridge_edid_read(lt->hdmi_port, connector);

	dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n");
	return NULL;
}

static const struct drm_bridge_funcs lt8912_bridge_funcs = {
	.attach = lt8912_bridge_attach,
	.detach = lt8912_bridge_detach,
	.mode_set = lt8912_bridge_mode_set,
	.enable = lt8912_bridge_enable,
	.detect = lt8912_bridge_detect,
	.edid_read = lt8912_bridge_edid_read,
};

static int lt8912_bridge_resume(struct device *dev)
{
	struct lt8912 *lt = dev_get_drvdata(dev);
	int ret;

	ret = lt8912_hard_power_on(lt);
	if (ret)
		return ret;

	ret = lt8912_soft_power_on(lt);
	if (ret)
		return ret;

	return lt8912_video_on(lt);
}

static int lt8912_bridge_suspend(struct device *dev)
{
	struct lt8912 *lt = dev_get_drvdata(dev);

	lt8912_hard_power_off(lt);

	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(lt8912_bridge_pm_ops, lt8912_bridge_suspend, lt8912_bridge_resume);

static int lt8912_get_regulators(struct lt8912 *lt)
{
	unsigned int i;
	const char * const supply_names[] = {
		"vdd", "vccmipirx", "vccsysclk", "vcclvdstx",
		"vcchdmitx", "vcclvdspll", "vcchdmipll"
	};

	for (i = 0; i < ARRAY_SIZE(lt->supplies); i++)
		lt->supplies[i].supply = supply_names[i];

	return devm_regulator_bulk_get(lt->dev, ARRAY_SIZE(lt->supplies),
				       lt->supplies);
}

static int lt8912_parse_dt(struct lt8912 *lt)
{
	struct gpio_desc *gp_reset;
	struct device *dev = lt->dev;
	int ret;
	int data_lanes;
	struct device_node *port_node;

	gp_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(gp_reset)) {
		ret = PTR_ERR(gp_reset);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Failed to get reset gpio: %d\n", ret);
		return ret;
	}
	lt->gp_reset = gp_reset;

	data_lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, -1, 1, 4);
	if (data_lanes < 0) {
		dev_err(lt->dev, "%s: Bad data-lanes property\n", __func__);
		return data_lanes;
	}

	lt->data_lanes = data_lanes;

	lt->host_node = of_graph_get_remote_node(dev->of_node, 0, -1);
	if (!lt->host_node) {
		dev_err(lt->dev, "%s: Failed to get remote port\n", __func__);
		return -ENODEV;
	}

	port_node = of_graph_get_remote_node(dev->of_node, 1, -1);
	if (!port_node) {
		dev_err(lt->dev, "%s: Failed to get connector port\n", __func__);
		ret = -ENODEV;
		goto err_free_host_node;
	}

	lt->hdmi_port = of_drm_find_bridge(port_node);
	if (!lt->hdmi_port) {
		ret = -EPROBE_DEFER;
		dev_err_probe(lt->dev, ret, "%s: Failed to get hdmi port\n", __func__);
		goto err_free_host_node;
	}

	if (!of_device_is_compatible(port_node, "hdmi-connector")) {
		dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
		ret = -EINVAL;
		goto err_free_host_node;
	}

	ret = lt8912_get_regulators(lt);
	if (ret)
		goto err_free_host_node;

	of_node_put(port_node);
	return 0;

err_free_host_node:
	of_node_put(port_node);
	of_node_put(lt->host_node);
	return ret;
}

static int lt8912_put_dt(struct lt8912 *lt)
{
	of_node_put(lt->host_node);
	return 0;
}

static int lt8912_probe(struct i2c_client *client)
{
	static struct lt8912 *lt;
	int ret = 0;
	struct device *dev = &client->dev;

	lt = devm_kzalloc(dev, sizeof(struct lt8912), GFP_KERNEL);
	if (!lt)
		return -ENOMEM;

	lt->dev = dev;
	lt->i2c_client[0] = client;

	ret = lt8912_parse_dt(lt);
	if (ret)
		goto err_dt_parse;

	ret = lt8912_init_i2c(lt, client);
	if (ret)
		goto err_i2c;

	i2c_set_clientdata(client, lt);

	lt->bridge.funcs = &lt8912_bridge_funcs;
	lt->bridge.of_node = dev->of_node;
	lt->bridge.ops = (DRM_BRIDGE_OP_EDID |
			  DRM_BRIDGE_OP_DETECT);

	drm_bridge_add(&lt->bridge);

	ret = lt8912_attach_dsi(lt);
	if (ret)
		goto err_attach;

	return 0;

err_attach:
	drm_bridge_remove(&lt->bridge);
	lt8912_free_i2c(lt);
err_i2c:
	lt8912_put_dt(lt);
err_dt_parse:
	return ret;
}

static void lt8912_remove(struct i2c_client *client)
{
	struct lt8912 *lt = i2c_get_clientdata(client);

	drm_bridge_remove(&lt->bridge);
	lt8912_free_i2c(lt);
	lt8912_put_dt(lt);
}

static const struct of_device_id lt8912_dt_match[] = {
	{.compatible = "lontium,lt8912b"},
	{}
};
MODULE_DEVICE_TABLE(of, lt8912_dt_match);

static const struct i2c_device_id lt8912_id[] = {
	{"lt8912", 0},
	{},
};
MODULE_DEVICE_TABLE(i2c, lt8912_id);

static struct i2c_driver lt8912_i2c_driver = {
	.driver = {
		.name = "lt8912",
		.of_match_table = lt8912_dt_match,
		.pm = pm_sleep_ptr(&lt8912_bridge_pm_ops),
	},
	.probe = lt8912_probe,
	.remove = lt8912_remove,
	.id_table = lt8912_id,
};
module_i2c_driver(lt8912_i2c_driver);

MODULE_AUTHOR("Adrien Grassein <adrien.grassein@gmail.com>");
MODULE_DESCRIPTION("lt8912 drm driver");
MODULE_LICENSE("GPL v2");
