/* 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/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_dp_helper.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] = drm_dp_max_link_rate(anx6345->dpcd);
	dpcd[0] = drm_dp_link_rate_to_bw_code(dpcd[0]);
	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);

unlock:
	if (power_off)
		anx6345_poweroff(anx6345);

	mutex_unlock(&anx6345->lock);

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

	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)
{
	struct anx6345 *anx6345 = connector_to_anx6345(connector);

	if (anx6345->panel)
		drm_panel_detach(anx6345->panel);
	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)
{
	struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
	int err;

	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.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);
		return err;
	}

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

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

	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);
		return err;
	}

	if (anx6345->panel) {
		err = drm_panel_attach(anx6345->panel, &anx6345->connector);
		if (err) {
			DRM_ERROR("Failed to attach panel: %d\n", err);
			return err;
		}
	}

	return 0;
}

static enum drm_mode_status
anx6345_bridge_mode_valid(struct drm_bridge *bridge,
			  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,
	.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,
			     const struct i2c_device_id *id)
{
	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-supply");
	if (IS_ERR(anx6345->dvdd12)) {
		DRM_ERROR("dvdd12-supply not found\n");
		return PTR_ERR(anx6345->dvdd12);
	}

	/* 2.5V digital core power regulator  */
	anx6345->dvdd25 = devm_regulator_get(dev, "dvdd25-supply");
	if (IS_ERR(anx6345->dvdd25)) {
		DRM_ERROR("dvdd25-supply not found\n");
		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(client->adapter,
						anx6345_i2c_addresses[i] >> 1);
		else
			anx6345->i2c_clients[i] = client;

		if (!anx6345->i2c_clients[i]) {
			err = -ENOMEM;
			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 int 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);

	return 0;
}

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 = of_match_ptr(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");
