/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __IT66121_REGS_H__
#define __IT66121_REGS_H__

#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/hdmi.h>
#include <drm/drm_connector.h>
#include <drm/drm_edid.h>

#include "it66121_drv.h"
#include "bridge_phy.h"
#include "bridge_phy_interface.h"

/**
 * @brief Config it66121 registers attribute
 */
static const u8 it66121_reg_defaults_raw[] = {
	0x54, 0x49, 0x12, 0x16, 0x1c, 0x60, 0x00, 0x00, /* 00 */
	0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0c, 0x08, /* 0F */
	0x96, 0xa0, 0x60, 0x20, 0x01, 0xf3, 0x82, 0xf4,
	0x00, 0x74, 0xe0, 0x03, 0x00, 0x00, 0xff, 0x00, /* 1F */
	0x08, 0xff, 0x00, 0xf7, 0x49, 0x5f, 0x4b, 0x40,
	0xec, 0xc3, 0x15, 0xe8, 0xca, 0xe5, 0x06, 0x34, /* 2F */
	0x6a, 0x67, 0x6f, 0x95, 0xee, 0x9a, 0xe5, 0x13,
	0xd5, 0xf1, 0xea, 0xcb, 0x9e, 0xce, 0x14, 0x56, /* 3F */
	0x9d, 0x88, 0xe8, 0x00, 0x68, 0xe7, 0x00, 0x00,
	0x4a, 0x22, 0xc8, 0x10, 0x2a, 0xa5, 0x00, 0xbb, /* 4F */
	0x80, 0x54, 0xcf, 0x5e, 0x0e, 0x2f, 0x8f, 0xbf,
	0x11, 0x03, 0x03, 0xfe, 0x00, 0x94, 0x37, 0x9e, /* 5F */
	0xff, 0x10, 0x88, 0x18, 0x94, 0x00, 0x00, 0x00,
	0x00, 0x30, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 6F */
	0x00, 0x08, 0x00, 0x10, 0x80, 0x00, 0x6c, 0x7c,
	0x89, 0xe9, 0x2d, 0x18, 0x4a, 0xc6, 0x6a, 0xd2, /* 7F */
	0x43, 0x08, 0x03, 0x16, 0x90, 0x08, 0x3f, 0xf6,
	0x2b, 0xb3, 0xff, 0xff, 0xff, 0xc8, 0x00, 0x00, /* 8F */
	0x00, 0x6a, 0xf0, 0x35, 0xb0, 0xdb, 0xcd, 0x10,
	0x16, 0xc7, 0x46, 0xd0, 0xa7, 0xe1, 0x37, 0x44, /* 9F */
	0x77, 0xc3, 0xd6, 0xfe, 0xb2, 0x06, 0x90, 0x86,
	0x00, 0x04, 0x39, 0x0a, 0xa1, 0x6f, 0xfb, 0xc9, /* AF */
	0x18, 0x67, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, /* BF */
	0x00, 0x81, 0xb9, 0x08, 0xc0, 0x04, 0x00, 0xff,
	0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, /* CF */
	0x00, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0x04,
	0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* DF */
	0xc0, 0x41, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x00, 0xff, /* EF */
	0x00, 0xff, 0xff, 0x18, 0x00, 0x02, 0xff, 0xff,
	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* FF */
	0x47, 0x8c, 0x72, 0x80, 0x18, 0x00, 0x00, 0x00,
	0x22, 0x72, 0x0c, 0x5f, 0xa6, 0x3d, 0x1a, 0x8c, /* 13F */
	0x09, 0x98, 0x42, 0x98, 0x43, 0x50, 0xdf, 0x20,
	0x40, 0xa6, 0xd2, 0x99, 0xff, 0x98, 0x4c, 0x66, /* 14F */
	0x1a, 0x61, 0x49, 0xa2, 0x0f, 0xec, 0xc9, 0xff,
	0x00, 0x08, 0x19, 0x99, 0x00, 0x55, 0x00, 0x00, /* 15F */
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x82,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf1, 0x3d, /* 16F */
	0xe6, 0xd9, 0x2d, 0xba, 0x0a, 0x07, 0x54, 0x9a,
	0xb9, 0xb9, 0x92, 0x98, 0x73, 0x5c, 0xdd, 0xf6, /* 17F */
	0x0d, 0xff, 0x4f, 0xc3, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0x50, 0x02, 0x3b, 0x06, 0x83, 0x7c, /* 18F */
	0xff, 0x00, 0x27, 0xfd, 0x0a, 0xff, 0xff, 0xff,
	0x00, 0xb4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 19F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 1AF */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x67, 0x67,
	0x28, 0x9a, 0xaf, 0x47, 0x2e, 0x27, 0xbf, 0x9f, /* 1BF */
};

