// SPDX-License-Identifier: GPL-2.0-only
/*
 * Chrontel CH7033 Video Encoder Driver
 *
 * Copyright (C) 2019,2020 Lubomir Rintel
 */

#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>

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

/* Page 0, Register 0x07 */
enum {
	DRI_PD		= BIT(3),
	IO_PD		= BIT(5),
};

/* Page 0, Register 0x08 */
enum {
	DRI_PDDRI	= GENMASK(7, 4),
	PDDAC		= GENMASK(3, 1),
	PANEN		= BIT(0),
};

/* Page 0, Register 0x09 */
enum {
	DPD		= BIT(7),
	GCKOFF		= BIT(6),
	TV_BP		= BIT(5),
	SCLPD		= BIT(4),
	SDPD		= BIT(3),
	VGA_PD		= BIT(2),
	HDBKPD		= BIT(1),
	HDMI_PD		= BIT(0),
};

/* Page 0, Register 0x0a */
enum {
	MEMINIT		= BIT(7),
	MEMIDLE		= BIT(6),
	MEMPD		= BIT(5),
	STOP		= BIT(4),
	LVDS_PD		= BIT(3),
	HD_DVIB		= BIT(2),
	HDCP_PD		= BIT(1),
	MCU_PD		= BIT(0),
};

/* Page 0, Register 0x18 */
enum {
	IDF		= GENMASK(7, 4),
	INTEN		= BIT(3),
	SWAP		= GENMASK(2, 0),
};

enum {
	BYTE_SWAP_RGB	= 0,
	BYTE_SWAP_RBG	= 1,
	BYTE_SWAP_GRB	= 2,
	BYTE_SWAP_GBR	= 3,
	BYTE_SWAP_BRG	= 4,
	BYTE_SWAP_BGR	= 5,
};

/* Page 0, Register 0x19 */
enum {
	HPO_I		= BIT(5),
	VPO_I		= BIT(4),
	DEPO_I		= BIT(3),
	CRYS_EN		= BIT(2),
	GCLKFREQ	= GENMASK(2, 0),
};

/* Page 0, Register 0x2e */
enum {
	HFLIP		= BIT(7),
	VFLIP		= BIT(6),
	DEPO_O		= BIT(5),
	HPO_O		= BIT(4),
	VPO_O		= BIT(3),
	TE		= GENMASK(2, 0),
};

/* Page 0, Register 0x2b */
enum {
	SWAPS		= GENMASK(7, 4),
	VFMT		= GENMASK(3, 0),
};

/* Page 0, Register 0x54 */
enum {
	COMP_BP		= BIT(7),
	DAC_EN_T	= BIT(6),
	HWO_HDMI_HI	= GENMASK(5, 3),
	HOO_HDMI_HI	= GENMASK(2, 0),
};

/* Page 0, Register 0x57 */
enum {
	FLDSEN		= BIT(7),
	VWO_HDMI_HI	= GENMASK(5, 3),
	VOO_HDMI_HI	= GENMASK(2, 0),
};

/* Page 0, Register 0x7e */
enum {
	HDMI_LVDS_SEL	= BIT(7),
	DE_GEN		= BIT(6),
	PWM_INDEX_HI	= BIT(5),
	USE_DE		= BIT(4),
	R_INT		= GENMASK(3, 0),
};

/* Page 1, Register 0x07 */
enum {
	BPCKSEL		= BIT(7),
	DRI_CMFB_EN	= BIT(6),
	CEC_PUEN	= BIT(5),
	CEC_T		= BIT(3),
	CKINV		= BIT(2),
	CK_TVINV	= BIT(1),
	DRI_CKS2	= BIT(0),
};

/* Page 1, Register 0x08 */
enum {
	DACG		= BIT(6),
	DACKTST		= BIT(5),
	DEDGEB		= BIT(4),
	SYO		= BIT(3),
	DRI_IT_LVDS	= GENMASK(2, 1),
	DISPON		= BIT(0),
};

