/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright(c) 2016, Analogix Semiconductor.
 * Copyright(c) 2017, Icenowy Zheng <icenowy@aosc.io>
 *
 * Based on anx7808 driver obtained from chromeos with copyright:
 * Copyright(c) 2013, Google Inc.
 */
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>

#include "analogix-i2c-dptx.h"
#include "analogix-i2c-txcommon.h"

#define POLL_DELAY		50000 /* us */
#define POLL_TIMEOUT		5000000 /* us */

#define I2C_IDX_DPTX		0
#define I2C_IDX_TXCOM		1

static const u8 anx6345_i2c_addresses[] = {
	[I2C_IDX_DPTX]	= 0x70,
	[I2C_IDX_TXCOM]	= 0x72,
};
#define I2C_NUM_ADDRESSES	ARRAY_SIZE(anx6345_i2c_addresses)

struct anx6345 {
	struct drm_dp_aux aux;
	struct drm_bridge bridge;
	struct i2c_client *client;
	struct edid *edid;
	struct drm_connector connector;
	struct drm_panel *panel;
	struct regulator *dvdd12;
	struct regulator *dvdd25;
	struct gpio_desc *gpiod_reset;
	struct mutex lock;	/* protect EDID access */

	/* I2C Slave addresses of ANX6345 are mapped as DPTX and SYS */
	struct i2c_client *i2c_clients[I2C_NUM_ADDRESSES];
	struct regmap *map[I2C_NUM_ADDRESSES];

	u16 chipid;
	u8 dpcd[DP_RECEIVER_CAP_SIZE];

	bool powered;
};

static inline struct anx6345 *connector_to_anx6345(struct drm_connector *c)
{
	return container_of(c, struct anx6345, connector);
}

static inline struct anx6345 *bridge_to_anx6345(struct drm_bridge *bridge)
{
	return container_of(bridge, struct anx6345, bridge);
}

static int anx6345_set_bits(struct regmap *map, u8 reg, u8 mask)
{
	return regmap_update_bits(map, reg, mask, mask);
}

static int anx6345_clear_bits(struct regmap *map, u8 reg, u8 mask)
{
	return regmap_update_bits(map, reg, mask, 0);
}

static ssize_t anx6345_aux_transfer(struct drm_dp_aux *aux,
				    struct drm_dp_aux_msg *msg)
{
	struct anx6345 *anx6345 = container_of(aux, struct anx6345, aux);

	return anx_dp_aux_transfer(anx6345->map[I2C_IDX_DPTX], msg);
}