static bool it66121_register_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case IT66121_REG_VENDOR_ID_BASE ... IT66121_REG_CFG:
	case IT66121_REG_INT_MASK_BASE ... IT66121_REG_INT_CLEAR_END:
	case IT66121_REG_SYS_CLK:
	case IT66121_REG_DDC_CTRL:
	case IT66121_REG_DDC_ADDR:
	case IT66121_REG_DDC_OFFSET:
	case IT66121_REG_DDC_FIFO_SIZE:
	case IT66121_REG_DDC_EDID_BLOCK:
	case IT66121_REG_INPUT_DATA:
	case IT66121_REG_HDMI_MODE:
	case IT66121_REG_AVI_BASE ... IT66121_REG_AVI_BASE + AVI_LENGTH:
		return false;
	case IT66121_REG_INT_STATUS_BASE ... IT66121_REG_INT_STATUS_END:
	case IT66121_REG_SYS_STATUS:
	case IT66121_REG_DDC_CMD:
	case IT66121_REG_DDC_STATUS:
	case IT66121_REG_FIFO_CONTENT:
	case IT66121_REG_AVMUTE:
	default:
		return true;
	}
}

static const struct regmap_range it66121_rw_regs_range[] = {
	regmap_reg_range(0x00, 0xff),
	regmap_reg_range(0x100, 0x1ff),
};

static const struct regmap_range it66121_ro_regs_range[] = {
	regmap_reg_range(IT66121_REG_VENDOR_ID_BASE, IT66121_REG_CHIP_REVISION),
};

static const struct regmap_range it66121_vo_regs_range[] = {
	regmap_reg_range(0x100, 0x1ff),
};

/**
 * @brief it66121 sequence
 */
static const struct reg_sequence it66121_reg_init_seq[] = {
	/* IT66121 initial batch */
	/* Initial clock */
	{ 0x0F, 0x38 },
	{ 0x62, 0x80 },
	{ 0x64, 0x90 },
	/* Initial register */
	{ 0x04, 0x20 },
	{ 0x04, 0x1D },
	{ 0x61, 0x30 },
	/* AFE for low speed */
	{ 0x62, 0x18 },
	{ 0x64, 0x1D },
	{ 0x68, 0x10 },
	/* AFE for high speed */
	{ 0x62, 0x88 },
	{ 0x64, 0x94 },
	{ 0x68, 0x00 },
	{ 0x61, 0x10 },
	{ 0x04, 0x05 },
	{ 0x05, IT66121_INT_CFG },
	{ 0x65, 0x00 },
	{ 0xD1, 0x08 },
	{ 0x65, 0x00 },
	{ 0xFF, 0xC3 },
	{ 0xFF, 0xA5 },
	{ 0x20, 0x88 },
	{ 0x37, 0x02 },
	{ 0x20, 0x08 },
	{ 0xFF, 0xFF },
	{ 0x09, 0xFF },
	{ 0x0A, 0xFF },
	{ 0x0B, 0xFF },
	{ 0x0C, 0xFF },
	{ 0x0D, 0xFF },
	{ 0x0E, 0xFF },
};

static const struct reg_sequence it66121_power_on_seq[] = {
	{ 0x0f, 0x38 },
	{ 0x05, IT66121_INT_CFG },
	/* High AFE */
	{ 0x61, 0x10 },
	{ 0x62, 0x80 },
	{ 0x64, 0x90 },
	{ 0x61, 0x00 },
	{ 0x62, 0x88 },
	{ 0x64, 0x94 },
	{ 0x68, 0x00 },
	/* Low AFE */
	{ 0x61, 0x10 },
	{ 0x62, 0x10 },
	{ 0x64, 0x19 },
	{ 0x61, 0x00 },
	{ 0x62, 0x18 },
	{ 0x64, 0x1D },
	{ 0x68, 0x00 },
};

static const struct reg_sequence it66121_power_off_seq[] = {
	/* Power off */
	{ 0x0F, 0x00 },
	{ 0x61, 0x10 },
	{ 0x62, 0x80 },
	{ 0x64, 0x80 },
	{ 0x61, 0x30 },
	{ 0x62, 0xC4 },
	{ 0x64, 0xC0 },
	{ 0x0F, 0x38 },
	{ 0x70, 0x00 },
	/* Set pin status */
	{ 0x05, IT66121_INT_CFG },
	{ 0xE0, 0x00 },
	{ 0x72, 0x00 },

};