/* Page 1, Register 0x0c */
enum {
	DRI_PLL_CP	= GENMASK(7, 6),
	DRI_PLL_DIVSEL	= BIT(5),
	DRI_PLL_N1_1	= BIT(4),
	DRI_PLL_N1_0	= BIT(3),
	DRI_PLL_N3_1	= BIT(2),
	DRI_PLL_N3_0	= BIT(1),
	DRI_PLL_CKTSTEN = BIT(0),
};

/* Page 1, Register 0x6b */
enum {
	VCO3CS		= GENMASK(7, 6),
	ICPGBK2_0	= GENMASK(5, 3),
	DRI_VCO357SC	= BIT(2),
	PDPLL2		= BIT(1),
	DRI_PD_SER	= BIT(0),
};

/* Page 1, Register 0x6c */
enum {
	PLL2N11		= GENMASK(7, 4),
	PLL2N5_4	= BIT(3),
	PLL2N5_TOP	= BIT(2),
	DRI_PLL_PD	= BIT(1),
	PD_I2CM		= BIT(0),
};

/* Page 3, Register 0x28 */
enum {
	DIFF_EN		= GENMASK(7, 6),
	CORREC_EN	= GENMASK(5, 4),
	VGACLK_BP	= BIT(3),
	HM_LV_SEL	= BIT(2),
	HD_VGA_SEL	= BIT(1),
};

/* Page 3, Register 0x2a */
enum {
	LVDSCLK_BP	= BIT(7),
	HDTVCLK_BP	= BIT(6),
	HDMICLK_BP	= BIT(5),
	HDTV_BP		= BIT(4),
	HDMI_BP		= BIT(3),
	THRWL		= GENMASK(2, 0),
};

/* Page 4, Register 0x52 */
enum {
	PGM_ARSTB	= BIT(7),
	MCU_ARSTB	= BIT(6),
	MCU_RETB	= BIT(2),
	RESETIB		= BIT(1),
	RESETDB		= BIT(0),
};

struct ch7033_priv {
	struct regmap *regmap;
	struct drm_bridge *next_bridge;
	struct drm_bridge bridge;
	struct drm_connector connector;
};

#define conn_to_ch7033_priv(x) \
	container_of(x, struct ch7033_priv, connector)
#define bridge_to_ch7033_priv(x) \
	container_of(x, struct ch7033_priv, bridge)


static enum drm_connector_status ch7033_connector_detect(
	struct drm_connector *connector, bool force)
{
	struct ch7033_priv *priv = conn_to_ch7033_priv(connector);

	return drm_bridge_detect(priv->next_bridge);
}

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

static int ch7033_connector_get_modes(struct drm_connector *connector)
{
	struct ch7033_priv *priv = conn_to_ch7033_priv(connector);
	const struct drm_edid *drm_edid;
	int ret;

	drm_edid = drm_bridge_edid_read(priv->next_bridge, connector);
	drm_edid_connector_update(connector, drm_edid);
	if (drm_edid) {
		ret = drm_edid_connector_add_modes(connector);
		drm_edid_free(drm_edid);
	} else {
		ret = drm_add_modes_noedid(connector, 1920, 1080);
		drm_set_preferred_mode(connector, 1024, 768);
	}

	return ret;
}

static struct drm_encoder *ch7033_connector_best_encoder(
			struct drm_connector *connector)
{
	struct ch7033_priv *priv = conn_to_ch7033_priv(connector);

	return priv->bridge.encoder;
}

static const struct drm_connector_helper_funcs ch7033_connector_helper_funcs = {
	.get_modes = ch7033_connector_get_modes,
	.best_encoder = ch7033_connector_best_encoder,
};

static void ch7033_hpd_event(void *arg, enum drm_connector_status status)
{
	struct ch7033_priv *priv = arg;

	if (priv->bridge.dev)
		drm_helper_hpd_irq_event(priv->connector.dev);
}

static int ch7033_bridge_attach(struct drm_bridge *bridge,
				enum drm_bridge_attach_flags flags)
{
	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
	struct drm_connector *connector = &priv->connector;
	int ret;

	ret = drm_bridge_attach(bridge->encoder, priv->next_bridge, bridge,
				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
	if (ret)
		return ret;

	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
		return 0;

	if (priv->next_bridge->ops & DRM_BRIDGE_OP_DETECT) {
		connector->polled = DRM_CONNECTOR_POLL_HPD;
	} else {
		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
				    DRM_CONNECTOR_POLL_DISCONNECT;
	}

	if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD) {
		drm_bridge_hpd_enable(priv->next_bridge, ch7033_hpd_event,
				      priv);
	}

