/*
 * Copyright 2016 Linaro Ltd.
 * Copyright 2016 ZTE Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/hdmi.h>
#include <linux/irq.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drmP.h>

#include <sound/hdmi-codec.h>

#include "zx_hdmi_regs.h"
#include "zx_vou.h"

#define ZX_HDMI_INFOFRAME_SIZE		31
#define DDC_SEGMENT_ADDR		0x30

struct zx_hdmi_i2c {
	struct i2c_adapter adap;
	struct mutex lock;
};

struct zx_hdmi {
	struct drm_connector connector;
	struct drm_encoder encoder;
	struct zx_hdmi_i2c *ddc;
	struct device *dev;
	struct drm_device *drm;
	void __iomem *mmio;
	struct clk *cec_clk;
	struct clk *osc_clk;
	struct clk *xclk;
	bool sink_is_hdmi;
	bool sink_has_audio;
	struct platform_device *audio_pdev;
};

#define to_zx_hdmi(x) container_of(x, struct zx_hdmi, x)

static inline u8 hdmi_readb(struct zx_hdmi *hdmi, u16 offset)
{
	return readl_relaxed(hdmi->mmio + offset * 4);
}

static inline void hdmi_writeb(struct zx_hdmi *hdmi, u16 offset, u8 val)
{
	writel_relaxed(val, hdmi->mmio + offset * 4);
}

static inline void hdmi_writeb_mask(struct zx_hdmi *hdmi, u16 offset,
				    u8 mask, u8 val)
{
	u8 tmp;

	tmp = hdmi_readb(hdmi, offset);
	tmp = (tmp & ~mask) | (val & mask);
	hdmi_writeb(hdmi, offset, tmp);
}

static int zx_hdmi_infoframe_trans(struct zx_hdmi *hdmi,
				   union hdmi_infoframe *frame, u8 fsel)
{
	u8 buffer[ZX_HDMI_INFOFRAME_SIZE];
	int num;
	int i;

	hdmi_writeb(hdmi, TPI_INFO_FSEL, fsel);

	num = hdmi_infoframe_pack(frame, buffer, ZX_HDMI_INFOFRAME_SIZE);
	if (num < 0) {
		DRM_DEV_ERROR(hdmi->dev, "failed to pack infoframe: %d\n", num);
		return num;
	}

	for (i = 0; i < num; i++)
		hdmi_writeb(hdmi, TPI_INFO_B0 + i, buffer[i]);

	hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_RPT,
			 TPI_INFO_TRANS_RPT);
	hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_EN,
			 TPI_INFO_TRANS_EN);

	return num;
}

static int zx_hdmi_config_video_vsi(struct zx_hdmi *hdmi,
				    struct drm_display_mode *mode)
{
	union hdmi_infoframe frame;
	int ret;

	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
							  mode);
	if (ret) {
		DRM_DEV_ERROR(hdmi->dev, "failed to get vendor infoframe: %d\n",
			      ret);
		return ret;
	}

	return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_VSIF);
}

static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi,
				    struct drm_display_mode *mode)
{
	union hdmi_infoframe frame;
	int ret;

	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
	if (ret) {
		DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n",
			      ret);
		return ret;
	}

	/* We always use YUV444 for HDMI output. */
	frame.avi.colorspace = HDMI_COLORSPACE_YUV444;

	return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AVI);
}

static void zx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
				     struct drm_display_mode *mode,
				     struct drm_display_mode *adj_mode)
{
	struct zx_hdmi *hdmi = to_zx_hdmi(encoder);

	if (hdmi->sink_is_hdmi) {
		zx_hdmi_config_video_avi(hdmi, mode);
		zx_hdmi_config_video_vsi(hdmi, mode);
	}
}