static int anx6345_dp_link_training(struct anx6345 *anx6345)
{
	unsigned int value;
	u8 dp_bw, dpcd[2];
	int err;

	err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
				 SP_POWERDOWN_CTRL_REG,
				 SP_TOTAL_PD);
	if (err)
		return err;

	err = drm_dp_dpcd_readb(&anx6345->aux, DP_MAX_LINK_RATE, &dp_bw);
	if (err < 0)
		return err;

	switch (dp_bw) {
	case DP_LINK_BW_1_62:
	case DP_LINK_BW_2_7:
		break;

	default:
		DRM_DEBUG_KMS("DP bandwidth (%#02x) not supported\n", dp_bw);
		return -EINVAL;
	}

	err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
			       SP_VIDEO_MUTE);
	if (err)
		return err;

	err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
				 SP_VID_CTRL1_REG, SP_VIDEO_EN);
	if (err)
		return err;

	/* Get DPCD info */
	err = drm_dp_dpcd_read(&anx6345->aux, DP_DPCD_REV,
			       &anx6345->dpcd, DP_RECEIVER_CAP_SIZE);
	if (err < 0) {
		DRM_ERROR("Failed to read DPCD: %d\n", err);
		return err;
	}

	/* Clear channel x SERDES power down */
	err = anx6345_clear_bits(anx6345->map[I2C_IDX_DPTX],
				 SP_DP_ANALOG_POWER_DOWN_REG, SP_CH0_PD);
	if (err)
		return err;

	/*
	 * Power up the sink (DP_SET_POWER register is only available on DPCD
	 * v1.1 and later).
	 */
	if (anx6345->dpcd[DP_DPCD_REV] >= 0x11) {
		err = drm_dp_dpcd_readb(&anx6345->aux, DP_SET_POWER, &dpcd[0]);
		if (err < 0) {
			DRM_ERROR("Failed to read DP_SET_POWER register: %d\n",
				  err);
			return err;
		}

		dpcd[0] &= ~DP_SET_POWER_MASK;
		dpcd[0] |= DP_SET_POWER_D0;

		err = drm_dp_dpcd_writeb(&anx6345->aux, DP_SET_POWER, dpcd[0]);
		if (err < 0) {
			DRM_ERROR("Failed to power up DisplayPort link: %d\n",
				  err);
			return err;
		}

		/*
		 * According to the DP 1.1 specification, a "Sink Device must
		 * exit the power saving state within 1 ms" (Section 2.5.3.1,
		 * Table 5-52, "Sink Control Field" (register 0x600).
		 */
		usleep_range(1000, 2000);
	}

	/* Possibly enable downspread on the sink */
	err = regmap_write(anx6345->map[I2C_IDX_DPTX],
			   SP_DP_DOWNSPREAD_CTRL1_REG, 0);
	if (err)
		return err;

	if (anx6345->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5) {
		DRM_DEBUG("Enable downspread on the sink\n");
		/* 4000PPM */
		err = regmap_write(anx6345->map[I2C_IDX_DPTX],
				   SP_DP_DOWNSPREAD_CTRL1_REG, 8);
		if (err)
			return err;

		err = drm_dp_dpcd_writeb(&anx6345->aux, DP_DOWNSPREAD_CTRL,
					 DP_SPREAD_AMP_0_5);
		if (err < 0)
			return err;
	} else {
		err = drm_dp_dpcd_writeb(&anx6345->aux, DP_DOWNSPREAD_CTRL, 0);
		if (err < 0)
			return err;
	}

	/* Set the lane count and the link rate on the sink */
	if (drm_dp_enhanced_frame_cap(anx6345->dpcd))
		err = anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
				       SP_DP_SYSTEM_CTRL_BASE + 4,
				       SP_ENHANCED_MODE);
	else
		err = anx6345_clear_bits(anx6345->map[I2C_IDX_DPTX],
					 SP_DP_SYSTEM_CTRL_BASE + 4,
					 SP_ENHANCED_MODE);
	if (err)
		return err;

	dpcd[0] = dp_bw;
	err = regmap_write(anx6345->map[I2C_IDX_DPTX],
			   SP_DP_MAIN_LINK_BW_SET_REG, dpcd[0]);
	if (err)
		return err;

	dpcd[1] = drm_dp_max_lane_count(anx6345->dpcd);

	err = regmap_write(anx6345->map[I2C_IDX_DPTX],
			   SP_DP_LANE_COUNT_SET_REG, dpcd[1]);
	if (err)
		return err;

	if (drm_dp_enhanced_frame_cap(anx6345->dpcd))
		dpcd[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;

	err = drm_dp_dpcd_write(&anx6345->aux, DP_LINK_BW_SET, dpcd,
				sizeof(dpcd));

	if (err < 0) {
		DRM_ERROR("Failed to configure link: %d\n", err);
		return err;
	}

	/* Start training on the source */
	err = regmap_write(anx6345->map[I2C_IDX_DPTX], SP_DP_LT_CTRL_REG,
			   SP_LT_EN);
	if (err)
		return err;

	return regmap_read_poll_timeout(anx6345->map[I2C_IDX_DPTX],
				       SP_DP_LT_CTRL_REG,
				       value, !(value & SP_DP_LT_INPROGRESS),
				       POLL_DELAY, POLL_TIMEOUT);
}