	drm_connector_helper_add(connector,
				 &ch7033_connector_helper_funcs);
	ret = drm_connector_init_with_ddc(bridge->dev, &priv->connector,
					  &ch7033_connector_funcs,
					  priv->next_bridge->type,
					  priv->next_bridge->ddc);
	if (ret) {
		DRM_ERROR("Failed to initialize connector\n");
		return ret;
	}

	return drm_connector_attach_encoder(&priv->connector, bridge->encoder);
}

static void ch7033_bridge_detach(struct drm_bridge *bridge)
{
	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);

	if (priv->next_bridge->ops & DRM_BRIDGE_OP_HPD)
		drm_bridge_hpd_disable(priv->next_bridge);
	drm_connector_cleanup(&priv->connector);
}

static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
				     const struct drm_display_info *info,
				     const struct drm_display_mode *mode)
{
	if (mode->clock > 165000)
		return MODE_CLOCK_HIGH;
	if (mode->hdisplay >= 1920)
		return MODE_BAD_HVALUE;
	if (mode->vdisplay >= 1080)
		return MODE_BAD_VVALUE;
	return MODE_OK;
}

static void ch7033_bridge_disable(struct drm_bridge *bridge)
{
	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);

	regmap_write(priv->regmap, 0x03, 0x04);
	regmap_update_bits(priv->regmap, 0x52, RESETDB, 0x00);
}

static void ch7033_bridge_enable(struct drm_bridge *bridge)
{
	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);

	regmap_write(priv->regmap, 0x03, 0x04);
	regmap_update_bits(priv->regmap, 0x52, RESETDB, RESETDB);
}