static void zx_hdmi_phy_start(struct zx_hdmi *hdmi)
{
	/* Copy from ZTE BSP code */
	hdmi_writeb(hdmi, 0x222, 0x0);
	hdmi_writeb(hdmi, 0x224, 0x4);
	hdmi_writeb(hdmi, 0x909, 0x0);
	hdmi_writeb(hdmi, 0x7b0, 0x90);
	hdmi_writeb(hdmi, 0x7b1, 0x00);
	hdmi_writeb(hdmi, 0x7b2, 0xa7);
	hdmi_writeb(hdmi, 0x7b8, 0xaa);
	hdmi_writeb(hdmi, 0x7b2, 0xa7);
	hdmi_writeb(hdmi, 0x7b3, 0x0f);
	hdmi_writeb(hdmi, 0x7b4, 0x0f);
	hdmi_writeb(hdmi, 0x7b5, 0x55);
	hdmi_writeb(hdmi, 0x7b7, 0x03);
	hdmi_writeb(hdmi, 0x7b9, 0x12);
	hdmi_writeb(hdmi, 0x7ba, 0x32);
	hdmi_writeb(hdmi, 0x7bc, 0x68);
	hdmi_writeb(hdmi, 0x7be, 0x40);
	hdmi_writeb(hdmi, 0x7bf, 0x84);
	hdmi_writeb(hdmi, 0x7c1, 0x0f);
	hdmi_writeb(hdmi, 0x7c8, 0x02);
	hdmi_writeb(hdmi, 0x7c9, 0x03);
	hdmi_writeb(hdmi, 0x7ca, 0x40);
	hdmi_writeb(hdmi, 0x7dc, 0x31);
	hdmi_writeb(hdmi, 0x7e2, 0x04);
	hdmi_writeb(hdmi, 0x7e0, 0x06);
	hdmi_writeb(hdmi, 0x7cb, 0x68);
	hdmi_writeb(hdmi, 0x7f9, 0x02);
	hdmi_writeb(hdmi, 0x7b6, 0x02);
	hdmi_writeb(hdmi, 0x7f3, 0x0);
}

static void zx_hdmi_hw_enable(struct zx_hdmi *hdmi)
{
	/* Enable pclk */
	hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, CLKPWD_PDIDCK);

	/* Enable HDMI for TX */
	hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, FUNC_HDMI_EN);

	/* Enable deep color packet */
	hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN);

	/* Enable HDMI/MHL mode for output */
	hdmi_writeb_mask(hdmi, TEST_TXCTRL, TEST_TXCTRL_HDMI_MODE,
			 TEST_TXCTRL_HDMI_MODE);

	/* Configure reg_qc_sel */
	hdmi_writeb(hdmi, HDMICTL4, 0x3);

	/* Enable interrupt */
	hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT,
			 INTR1_MONITOR_DETECT);

	/* Start up phy */
	zx_hdmi_phy_start(hdmi);
}

static void zx_hdmi_hw_disable(struct zx_hdmi *hdmi)
{
	/* Disable interrupt */
	hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT, 0);

	/* Disable deep color packet */
	hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN);

	/* Disable HDMI for TX */
	hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, 0);

	/* Disable pclk */
	hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, 0);
}

static void zx_hdmi_encoder_enable(struct drm_encoder *encoder)
{
	struct zx_hdmi *hdmi = to_zx_hdmi(encoder);

	clk_prepare_enable(hdmi->cec_clk);
	clk_prepare_enable(hdmi->osc_clk);
	clk_prepare_enable(hdmi->xclk);

	zx_hdmi_hw_enable(hdmi);

	vou_inf_enable(VOU_HDMI, encoder->crtc);
}

static void zx_hdmi_encoder_disable(struct drm_encoder *encoder)
{
	struct zx_hdmi *hdmi = to_zx_hdmi(encoder);

	vou_inf_disable(VOU_HDMI, encoder->crtc);

	zx_hdmi_hw_disable(hdmi);

	clk_disable_unprepare(hdmi->xclk);
	clk_disable_unprepare(hdmi->osc_clk);
	clk_disable_unprepare(hdmi->cec_clk);
}

static const struct drm_encoder_helper_funcs zx_hdmi_encoder_helper_funcs = {
	.enable	= zx_hdmi_encoder_enable,
	.disable = zx_hdmi_encoder_disable,
	.mode_set = zx_hdmi_encoder_mode_set,
};

static const struct drm_encoder_funcs zx_hdmi_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static int zx_hdmi_connector_get_modes(struct drm_connector *connector)
{
	struct zx_hdmi *hdmi = to_zx_hdmi(connector);
	struct edid *edid;
	int ret;

	edid = drm_get_edid(connector, &hdmi->ddc->adap);
	if (!edid)
		return 0;

	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	kfree(edid);

	return ret;
}

static enum drm_mode_status
zx_hdmi_connector_mode_valid(struct drm_connector *connector,
			     struct drm_display_mode *mode)
{
	return MODE_OK;
}

static struct drm_connector_helper_funcs zx_hdmi_connector_helper_funcs = {
	.get_modes = zx_hdmi_connector_get_modes,
	.mode_valid = zx_hdmi_connector_mode_valid,
};

