/*
 * 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);
	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 = {
	.dpms = drm_atomic_helper_connector_dpms,
	.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,
	},
};