static void ch7033_bridge_mode_set(struct drm_bridge *bridge,
				   const struct drm_display_mode *mode,
				   const struct drm_display_mode *adjusted_mode)
{
	struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge);
	int hbporch = mode->hsync_start - mode->hdisplay;
	int hsynclen = mode->hsync_end - mode->hsync_start;
	int vbporch = mode->vsync_start - mode->vdisplay;
	int vsynclen = mode->vsync_end - mode->vsync_start;

	/*
	 * Page 4
	 */
	regmap_write(priv->regmap, 0x03, 0x04);

	/* Turn everything off to set all the registers to their defaults. */
	regmap_write(priv->regmap, 0x52, 0x00);
	/* Bring I/O block up. */
	regmap_write(priv->regmap, 0x52, RESETIB);

	/*
	 * Page 0
	 */
	regmap_write(priv->regmap, 0x03, 0x00);

	/* Bring up parts we need from the power down. */
	regmap_update_bits(priv->regmap, 0x07, DRI_PD | IO_PD, 0);
	regmap_update_bits(priv->regmap, 0x08, DRI_PDDRI | PDDAC | PANEN, 0);
	regmap_update_bits(priv->regmap, 0x09, DPD | GCKOFF |
					       HDMI_PD | VGA_PD, 0);
	regmap_update_bits(priv->regmap, 0x0a, HD_DVIB, 0);

	/* Horizontal input timing. */
	regmap_write(priv->regmap, 0x0b, (mode->htotal >> 8) << 3 |
					 (mode->hdisplay >> 8));
	regmap_write(priv->regmap, 0x0c, mode->hdisplay);
	regmap_write(priv->regmap, 0x0d, mode->htotal);
	regmap_write(priv->regmap, 0x0e, (hsynclen >> 8) << 3 |
					 (hbporch >> 8));
	regmap_write(priv->regmap, 0x0f, hbporch);
	regmap_write(priv->regmap, 0x10, hsynclen);

	/* Vertical input timing. */
	regmap_write(priv->regmap, 0x11, (mode->vtotal >> 8) << 3 |
					 (mode->vdisplay >> 8));
	regmap_write(priv->regmap, 0x12, mode->vdisplay);
	regmap_write(priv->regmap, 0x13, mode->vtotal);
	regmap_write(priv->regmap, 0x14, ((vsynclen >> 8) << 3) |
					 (vbporch >> 8));
	regmap_write(priv->regmap, 0x15, vbporch);
	regmap_write(priv->regmap, 0x16, vsynclen);

	/* Input color swap. */
	regmap_update_bits(priv->regmap, 0x18, SWAP, BYTE_SWAP_BGR);

	/* Input clock and sync polarity. */
	regmap_update_bits(priv->regmap, 0x19, 0x1, mode->clock >> 16);
	regmap_update_bits(priv->regmap, 0x19, HPO_I | VPO_I | GCLKFREQ,
			   (mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_I : 0 |
			   (mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_I : 0 |
			   mode->clock >> 16);
	regmap_write(priv->regmap, 0x1a, mode->clock >> 8);
	regmap_write(priv->regmap, 0x1b, mode->clock);

	/* Horizontal output timing. */
	regmap_write(priv->regmap, 0x1f, (mode->htotal >> 8) << 3 |
					 (mode->hdisplay >> 8));
	regmap_write(priv->regmap, 0x20, mode->hdisplay);
	regmap_write(priv->regmap, 0x21, mode->htotal);

	/* Vertical output timing. */
	regmap_write(priv->regmap, 0x25, (mode->vtotal >> 8) << 3 |
					 (mode->vdisplay >> 8));
	regmap_write(priv->regmap, 0x26, mode->vdisplay);
	regmap_write(priv->regmap, 0x27, mode->vtotal);

	/* VGA channel bypass */
	regmap_update_bits(priv->regmap, 0x2b, VFMT, 9);

	/* Output sync polarity. */
	regmap_update_bits(priv->regmap, 0x2e, HPO_O | VPO_O,
			   (mode->flags & DRM_MODE_FLAG_PHSYNC) ? HPO_O : 0 |
			   (mode->flags & DRM_MODE_FLAG_PVSYNC) ? VPO_O : 0);

	/* HDMI horizontal output timing. */
	regmap_update_bits(priv->regmap, 0x54, HWO_HDMI_HI | HOO_HDMI_HI,
					       (hsynclen >> 8) << 3 |
					       (hbporch >> 8));
	regmap_write(priv->regmap, 0x55, hbporch);
	regmap_write(priv->regmap, 0x56, hsynclen);

	/* HDMI vertical output timing. */
	regmap_update_bits(priv->regmap, 0x57, VWO_HDMI_HI | VOO_HDMI_HI,
					       (vsynclen >> 8) << 3 |
					       (vbporch >> 8));
	regmap_write(priv->regmap, 0x58, vbporch);
	regmap_write(priv->regmap, 0x59, vsynclen);

	/* Pick HDMI, not LVDS. */
	regmap_update_bits(priv->regmap, 0x7e, HDMI_LVDS_SEL, HDMI_LVDS_SEL);

	/*
	 * Page 1
	 */
	regmap_write(priv->regmap, 0x03, 0x01);

	/* No idea what these do, but VGA is wobbly and blinky without them. */
	regmap_update_bits(priv->regmap, 0x07, CKINV, CKINV);
	regmap_update_bits(priv->regmap, 0x08, DISPON, DISPON);

	/* DRI PLL */
	regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_DIVSEL, DRI_PLL_DIVSEL);
	if (mode->clock <= 40000) {
		regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
						       DRI_PLL_N1_0 |
						       DRI_PLL_N3_1 |
						       DRI_PLL_N3_0,
						       0);
	} else if (mode->clock < 80000) {
		regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
						       DRI_PLL_N1_0 |
						       DRI_PLL_N3_1 |
						       DRI_PLL_N3_0,
						       DRI_PLL_N3_0 |
						       DRI_PLL_N1_0);
	} else {
		regmap_update_bits(priv->regmap, 0x0c, DRI_PLL_N1_1 |
						       DRI_PLL_N1_0 |
						       DRI_PLL_N3_1 |
						       DRI_PLL_N3_0,
						       DRI_PLL_N3_1 |
						       DRI_PLL_N1_1);
	}

	/* This seems to be color calibration for VGA. */
	regmap_write(priv->regmap, 0x64, 0x29); /* LSB Blue */
	regmap_write(priv->regmap, 0x65, 0x29); /* LSB Green */
	regmap_write(priv->regmap, 0x66, 0x29); /* LSB Red */
	regmap_write(priv->regmap, 0x67, 0x00); /* MSB Blue */
	regmap_write(priv->regmap, 0x68, 0x00); /* MSB Green */
	regmap_write(priv->regmap, 0x69, 0x00); /* MSB Red */

	regmap_update_bits(priv->regmap, 0x6b, DRI_PD_SER, 0x00);
	regmap_update_bits(priv->regmap, 0x6c, DRI_PLL_PD, 0x00);

	/*
	 * Page 3
	 */
	regmap_write(priv->regmap, 0x03, 0x03);

	/* More bypasses and apparently another HDMI/LVDS selector. */
	regmap_update_bits(priv->regmap, 0x28, VGACLK_BP | HM_LV_SEL,
					       VGACLK_BP | HM_LV_SEL);
	regmap_update_bits(priv->regmap, 0x2a, HDMICLK_BP | HDMI_BP,
					       HDMICLK_BP | HDMI_BP);

	/*
	 * Page 4
	 */
	regmap_write(priv->regmap, 0x03, 0x04);

	/* Output clock. */
	regmap_write(priv->regmap, 0x10, mode->clock >> 16);
	regmap_write(priv->regmap, 0x11, mode->clock >> 8);
	regmap_write(priv->regmap, 0x12, mode->clock);
}