static enum drm_connector_status
zx_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
	struct zx_hdmi *hdmi = to_zx_hdmi(connector);

	return (hdmi_readb(hdmi, TPI_HPD_RSEN) & TPI_HPD_CONNECTION) ?
		connector_status_connected : connector_status_disconnected;
}

static const struct drm_connector_funcs zx_hdmi_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.detect = zx_hdmi_connector_detect,
	.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 int zx_hdmi_register(struct drm_device *drm, struct zx_hdmi *hdmi)
{
	struct drm_encoder *encoder = &hdmi->encoder;

	encoder->possible_crtcs = VOU_CRTC_MASK;

	drm_encoder_init(drm, encoder, &zx_hdmi_encoder_funcs,
			 DRM_MODE_ENCODER_TMDS, NULL);
	drm_encoder_helper_add(encoder, &zx_hdmi_encoder_helper_funcs);

	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;

	drm_connector_init(drm, &hdmi->connector, &zx_hdmi_connector_funcs,
			   DRM_MODE_CONNECTOR_HDMIA);
	drm_connector_helper_add(&hdmi->connector,
				 &zx_hdmi_connector_helper_funcs);

	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);

	return 0;
}

static irqreturn_t zx_hdmi_irq_thread(int irq, void *dev_id)
{
	struct zx_hdmi *hdmi = dev_id;

	drm_helper_hpd_irq_event(hdmi->connector.dev);

	return IRQ_HANDLED;
}

static irqreturn_t zx_hdmi_irq_handler(int irq, void *dev_id)
{
	struct zx_hdmi *hdmi = dev_id;
	u8 lstat;

	lstat = hdmi_readb(hdmi, L1_INTR_STAT);

	/* Monitor detect/HPD interrupt */
	if (lstat & L1_INTR_STAT_INTR1) {
		u8 stat;

		stat = hdmi_readb(hdmi, INTR1_STAT);
		hdmi_writeb(hdmi, INTR1_STAT, stat);

		if (stat & INTR1_MONITOR_DETECT)
			return IRQ_WAKE_THREAD;
	}

	return IRQ_NONE;
}

static int zx_hdmi_audio_startup(struct device *dev, void *data)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);
	struct drm_encoder *encoder = &hdmi->encoder;

	vou_inf_hdmi_audio_sel(encoder->crtc, VOU_HDMI_AUD_SPDIF);

	return 0;
}

static void zx_hdmi_audio_shutdown(struct device *dev, void *data)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);

	/* Disable audio input */
	hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, 0);
}

static inline int zx_hdmi_audio_get_n(unsigned int fs)
{
	unsigned int n;

	if (fs && (fs % 44100) == 0)
		n = 6272 * (fs / 44100);
	else
		n = fs * 128 / 1000;

	return n;
}

static int zx_hdmi_audio_hw_params(struct device *dev,
				   void *data,
				   struct hdmi_codec_daifmt *daifmt,
				   struct hdmi_codec_params *params)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);
	struct hdmi_audio_infoframe *cea = &params->cea;
	union hdmi_infoframe frame;
	int n;

	/* We only support spdif for now */
	if (daifmt->fmt != HDMI_SPDIF) {
		DRM_DEV_ERROR(hdmi->dev, "invalid daifmt %d\n", daifmt->fmt);
		return -EINVAL;
	}

	switch (params->sample_width) {
	case 16:
		hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
				 SPDIF_SAMPLE_SIZE_16BIT);
		break;
	case 20:
		hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
				 SPDIF_SAMPLE_SIZE_20BIT);
		break;
	case 24:
		hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
				 SPDIF_SAMPLE_SIZE_24BIT);
		break;
	default:
		DRM_DEV_ERROR(hdmi->dev, "invalid sample width %d\n",
			      params->sample_width);
		return -EINVAL;
	}

	/* CTS is calculated by hardware, and we only need to take care of N */
	n = zx_hdmi_audio_get_n(params->sample_rate);
	hdmi_writeb(hdmi, N_SVAL1, n & 0xff);
	hdmi_writeb(hdmi, N_SVAL2, (n >> 8) & 0xff);
	hdmi_writeb(hdmi, N_SVAL3, (n >> 16) & 0xf);

	/* Enable spdif mode */
	hdmi_writeb_mask(hdmi, AUD_MODE, SPDIF_EN, SPDIF_EN);

	/* Enable audio input */
	hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, AUD_IN_EN);

	memcpy(&frame.audio, cea, sizeof(*cea));

	return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AUDIO);
}

static int zx_hdmi_audio_digital_mute(struct device *dev, void *data,
				      bool enable)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);

	if (enable)
		hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE,
				 TPI_AUD_MUTE);
	else
		hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE, 0);

	return 0;
}