static const struct reg_sequence it66121_afe_high_seq[] = {
	/* IT66121 initial batch */
	{ 0x0F, 0x00 },
	{ 0x61, 0x10 },
	{ 0x62, 0x88 },
	{ 0x64, 0x94 },
	/* Initial clock */
	{ 0x68, 0x00 },
	{ 0x04, 0x1D },
	{ 0x04, 0x15 },
	{ 0x61, 0x00 },
};

static const struct reg_sequence it66121_afe_low_seq[] = {
	/* IT66121 initial batch */
	{ 0x0F, 0x00 },
	{ 0x61, 0x10 },
	{ 0x62, 0x18 },
	{ 0x64, 0x1D },
	/* Initial clock */
	{ 0x68, 0x10 },
	{ 0x04, 0x1D },
	{ 0x04, 0x15 },
	{ 0x61, 0x00 },
};

static const struct reg_sequence it66121_hdmi_seq[] = {
	{ 0x0F, 0x00 },
	{ 0xC0, 0x01 },
	{ 0xC1, 0x00 },
	/* Set GCP package */
	{ 0xC6, 0x03 },
	{ 0xCD, 0x03 },
	{ 0xCE, 0x03 },
};

static const struct reg_mask_seq it66121_hdcp_seq[] = {
	{ 0x20, 0x00, 0x98 },
	{ 0x04, 0x01, 0x98 },
	{ 0x04, 0x00, 0x98 },
	{ 0x10, 0x00, 0x98 },
	/* Enable HDCP-1.2 sync detect */
	{ 0x20, 0x01, 0x98 },
	{ 0x21, 0x01, 0x98 },
};

static const struct reg_mask_seq it66121_avi_info_frame_seq[] = {
	/* 1080p */
	{ 0x0F, 0x01, 0x01 },
	{ 0x58, 0xFF, 0x10 },
	{ 0x59, 0xFF, 0x08 },
	{ 0x5A, 0xFF, 0x00 },
	{ 0x5B, 0xFF, 0x10 },
	{ 0x5C, 0xFF, 0x00 },
	/* Set AVI package check sum */
	{ 0x5D, 0xFF, 0x47 },
	{ 0x5E, 0xFF, 0x00 },
	{ 0x5F, 0xFF, 0x00 },
	{ 0x60, 0xFF, 0x00 },
	{ 0x61, 0xFF, 0x00 },
	{ 0x62, 0xFF, 0x00 },
	{ 0x63, 0xFF, 0x00 },
	{ 0x64, 0xFF, 0x00 },
	{ 0x65, 0xFF, 0x00 },
	{ 0x0F, 0x01, 0x00 },
	{ 0xCD, 0x03, 0x03 },
};

static const struct reg_sequence it66121_int_en_all_seq[] = {
	{ 0x09, 0x00 },
	{ 0x0A, 0x00 },
	{ 0x0B, 0x00 },
};

static const struct reg_sequence it66121_int_dis_all_seq[] = {
	{ 0x09, 0xFF },
	{ 0x0A, 0xFF },
	{ 0x0B, 0xFF },
};

static const struct reg_mask_seq it66121_audio_seq[] = {
	{0x0F, 0x01, 0x01},
	{0x68, 0xFF, 0x00},
	{0x69, 0xFF, 0x00},
	{0x6A, 0xFF, 0x00},
	{0x6B, 0xFF, 0x00},
	{0x6C, 0xFF, 0x00},
	{0x6D, 0xFF, 0x71},
	{0x0F, 0x01, 0x00},
	{0xCE, 0x03, 0x03},
	/*LPCM 20bit 48Khz*/
	{0x0F, 0x01, 0x01},
	{0x33, 0xFF, 0x00},
	{0x34, 0xFF, 0x18},
	{0x35, 0xFF, 0x00},
	{0x91, 0xFF, 0x00},
	{0x92, 0xFF, 0x00},
	{0x93, 0xFF, 0x01},
	{0x94, 0xFF, 0x00},
	{0x98, 0xFF, 0x02},
	{0x99, 0xFF, 0xDA},
	{0x0F, 0x01, 0x00},
	/*SPDIF 2ch 24Bit*/
	{0x0F, 0x11, 0x00},
	{0x04, 0x14, 0x04},
	{0xE0, 0xFF, 0xD1},
	{0xE1, 0xFF, 0x01},
	{0xE2, 0xFF, 0xE4},
	{0xE3, 0xFF, 0x10},
	{0xE4, 0xFF, 0x00},
	{0xE5, 0xFF, 0x00},
	{0x04, 0x14, 0x00},
};
#endif