static int anx6345_tx_initialization(struct anx6345 *anx6345)
{
	int err, i;

	/* FIXME: colordepth is hardcoded for now */
	err = regmap_write(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL2_REG,
			   SP_IN_BPC_6BIT << SP_IN_BPC_SHIFT);
	if (err)
		return err;

	err = regmap_write(anx6345->map[I2C_IDX_DPTX], SP_DP_PLL_CTRL_REG, 0);
	if (err)
		return err;

	err = regmap_write(anx6345->map[I2C_IDX_TXCOM],
			   SP_ANALOG_DEBUG1_REG, 0);
	if (err)
		return err;

	err = regmap_write(anx6345->map[I2C_IDX_DPTX],
			   SP_DP_LINK_DEBUG_CTRL_REG,
			   SP_NEW_PRBS7 | SP_M_VID_DEBUG);
	if (err)
		return err;

	err = regmap_write(anx6345->map[I2C_IDX_DPTX],
			   SP_DP_ANALOG_POWER_DOWN_REG, 0);
	if (err)
		return err;

	/* Force HPD */
	err = anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
			       SP_DP_SYSTEM_CTRL_BASE + 3,
			       SP_HPD_FORCE | SP_HPD_CTRL);
	if (err)
		return err;

	for (i = 0; i < 4; i++) {
		/* 4 lanes */
		err = regmap_write(anx6345->map[I2C_IDX_DPTX],
				   SP_DP_LANE0_LT_CTRL_REG + i, 0);
		if (err)
			return err;
	}

	/* Reset AUX */
	err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM],
			       SP_RESET_CTRL2_REG, SP_AUX_RST);
	if (err)
		return err;

	return anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
				 SP_RESET_CTRL2_REG, SP_AUX_RST);
}

static void anx6345_poweron(struct anx6345 *anx6345)
{
	int err;

	/* Ensure reset is asserted before starting power on sequence */
	gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
	usleep_range(1000, 2000);

	err = regulator_enable(anx6345->dvdd12);
	if (err) {
		DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
			  err);
		return;
	}

	/* T1 - delay between VDD12 and VDD25 should be 0-2ms */
	usleep_range(1000, 2000);

	err = regulator_enable(anx6345->dvdd25);
	if (err) {
		DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
			  err);
		return;
	}

	/* T2 - delay between RESETN and all power rail stable,
	 * should be 2-5ms
	 */
	usleep_range(2000, 5000);

	gpiod_set_value_cansleep(anx6345->gpiod_reset, 0);

	/* Power on registers module */
	anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
			 SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD);
	anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
			   SP_REGISTER_PD | SP_TOTAL_PD);

	if (anx6345->panel)
		drm_panel_prepare(anx6345->panel);

	anx6345->powered = true;
}

static void anx6345_poweroff(struct anx6345 *anx6345)
{
	int err;

	gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
	usleep_range(1000, 2000);

	if (anx6345->panel)
		drm_panel_unprepare(anx6345->panel);

	err = regulator_disable(anx6345->dvdd25);
	if (err) {
		DRM_ERROR("Failed to disable dvdd25 regulator: %d\n",
			  err);
		return;
	}

	usleep_range(5000, 10000);

	err = regulator_disable(anx6345->dvdd12);
	if (err) {
		DRM_ERROR("Failed to disable dvdd12 regulator: %d\n",
			  err);
		return;
	}

	usleep_range(1000, 2000);

	anx6345->powered = false;
}

static int anx6345_start(struct anx6345 *anx6345)
{
	int err;

	if (!anx6345->powered)
		anx6345_poweron(anx6345);

	/* Power on needed modules */
	err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
				SP_POWERDOWN_CTRL_REG,
				SP_VIDEO_PD | SP_LINK_PD);

	err = anx6345_tx_initialization(anx6345);
	if (err) {
		DRM_ERROR("Failed eDP transmitter initialization: %d\n", err);
		anx6345_poweroff(anx6345);
		return err;
	}

	err = anx6345_dp_link_training(anx6345);
	if (err) {
		DRM_ERROR("Failed link training: %d\n", err);
		anx6345_poweroff(anx6345);
		return err;
	}

	/*
	 * This delay seems to help keep the hardware in a good state. Without
	 * it, there are times where it fails silently.
	 */
	usleep_range(10000, 15000);

	return 0;
}