static const struct drm_bridge_funcs ch7033_bridge_funcs = {
	.attach = ch7033_bridge_attach,
	.detach = ch7033_bridge_detach,
	.mode_valid = ch7033_bridge_mode_valid,
	.disable = ch7033_bridge_disable,
	.enable = ch7033_bridge_enable,
	.mode_set = ch7033_bridge_mode_set,
};

static const struct regmap_config ch7033_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0x7f,
};

static int ch7033_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ch7033_priv *priv;
	unsigned int val;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	dev_set_drvdata(dev, priv);

	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
					  &priv->next_bridge);
	if (ret)
		return ret;

	priv->regmap = devm_regmap_init_i2c(client, &ch7033_regmap_config);
	if (IS_ERR(priv->regmap)) {
		dev_err(&client->dev, "regmap init failed\n");
		return PTR_ERR(priv->regmap);
	}

	ret = regmap_read(priv->regmap, 0x00, &val);
	if (ret < 0) {
		dev_err(&client->dev, "error reading the model id: %d\n", ret);
		return ret;
	}
	if ((val & 0xf7) != 0x56) {
		dev_err(&client->dev, "the device is not a ch7033\n");
		return -ENODEV;
	}

	regmap_write(priv->regmap, 0x03, 0x04);
	ret = regmap_read(priv->regmap, 0x51, &val);
	if (ret < 0) {
		dev_err(&client->dev, "error reading the model id: %d\n", ret);
		return ret;
	}
	if ((val & 0x0f) != 3) {
		dev_err(&client->dev, "unknown revision %u\n", val);
		return -ENODEV;
	}

	INIT_LIST_HEAD(&priv->bridge.list);
	priv->bridge.funcs = &ch7033_bridge_funcs;
	priv->bridge.of_node = dev->of_node;
	drm_bridge_add(&priv->bridge);

	dev_info(dev, "Chrontel CH7033 Video Encoder\n");
	return 0;
}

static void ch7033_remove(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ch7033_priv *priv = dev_get_drvdata(dev);

	drm_bridge_remove(&priv->bridge);
}

static const struct of_device_id ch7033_dt_ids[] = {
	{ .compatible = "chrontel,ch7033", },
	{ }
};
MODULE_DEVICE_TABLE(of, ch7033_dt_ids);

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

static struct i2c_driver ch7033_driver = {
	.probe = ch7033_probe,
	.remove = ch7033_remove,
	.driver = {
		.name = "ch7033",
		.of_match_table = ch7033_dt_ids,
	},
	.id_table = ch7033_ids,
};

module_i2c_driver(ch7033_driver);

MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("Chrontel CH7033 Video Encoder Driver");
MODULE_LICENSE("GPL v2");