static int zx_hdmi_audio_get_eld(struct device *dev, void *data,
				 uint8_t *buf, size_t len)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);
	struct drm_connector *connector = &hdmi->connector;

	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));

	return 0;
}

static const struct hdmi_codec_ops zx_hdmi_codec_ops = {
	.audio_startup = zx_hdmi_audio_startup,
	.hw_params = zx_hdmi_audio_hw_params,
	.audio_shutdown = zx_hdmi_audio_shutdown,
	.digital_mute = zx_hdmi_audio_digital_mute,
	.get_eld = zx_hdmi_audio_get_eld,
};

static struct hdmi_codec_pdata zx_hdmi_codec_pdata = {
	.ops = &zx_hdmi_codec_ops,
	.spdif = 1,
};

static int zx_hdmi_audio_register(struct zx_hdmi *hdmi)
{
	struct platform_device *pdev;

	pdev = platform_device_register_data(hdmi->dev, HDMI_CODEC_DRV_NAME,
					     PLATFORM_DEVID_AUTO,
					     &zx_hdmi_codec_pdata,
					     sizeof(zx_hdmi_codec_pdata));
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	hdmi->audio_pdev = pdev;

	return 0;
}

static int zx_hdmi_i2c_read(struct zx_hdmi *hdmi, struct i2c_msg *msg)
{
	int len = msg->len;
	u8 *buf = msg->buf;
	int retry = 0;
	int ret = 0;

	/* Bits [9:8] of bytes */
	hdmi_writeb(hdmi, ZX_DDC_DIN_CNT2, (len >> 8) & 0xff);
	/* Bits [7:0] of bytes */
	hdmi_writeb(hdmi, ZX_DDC_DIN_CNT1, len & 0xff);

	/* Clear FIFO */
	hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK, DDC_CMD_CLEAR_FIFO);

	/* Kick off the read */
	hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK,
			 DDC_CMD_SEQUENTIAL_READ);

	while (len > 0) {
		int cnt, i;

		/* FIFO needs some time to get ready */
		usleep_range(500, 1000);

		cnt = hdmi_readb(hdmi, ZX_DDC_DOUT_CNT) & DDC_DOUT_CNT_MASK;
		if (cnt == 0) {
			if (++retry > 5) {
				DRM_DEV_ERROR(hdmi->dev,
					      "DDC FIFO read timed out!");
				return -ETIMEDOUT;
			}
			continue;
		}

		for (i = 0; i < cnt; i++)
			*buf++ = hdmi_readb(hdmi, ZX_DDC_DATA);
		len -= cnt;
	}

	return ret;
}

static int zx_hdmi_i2c_write(struct zx_hdmi *hdmi, struct i2c_msg *msg)
{
	/*
	 * The DDC I2C adapter is only for reading EDID data, so we assume
	 * that the write to this adapter must be the EDID data offset.
	 */
	if ((msg->len != 1) ||
	    ((msg->addr != DDC_ADDR) && (msg->addr != DDC_SEGMENT_ADDR)))
		return -EINVAL;

	if (msg->addr == DDC_SEGMENT_ADDR)
		hdmi_writeb(hdmi, ZX_DDC_SEGM, msg->addr << 1);
	else if (msg->addr == DDC_ADDR)
		hdmi_writeb(hdmi, ZX_DDC_ADDR, msg->addr << 1);

	hdmi_writeb(hdmi, ZX_DDC_OFFSET, msg->buf[0]);

	return 0;
}

static int zx_hdmi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			    int num)
{
	struct zx_hdmi *hdmi = i2c_get_adapdata(adap);
	struct zx_hdmi_i2c *ddc = hdmi->ddc;
	int i, ret = 0;

	mutex_lock(&ddc->lock);

	/* Enable DDC master access */
	hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, HW_DDC_MASTER);

	for (i = 0; i < num; i++) {
		DRM_DEV_DEBUG(hdmi->dev,
			      "xfer: num: %d/%d, len: %d, flags: %#x\n",
			      i + 1, num, msgs[i].len, msgs[i].flags);

		if (msgs[i].flags & I2C_M_RD)
			ret = zx_hdmi_i2c_read(hdmi, &msgs[i]);
		else
			ret = zx_hdmi_i2c_write(hdmi, &msgs[i]);

		if (ret < 0)
			break;
	}

	if (!ret)
		ret = num;

	/* Disable DDC master access */
	hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, 0);

	mutex_unlock(&ddc->lock);

	return ret;
}