static int anx6345_config_dp_output(struct anx6345 *anx6345)
{
	int err;

	err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
				 SP_VIDEO_MUTE);
	if (err)
		return err;

	/* Enable DP output */
	err = anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_VID_CTRL1_REG,
			       SP_VIDEO_EN);
	if (err)
		return err;

	/* Force stream valid */
	return anx6345_set_bits(anx6345->map[I2C_IDX_DPTX],
			       SP_DP_SYSTEM_CTRL_BASE + 3,
			       SP_STRM_FORCE | SP_STRM_CTRL);
}

static int anx6345_get_downstream_info(struct anx6345 *anx6345)
{
	u8 value;
	int err;

	err = drm_dp_dpcd_readb(&anx6345->aux, DP_SINK_COUNT, &value);
	if (err < 0) {
		DRM_ERROR("Get sink count failed %d\n", err);
		return err;
	}

	if (!DP_GET_SINK_COUNT(value)) {
		DRM_ERROR("Downstream disconnected\n");
		return -EIO;
	}

	return 0;
}

static int anx6345_get_modes(struct drm_connector *connector)
{
	struct anx6345 *anx6345 = connector_to_anx6345(connector);
	int err, num_modes = 0;
	bool power_off = false;

	mutex_lock(&anx6345->lock);

	if (!anx6345->edid) {
		if (!anx6345->powered) {
			anx6345_poweron(anx6345);
			power_off = true;
		}

		err = anx6345_get_downstream_info(anx6345);
		if (err) {
			DRM_ERROR("Failed to get downstream info: %d\n", err);
			goto unlock;
		}

		anx6345->edid = drm_get_edid(connector, &anx6345->aux.ddc);
		if (!anx6345->edid)
			DRM_ERROR("Failed to read EDID from panel\n");

		err = drm_connector_update_edid_property(connector,
							 anx6345->edid);
		if (err) {
			DRM_ERROR("Failed to update EDID property: %d\n", err);
			goto unlock;
		}
	}

	num_modes += drm_add_edid_modes(connector, anx6345->edid);

	/* Driver currently supports only 6bpc */
	connector->display_info.bpc = 6;

unlock:
	if (power_off)
		anx6345_poweroff(anx6345);

	mutex_unlock(&anx6345->lock);

	if (!num_modes && anx6345->panel)
		num_modes += drm_panel_get_modes(anx6345->panel, connector);

	return num_modes;
}

static const struct drm_connector_helper_funcs anx6345_connector_helper_funcs = {
	.get_modes = anx6345_get_modes,
};

static void
anx6345_connector_destroy(struct drm_connector *connector)
{
	drm_connector_cleanup(connector);
}

static const struct drm_connector_funcs anx6345_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = anx6345_connector_destroy,
	.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 int anx6345_bridge_attach(struct drm_bridge *bridge,
				 enum drm_bridge_attach_flags flags)
{
	struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
	int err;

	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
		DRM_ERROR("Fix bridge driver to make connector optional!");
		return -EINVAL;
	}

	if (!bridge->encoder) {
		DRM_ERROR("Parent encoder object not found");
		return -ENODEV;
	}

	/* Register aux channel */
	anx6345->aux.name = "DP-AUX";
	anx6345->aux.dev = &anx6345->client->dev;
	anx6345->aux.drm_dev = bridge->dev;
	anx6345->aux.transfer = anx6345_aux_transfer;

	err = drm_dp_aux_register(&anx6345->aux);
	if (err < 0) {
		DRM_ERROR("Failed to register aux channel: %d\n", err);
		return err;
	}

	err = drm_connector_init(bridge->dev, &anx6345->connector,
				 &anx6345_connector_funcs,
				 DRM_MODE_CONNECTOR_eDP);
	if (err) {
		DRM_ERROR("Failed to initialize connector: %d\n", err);
		goto aux_unregister;
	}

	drm_connector_helper_add(&anx6345->connector,
				 &anx6345_connector_helper_funcs);

	anx6345->connector.polled = DRM_CONNECTOR_POLL_HPD;

	err = drm_connector_attach_encoder(&anx6345->connector,
					   bridge->encoder);
	if (err) {
		DRM_ERROR("Failed to link up connector to encoder: %d\n", err);
		goto connector_cleanup;
	}

	err = drm_connector_register(&anx6345->connector);
	if (err) {
		DRM_ERROR("Failed to register connector: %d\n", err);
		goto connector_cleanup;
	}

	return 0;
connector_cleanup:
	drm_connector_cleanup(&anx6345->connector);
aux_unregister:
	drm_dp_aux_unregister(&anx6345->aux);
	return err;
}

static void anx6345_bridge_detach(struct drm_bridge *bridge)
{
	drm_dp_aux_unregister(&bridge_to_anx6345(bridge)->aux);
}

static enum drm_mode_status
anx6345_bridge_mode_valid(struct drm_bridge *bridge,
			  const struct drm_display_info *info,
			  const struct drm_display_mode *mode)
{
	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
		return MODE_NO_INTERLACE;

	/* Max 1200p at 5.4 Ghz, one lane */
	if (mode->clock > 154000)
		return MODE_CLOCK_HIGH;

	return MODE_OK;
}

static void anx6345_bridge_disable(struct drm_bridge *bridge)
{
	struct anx6345 *anx6345 = bridge_to_anx6345(bridge);

	/* Power off all modules except configuration registers access */
	anx6345_set_bits(anx6345->map[I2C_IDX_TXCOM], SP_POWERDOWN_CTRL_REG,
			 SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD);
	if (anx6345->panel)
		drm_panel_disable(anx6345->panel);

	if (anx6345->powered)
		anx6345_poweroff(anx6345);
}

static void anx6345_bridge_enable(struct drm_bridge *bridge)
{
	struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
	int err;

	if (anx6345->panel)
		drm_panel_enable(anx6345->panel);

	err = anx6345_start(anx6345);
	if (err) {
		DRM_ERROR("Failed to initialize: %d\n", err);
		return;
	}

	err = anx6345_config_dp_output(anx6345);
	if (err)
		DRM_ERROR("Failed to enable DP output: %d\n", err);
}

static const struct drm_bridge_funcs anx6345_bridge_funcs = {
	.attach = anx6345_bridge_attach,
	.detach = anx6345_bridge_detach,
	.mode_valid = anx6345_bridge_mode_valid,
	.disable = anx6345_bridge_disable,
	.enable = anx6345_bridge_enable,
};

static void unregister_i2c_dummy_clients(struct anx6345 *anx6345)
{
	unsigned int i;

	for (i = 1; i < ARRAY_SIZE(anx6345->i2c_clients); i++)
		if (anx6345->i2c_clients[i] &&
		    anx6345->i2c_clients[i]->addr != anx6345->client->addr)
			i2c_unregister_device(anx6345->i2c_clients[i]);
}

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

static const u16 anx6345_chipid_list[] = {
	0x6345,
};

static bool anx6345_get_chip_id(struct anx6345 *anx6345)
{
	unsigned int i, idl, idh, version;

	if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_IDL_REG, &idl))
		return false;

	if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_IDH_REG, &idh))
		return false;

	anx6345->chipid = (u8)idl | ((u8)idh << 8);

	if (regmap_read(anx6345->map[I2C_IDX_TXCOM], SP_DEVICE_VERSION_REG,
			&version))
		return false;

	for (i = 0; i < ARRAY_SIZE(anx6345_chipid_list); i++) {
		if (anx6345->chipid == anx6345_chipid_list[i]) {
			DRM_INFO("Found ANX%x (ver. %d) eDP Transmitter\n",
				 anx6345->chipid, version);
			return true;
		}
	}

	DRM_ERROR("ANX%x (ver. %d) not supported by this driver\n",
		  anx6345->chipid, version);

	return false;
}