static u32 zx_hdmi_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm zx_hdmi_algorithm = {
	.master_xfer	= zx_hdmi_i2c_xfer,
	.functionality	= zx_hdmi_i2c_func,
};

static int zx_hdmi_ddc_register(struct zx_hdmi *hdmi)
{
	struct i2c_adapter *adap;
	struct zx_hdmi_i2c *ddc;
	int ret;

	ddc = devm_kzalloc(hdmi->dev, sizeof(*ddc), GFP_KERNEL);
	if (!ddc)
		return -ENOMEM;

	hdmi->ddc = ddc;
	mutex_init(&ddc->lock);

	adap = &ddc->adap;
	adap->owner = THIS_MODULE;
	adap->class = I2C_CLASS_DDC;
	adap->dev.parent = hdmi->dev;
	adap->algo = &zx_hdmi_algorithm;
	snprintf(adap->name, sizeof(adap->name), "zx hdmi i2c");

	ret = i2c_add_adapter(adap);
	if (ret) {
		DRM_DEV_ERROR(hdmi->dev, "failed to add I2C adapter: %d\n",
			      ret);
		return ret;
	}

	i2c_set_adapdata(adap, hdmi);

	return 0;
}

static int zx_hdmi_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = data;
	struct resource *res;
	struct zx_hdmi *hdmi;
	int irq;
	int ret;

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

	hdmi->dev = dev;
	hdmi->drm = drm;

	dev_set_drvdata(dev, hdmi);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hdmi->mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR(hdmi->mmio)) {
		ret = PTR_ERR(hdmi->mmio);
		DRM_DEV_ERROR(dev, "failed to remap hdmi region: %d\n", ret);
		return ret;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	hdmi->cec_clk = devm_clk_get(hdmi->dev, "osc_cec");
	if (IS_ERR(hdmi->cec_clk)) {
		ret = PTR_ERR(hdmi->cec_clk);
		DRM_DEV_ERROR(dev, "failed to get cec_clk: %d\n", ret);
		return ret;
	}

	hdmi->osc_clk = devm_clk_get(hdmi->dev, "osc_clk");
	if (IS_ERR(hdmi->osc_clk)) {
		ret = PTR_ERR(hdmi->osc_clk);
		DRM_DEV_ERROR(dev, "failed to get osc_clk: %d\n", ret);
		return ret;
	}

	hdmi->xclk = devm_clk_get(hdmi->dev, "xclk");
	if (IS_ERR(hdmi->xclk)) {
		ret = PTR_ERR(hdmi->xclk);
		DRM_DEV_ERROR(dev, "failed to get xclk: %d\n", ret);
		return ret;
	}

	ret = zx_hdmi_ddc_register(hdmi);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret);
		return ret;
	}

	ret = zx_hdmi_audio_register(hdmi);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to register audio: %d\n", ret);
		return ret;
	}

	ret = zx_hdmi_register(drm, hdmi);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to register hdmi: %d\n", ret);
		return ret;
	}

	ret = devm_request_threaded_irq(dev, irq, zx_hdmi_irq_handler,
					zx_hdmi_irq_thread, IRQF_SHARED,
					dev_name(dev), hdmi);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret);
		return ret;
	}

	return 0;
}

static void zx_hdmi_unbind(struct device *dev, struct device *master,
			   void *data)
{
	struct zx_hdmi *hdmi = dev_get_drvdata(dev);

	hdmi->connector.funcs->destroy(&hdmi->connector);
	hdmi->encoder.funcs->destroy(&hdmi->encoder);

	if (hdmi->audio_pdev)
		platform_device_unregister(hdmi->audio_pdev);
}

static const struct component_ops zx_hdmi_component_ops = {
	.bind = zx_hdmi_bind,
	.unbind = zx_hdmi_unbind,
};

static int zx_hdmi_probe(struct platform_device *pdev)
{
	return component_add(&pdev->dev, &zx_hdmi_component_ops);
}

static int zx_hdmi_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &zx_hdmi_component_ops);
	return 0;
}

static const struct of_device_id zx_hdmi_of_match[] = {
	{ .compatible = "zte,zx296718-hdmi", },
	{ /* end */ },
};
MODULE_DEVICE_TABLE(of, zx_hdmi_of_match);

struct platform_driver zx_hdmi_driver = {
	.probe = zx_hdmi_probe,
	.remove = zx_hdmi_remove,
	.driver	= {
		.name = "zx-hdmi",
		.of_match_table	= zx_hdmi_of_match,
	},
};