static int anx6345_i2c_probe(struct i2c_client *client)
{
	struct anx6345 *anx6345;
	struct device *dev;
	int i, err;

	anx6345 = devm_kzalloc(&client->dev, sizeof(*anx6345), GFP_KERNEL);
	if (!anx6345)
		return -ENOMEM;

	mutex_init(&anx6345->lock);

	anx6345->bridge.of_node = client->dev.of_node;

	anx6345->client = client;
	i2c_set_clientdata(client, anx6345);

	dev = &anx6345->client->dev;

	err = drm_of_find_panel_or_bridge(client->dev.of_node, 1, 0,
					  &anx6345->panel, NULL);
	if (err == -EPROBE_DEFER)
		return err;

	if (err)
		DRM_DEBUG("No panel found\n");

	/* 1.2V digital core power regulator  */
	anx6345->dvdd12 = devm_regulator_get(dev, "dvdd12");
	if (IS_ERR(anx6345->dvdd12)) {
		if (PTR_ERR(anx6345->dvdd12) != -EPROBE_DEFER)
			DRM_ERROR("Failed to get dvdd12 supply (%ld)\n",
				  PTR_ERR(anx6345->dvdd12));
		return PTR_ERR(anx6345->dvdd12);
	}

	/* 2.5V digital core power regulator  */
	anx6345->dvdd25 = devm_regulator_get(dev, "dvdd25");
	if (IS_ERR(anx6345->dvdd25)) {
		if (PTR_ERR(anx6345->dvdd25) != -EPROBE_DEFER)
			DRM_ERROR("Failed to get dvdd25 supply (%ld)\n",
				  PTR_ERR(anx6345->dvdd25));
		return PTR_ERR(anx6345->dvdd25);
	}

	/* GPIO for chip reset */
	anx6345->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(anx6345->gpiod_reset)) {
		DRM_ERROR("Reset gpio not found\n");
		return PTR_ERR(anx6345->gpiod_reset);
	}

	/* Map slave addresses of ANX6345 */
	for (i = 0; i < I2C_NUM_ADDRESSES; i++) {
		if (anx6345_i2c_addresses[i] >> 1 != client->addr)
			anx6345->i2c_clients[i] = i2c_new_dummy_device(client->adapter,
						anx6345_i2c_addresses[i] >> 1);
		else
			anx6345->i2c_clients[i] = client;

		if (IS_ERR(anx6345->i2c_clients[i])) {
			err = PTR_ERR(anx6345->i2c_clients[i]);
			DRM_ERROR("Failed to reserve I2C bus %02x\n",
				  anx6345_i2c_addresses[i]);
			goto err_unregister_i2c;
		}

		anx6345->map[i] = devm_regmap_init_i2c(anx6345->i2c_clients[i],
						       &anx6345_regmap_config);
		if (IS_ERR(anx6345->map[i])) {
			err = PTR_ERR(anx6345->map[i]);
			DRM_ERROR("Failed regmap initialization %02x\n",
				  anx6345_i2c_addresses[i]);
			goto err_unregister_i2c;
		}
	}

	/* Look for supported chip ID */
	anx6345_poweron(anx6345);
	if (anx6345_get_chip_id(anx6345)) {
		anx6345->bridge.funcs = &anx6345_bridge_funcs;
		drm_bridge_add(&anx6345->bridge);

		return 0;
	} else {
		anx6345_poweroff(anx6345);
		err = -ENODEV;
	}

err_unregister_i2c:
	unregister_i2c_dummy_clients(anx6345);
	return err;
}

static void anx6345_i2c_remove(struct i2c_client *client)
{
	struct anx6345 *anx6345 = i2c_get_clientdata(client);

	drm_bridge_remove(&anx6345->bridge);

	unregister_i2c_dummy_clients(anx6345);

	kfree(anx6345->edid);

	mutex_destroy(&anx6345->lock);
}

static const struct i2c_device_id anx6345_id[] = {
	{ "anx6345", 0 },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, anx6345_id);

static const struct of_device_id anx6345_match_table[] = {
	{ .compatible = "analogix,anx6345", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, anx6345_match_table);

static struct i2c_driver anx6345_driver = {
	.driver = {
		   .name = "anx6345",
		   .of_match_table = anx6345_match_table,
		  },
	.probe = anx6345_i2c_probe,
	.remove = anx6345_i2c_remove,
	.id_table = anx6345_id,
};
module_i2c_driver(anx6345_driver);

MODULE_DESCRIPTION("ANX6345 eDP Transmitter driver");
MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.io>");
MODULE_LICENSE("GPL v2");
