slimport: add slimport anx7808 driver
add slimport anx7808 driver
Change-Id: I133d5272172532a52e27e08779b97789c104173a
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index de4ad40..8f6735d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -689,4 +689,6 @@
source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
+source "drivers/misc/slimport_anx7808/Kconfig"
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9b55cd4..90f1803 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -74,3 +74,4 @@
obj-$(CONFIG_QFP_FUSE) += qfp_fuse.o
obj-y += tspdrv/
obj-$(CONFIG_BU52031NVX) += pm8xxx-cradle.o
+obj-$(CONFIG_SLIMPORT_ANX7808) += slimport_anx7808/
diff --git a/drivers/misc/slimport_anx7808/Kconfig b/drivers/misc/slimport_anx7808/Kconfig
new file mode 100644
index 0000000..20d3f52
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/Kconfig
@@ -0,0 +1,5 @@
+config SLIMPORT_ANX7808
+ tristate "Analogix Slimport transmitter ANX7808 support"
+ help
+ Slimport Transmitter is a HD video transmitter chip
+ over micro-USB connector for smartphone device.
diff --git a/drivers/misc/slimport_anx7808/Makefile b/drivers/misc/slimport_anx7808/Makefile
new file mode 100644
index 0000000..aae059e
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SLIMPORT_ANX7808) += slimport.o slimport_tx_drv.o
diff --git a/drivers/misc/slimport_anx7808/slimport.c b/drivers/misc/slimport_anx7808/slimport.c
new file mode 100644
index 0000000..5f390e8
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/slimport.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright(c) 2012, LG Electronics Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/slimport_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "slimport_tx_drv.h"
+#include "slimport.h"
+
+struct i2c_client *anx7808_client;
+
+struct anx7808_data {
+ struct anx7808_platform_data *pdata;
+ struct delayed_work work;
+ struct workqueue_struct *workqueue;
+ struct mutex lock;
+};
+
+#ifdef HDCP_EN
+static bool hdcp_enable = 1;
+#else
+static bool hdcp_enable = 0;
+#endif
+
+int sp_tx_read_reg(uint8_t slave_addr, uint8_t offset, uint8_t *buf)
+{
+ int ret = 0;
+
+ anx7808_client->addr = (slave_addr >> 1);
+ ret = i2c_smbus_read_byte_data(anx7808_client, offset);
+ if (ret < 0) {
+ pr_err("%s: failed to read i2c addr=%x\n", __func__, slave_addr);
+ return ret;
+ }
+ *buf = (uint8_t) ret;
+
+ return 0;
+}
+
+int sp_tx_write_reg(uint8_t slave_addr, uint8_t offset, uint8_t value)
+{
+ int ret = 0;
+
+ anx7808_client->addr = (slave_addr >> 1);
+ ret = i2c_smbus_write_byte_data(anx7808_client, offset, value);
+ if (ret < 0) {
+ pr_err("%s: failed to write i2c addr=%x\n", __func__, slave_addr);
+ }
+ return ret;
+}
+
+void sp_tx_hardware_poweron(void)
+{
+ struct anx7808_platform_data *pdata = anx7808_client->dev.platform_data;
+
+ gpio_set_value(pdata->gpio_reset, 0);
+ mdelay(20);
+ gpio_set_value(pdata->gpio_p_dwn, 0);
+ pdata->dvdd_power(1);
+ mdelay(100);
+ gpio_set_value(pdata->gpio_reset, 1);
+ mdelay(20);
+
+ pr_info("%s: anx7808 power on\n", __func__);
+}
+
+void sp_tx_hardware_powerdown(void)
+{
+ struct anx7808_platform_data *pdata = anx7808_client->dev.platform_data;
+
+ gpio_set_value(pdata->gpio_reset, 0);
+ mdelay(10);
+ pdata->dvdd_power(0);
+ mdelay(10);
+ gpio_set_value(pdata->gpio_p_dwn, 1);
+ mdelay(20);
+
+ pr_info("%s: anx7808 power down\n", __func__);
+}
+
+int slimport_read_edid_block(int block, uint8_t *edid_buf)
+{
+ if (block == 0) {
+ memcpy(edid_buf, bEDID_firstblock, sizeof(bEDID_firstblock));
+ }
+ else if (block == 1) {
+ memcpy(edid_buf, bEDID_extblock, sizeof(bEDID_extblock));
+ }
+ else {
+ pr_err("%s: block number %d is invalid\n",__func__, block);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void slimport_cable_plug_proc(struct anx7808_data *anx7808)
+{
+ struct anx7808_platform_data *pdata = anx7808->pdata;
+
+ if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
+ mdelay(50);
+ if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
+ if (sp_tx_pd_mode) {
+ sp_tx_pd_mode = 0;
+ sp_tx_hardware_poweron();
+ sp_tx_power_on(SP_TX_PWR_REG);
+ sp_tx_power_on(SP_TX_PWR_TOTAL);
+ sp_tx_initialization();
+ hdmi_rx_initialize();
+ sp_tx_vbus_poweron();
+ msleep(300);
+ if (!sp_tx_get_cable_type()) {
+ pr_err("%s:AUX ERR\n", __func__);
+ sp_tx_vbus_powerdown();
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_hardware_powerdown();
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ return;
+ }
+ }
+ if (sp_tx_rx_anx7730) {
+ if (sp_tx_get_hdmi_connection())
+ sp_tx_set_system_state(SP_TX_PARSE_EDID);
+ } else if (sp_tx_rx_mydp) {
+ if (sp_tx_get_dp_connection())
+ sp_tx_set_system_state(SP_TX_PARSE_EDID);
+ } else {
+ if (sp_tx_get_vga_connection()) {
+ sp_tx_send_message(MSG_CLEAR_IRQ);
+ sp_tx_set_system_state(SP_TX_PARSE_EDID);
+ }
+ }
+ }
+ } else if (sp_tx_pd_mode == 0) {
+ sp_tx_vbus_powerdown();
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_hardware_powerdown();
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ }
+}
+
+static void slimport_edid_proc(void)
+{
+ sp_tx_edid_read();
+ sp_tx_rst_aux();
+ if (bEDID_break)
+ pr_err("%s: EDID corruption!\n", __func__);
+ hdmi_rx_tmds_en();
+ hdmi_rx_set_hpd(1);
+ hdmi_rx_set_termination(1);
+ sp_tx_set_system_state(SP_TX_CONFIG_HDMI_INPUT);
+}
+
+static void slimport_config_output(void)
+{
+ sp_tx_clean_hdcp();
+ sp_tx_set_colorspace();
+ sp_tx_avi_setup();
+ sp_tx_config_packets(AVI_PACKETS);
+ sp_tx_set_system_state(SP_TX_HDCP_AUTHENTICATION);
+}
+
+static void slimport_playback_proc(void)
+{
+ sp_tx_set_3d_packets();
+ /*sp_tx_link_err_check();*/
+}
+
+static void slimport_main_proc(struct anx7808_data *anx7808)
+{
+ mutex_lock(&anx7808->lock);
+
+ if (!sp_tx_pd_mode) {
+ sp_tx_int_irq_handler();
+ hdmi_rx_int_irq_handler();
+ }
+
+ if (sp_tx_system_state == SP_TX_WAIT_SLIMPORT_PLUGIN)
+ slimport_cable_plug_proc(anx7808);
+
+ if (sp_tx_system_state == SP_TX_PARSE_EDID)
+ slimport_edid_proc();
+
+ if (sp_tx_system_state == SP_TX_CONFIG_HDMI_INPUT)
+ sp_tx_config_hdmi_input();
+
+ if (sp_tx_system_state == SP_TX_LINK_TRAINING) {
+ if (!sp_tx_lt_pre_config())
+ sp_tx_hw_link_training();
+ }
+
+ if (sp_tx_system_state == SP_TX_CONFIG_SLIMPORT_OUTPUT)
+ slimport_config_output();
+
+ if (sp_tx_system_state == SP_TX_HDCP_AUTHENTICATION) {
+ if ((!hdcp_enable) || (!sp_tx_rx_anx7730)) {
+ sp_tx_power_down(SP_TX_PWR_HDCP);
+ sp_tx_show_infomation();
+ sp_tx_video_mute(0);
+ sp_tx_set_system_state(SP_TX_PLAY_BACK);
+ } else {
+ sp_tx_hdcp_process();
+ }
+ }
+
+ if (sp_tx_system_state == SP_TX_PLAY_BACK)
+ slimport_playback_proc();
+
+ mutex_unlock(&anx7808->lock);
+}
+
+static uint8_t anx7808_chip_detect(void)
+{
+ return sp_tx_chip_located();
+}
+
+static void anx7808_chip_initial(void)
+{
+#ifdef EYE_TEST
+ sp_tx_eye_diagram_test();
+#else
+ sp_tx_variable_init();
+ sp_tx_vbus_powerdown();
+ sp_tx_hardware_powerdown();
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+#endif
+}
+
+static void anx7808_free_gpio(struct anx7808_data *anx7808)
+{
+ gpio_free(anx7808->pdata->gpio_cbl_det);
+ gpio_free(anx7808->pdata->gpio_int);
+ gpio_free(anx7808->pdata->gpio_reset);
+ gpio_free(anx7808->pdata->gpio_p_dwn);
+}
+
+static int anx7808_init_gpio(struct anx7808_data *anx7808)
+{
+ int ret = 0;
+
+ pr_info("anx7808 init gpio\n");
+
+ ret = gpio_request_one(anx7808->pdata->gpio_p_dwn,
+ GPIOF_OUT_INIT_HIGH, "anx_p_dwn_ctl");
+ if (ret) {
+ pr_err("%s : failed to request gpio %d \n", __func__,
+ anx7808->pdata->gpio_p_dwn);
+ goto out;
+ }
+
+ ret = gpio_request_one(anx7808->pdata->gpio_reset,
+ GPIOF_OUT_INIT_LOW, "anx7808_reset_n");
+ if (ret) {
+ pr_err("%s : failed to request gpio %d \n", __func__,
+ anx7808->pdata->gpio_reset);
+ goto err0;
+ }
+
+ ret = gpio_request_one(anx7808->pdata->gpio_int,
+ GPIOF_IN, "anx7808_int_n");
+
+ if (ret) {
+ pr_err("%s : failed to request gpio %d \n", __func__,
+ anx7808->pdata->gpio_int);
+ goto err1;
+ }
+
+ ret = gpio_request_one(anx7808->pdata->gpio_cbl_det,
+ GPIOF_IN, "anx7808_cbl_det");
+ if (ret) {
+ pr_err("%s : failed to request gpio %d \n", __func__,
+ anx7808->pdata->gpio_cbl_det);
+ goto err2;
+ }
+
+ gpio_set_value(anx7808->pdata->gpio_reset, 0);
+ gpio_set_value(anx7808->pdata->gpio_p_dwn, 1);
+
+ goto out;
+
+err2:
+ gpio_free(anx7808->pdata->gpio_int);
+err1:
+ gpio_free(anx7808->pdata->gpio_reset);
+err0:
+ gpio_free(anx7808->pdata->gpio_p_dwn);
+out:
+ return ret;
+}
+
+static int anx7808_system_init (void)
+{
+ int ret = 0;
+
+ ret = anx7808_chip_detect();
+ if (ret == 0) {
+ pr_err("%s : failed to detect anx7808\n", __func__);
+ return -ENODEV;
+ }
+
+ anx7808_chip_initial();
+ return 0;
+}
+
+static irqreturn_t anx7808_cbl_det_isr(int irq, void *data)
+{
+ struct anx7808_data *anx7808 = data;
+
+ slimport_main_proc(anx7808);
+
+ if (gpio_get_value(anx7808->pdata->gpio_cbl_det)) {
+ pr_info("%s : detect cable insertion\n", __func__);
+ queue_delayed_work(anx7808->workqueue, &anx7808->work,
+ msecs_to_jiffies(500));
+ } else {
+ pr_info("%s : detect cable removal\n", __func__);
+ cancel_delayed_work_sync(&anx7808->work);
+ }
+ return IRQ_HANDLED;
+}
+
+static void anx7808_work_func(struct work_struct *work)
+{
+#ifndef EYE_TEST
+ struct anx7808_data *td = container_of(work, struct anx7808_data,
+ work.work);
+
+ slimport_main_proc(td);
+ queue_delayed_work(td->workqueue, &td->work,
+ msecs_to_jiffies(500));
+#endif
+}
+
+static int anx7808_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct anx7808_data *anx7808;
+ int ret = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ pr_err("%s: i2c bus does not support the anx7808\n", __func__);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ anx7808 = kzalloc(sizeof(struct anx7808_data), GFP_KERNEL);
+ if (!anx7808) {
+ pr_err("%s: failed to allocate driver data\n", __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ anx7808->pdata = client->dev.platform_data;
+ i2c_set_clientdata(client, anx7808);
+ memcpy(&anx7808_client, &client, sizeof(client));
+
+ mutex_init(&anx7808->lock);
+
+ if (!anx7808->pdata) {
+ ret = -EINVAL;
+ goto err0;
+ }
+
+ ret = anx7808_init_gpio(anx7808);
+ if (ret) {
+ pr_err("%s: failed to initialize gpio\n", __func__);
+ goto err0;
+ }
+
+ INIT_DELAYED_WORK(&anx7808->work, anx7808_work_func);
+
+ anx7808->workqueue = create_singlethread_workqueue("anx7808_work");
+ if (anx7808->workqueue == NULL) {
+ pr_err("%s: failed to create work queue\n", __func__);
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ anx7808->pdata->avdd_power(1);
+ anx7808->pdata->dvdd_power(1);
+
+ ret = anx7808_system_init();
+ if (ret) {
+ pr_err("%s: failed to initialize anx7808\n", __func__);
+ goto err1;
+ }
+
+ client->irq = gpio_to_irq(anx7808->pdata->gpio_cbl_det);
+ if (client->irq < 0) {
+ pr_err("%s : failed to get gpio irq\n", __func__);
+ goto err1;
+ }
+
+ ret = request_threaded_irq(client->irq, NULL, anx7808_cbl_det_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "anx7808", anx7808);
+ if (ret < 0) {
+ pr_err("%s : failed to request irq \n", __func__);
+ goto err1;
+ }
+
+ ret = irq_set_irq_wake(client->irq, 1);
+ if (ret < 0) {
+ pr_err ("%s : Request irq for cable detect interrupt wake fail \n", __func__);
+ goto err2;
+ }
+ goto out;
+
+err2:
+ free_irq(client->irq, anx7808);
+err1:
+ destroy_workqueue(anx7808->workqueue);
+err0:
+ kfree(anx7808);
+out:
+ return ret;
+}
+
+static int anx7808_i2c_remove(struct i2c_client *client)
+{
+ struct anx7808_data *anx7808 = i2c_get_clientdata(client);
+
+ free_irq(client->irq, anx7808);
+ anx7808_free_gpio(anx7808);
+ destroy_workqueue(anx7808->workqueue);
+ kfree(anx7808);
+ return 0;
+}
+
+static const struct i2c_device_id anx7808_id[] = {
+ { "anx7808", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, anx7808_id);
+
+static struct i2c_driver anx7808_driver = {
+ .driver = {
+ .name = "anx7808",
+ .owner = THIS_MODULE,
+ },
+ .probe = anx7808_i2c_probe,
+ .remove = anx7808_i2c_remove,
+ .id_table = anx7808_id,
+};
+
+static int __init anx7808_init(void)
+{
+ int ret = 0;
+
+ ret = i2c_add_driver(&anx7808_driver);
+ if (ret < 0) {
+ pr_err("%s: failed to register anx7808 i2c drivern", __func__);
+ }
+ return ret;
+}
+
+static void __exit anx7808_exit(void)
+{
+ i2c_del_driver(&anx7808_driver);
+}
+
+module_init(anx7808_init);
+module_exit(anx7808_exit);
+
+MODULE_DESCRIPTION ("Slimport transmitter ANX7808 driver");
+MODULE_AUTHOR("ChoongRyeol Lee <choongryeol.lee@lge.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/slimport_anx7808/slimport.h b/drivers/misc/slimport_anx7808/slimport.h
new file mode 100644
index 0000000..95060aa
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/slimport.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright(c) 2012, LG Electronics Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __SLIMPORT_H
+#define __SLIMPORT_H
+
+
+#define SSC_EN
+//#define SSC_1
+#define HDCP_EN
+//#define EYE_TEST
+//#define EDID_DEBUG_PRINT
+
+#define AUX_ERR 1
+#define AUX_OK 0
+
+extern unchar sp_tx_hw_lt_done;
+extern unchar sp_tx_hw_lt_enable;
+extern unchar sp_tx_link_config_done ;
+extern enum SP_TX_System_State sp_tx_system_state;
+extern unchar sp_tx_rx_anx7730;
+extern unchar sp_tx_pd_mode;
+extern unchar sp_tx_rx_mydp;
+
+extern unchar bEDID_break;
+
+int sp_tx_read_reg(uint8_t slave_addr, uint8_t offset, uint8_t *buf);
+int sp_tx_write_reg(uint8_t slave_addr, uint8_t offset, uint8_t value);
+void sp_tx_hardware_poweron(void);
+void sp_tx_hardware_powerdown(void);
+int slimport_read_edid_block(int block, uint8_t *edid_buf);
+#endif
diff --git a/drivers/misc/slimport_anx7808/slimport_tx_drv.c b/drivers/misc/slimport_anx7808/slimport_tx_drv.c
new file mode 100644
index 0000000..88737ee
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/slimport_tx_drv.c
@@ -0,0 +1,3436 @@
+/*
+ * Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include "slimport_tx_drv.h"
+#include "slimport_tx_reg.h"
+#include "slimport.h"
+
+static unchar ByteBuf[MAX_BUF_CNT];
+
+/* EDID access break */
+unchar bEDID_break;
+unchar bEDID_extblock[128];
+unchar bEDID_firstblock[128];
+
+
+static ulong pclk;
+static ulong M_val, N_val;
+enum SP_LINK_BW sp_tx_bw;
+unchar sp_tx_link_config_done;
+unchar sp_tx_hw_lt_done;
+unchar sp_tx_hw_lt_enable;
+
+/* for HDCP */
+static unchar sp_tx_hdcp_auth_pass;
+static unchar sp_tx_hdcp_auth_fail_counter;
+static unchar sp_tx_hdcp_capable_chk;
+static unchar sp_tx_hw_hdcp_en;
+static unchar sp_tx_hdcp_auth_done;
+
+unchar sp_tx_pd_mode;
+unchar sp_tx_rx_anx7730;
+unchar sp_tx_rx_mydp;
+
+static struct AudiInfoframe SP_TX_AudioInfoFrmae;
+static struct Packet_AVI SP_TX_Packet_AVI;
+static struct Packet_SPD SP_TX_Packet_SPD;
+static struct Packet_MPEG SP_TX_Packet_MPEG;
+enum SP_TX_System_State sp_tx_system_state;
+
+/* ***************************************************************** */
+
+/* GLOBAL VARIABLES DEFINITION FOR HDMI START */
+
+/* ***************************************************************** */
+
+static unchar g_HDMI_DVI_Status;
+static unchar g_Cur_Pix_Clk;
+static unchar g_Video_Stable_Cntr;
+static unchar g_Audio_Stable_Cntr;
+static unchar g_Sync_Expire_Cntr;
+static unchar g_HDCP_Err_Cnt;
+
+static ulong g_Cur_H_Res;
+static ulong g_Cur_V_Res;
+static unchar g_Video_Muted;
+static unchar g_Audio_Muted;
+static unchar g_CTS_Got;
+static unchar g_Audio_Got;
+static unchar g_VSI_Got;
+static unchar g_No_VSI_Counter;
+
+static enum HDMI_RX_System_State hdmi_system_state;
+
+/* ***************************************************************** */
+
+/* GLOBAL VARIABLES DEFINITION FOR HDMI END */
+
+/* ***************************************************************** */
+
+void sp_tx_variable_init(void)
+{
+
+ sp_tx_hdcp_auth_fail_counter = 0;
+ sp_tx_hdcp_auth_pass = 0;
+ sp_tx_hw_hdcp_en = 0;
+ sp_tx_hdcp_capable_chk = 0;
+ sp_tx_hdcp_auth_done = 0;
+ sp_tx_pd_mode = 1;
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_link_config_done = 0;
+
+ bEDID_break = 0;
+ sp_tx_bw = BW_54G;
+
+}
+
+static void sp_tx_api_m_gen_clk_select(unchar bSpreading)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_M_CALCU_CTRL, &c);
+ if (bSpreading) {
+ c |= M_GEN_CLK_SEL;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_M_CALCU_CTRL, c);
+ } else {
+ c &= ~M_GEN_CLK_SEL;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_M_CALCU_CTRL, c);
+ }
+}
+
+void sp_tx_initialization(void)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, &c);
+ c |= SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+ c &= ~SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_EXTRA_ADDR_REG, 0x50);
+ /* disable HDCP polling mode. */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL, 0x02);
+ /* enable M value read out */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_DEBUG_REG, 0x30);
+
+ /* disable polling HPD, force hotplug for HDCP */
+ /* enable polling, for pll lock */
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, &c);
+ c |= 0x8a;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, c);
+
+ /* change the c-wire termination to 50 ohm */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, &c);
+ c |= 0x30;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, &c);
+ c |= SP_TX_HDCP_CTRL0_KSVLIST_VLD;
+ c |= SP_TX_HDCP_CTRL0_BKSV_SRM_PASS;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, c);
+
+ /* open short portect and 5V detect */
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, 0x00);
+ /* set power on time 1.5ms */
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_ANALOG_DEBUG_REG2, 0x06);
+
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK1, 0x00);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK2, 0x00);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK3, 0x00);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK4, 0x00);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_INT_MASK, 0xb4);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, 0x14);
+
+ /* PHY parameter for cts */
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG0, 0x16);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG4, 0x1b);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG7, 0x22);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG9, 0x23);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG14, 0x09);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG17, 0x16);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG19, 0x1F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG1, 0x26);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG5, 0x28);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG8, 0x2F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG15, 0x10);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG18, 0x1F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG2, 0x36);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG6, 0x3c);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG16, 0x10);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG3, 0x3F);
+
+ /* M value select, select clock with downspreading */
+ sp_tx_api_m_gen_clk_select(1);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DP_POLLING_CTRL_REG, 0x01);
+}
+
+void sp_tx_power_down(enum SP_TX_POWER_BLOCK sp_tx_pd_block)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_POWERD_CTRL_REG, &c);
+ if (sp_tx_pd_block == SP_TX_PWR_REG)
+ c |= SP_POWERD_REGISTER_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_HDCP)
+ c |= SP_POWERD_HDCP_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_AUDIO)
+ c |= SP_POWERD_AUDIO_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_VIDEO)
+ c |= SP_POWERD_VIDEO_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_LINK)
+ c |= SP_POWERD_LINK_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_TOTAL)
+ c |= SP_POWERD_TOTAL_REG;
+
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_POWERD_CTRL_REG, c);
+
+ pr_info("sp_tx_power_down");
+
+}
+
+void sp_tx_power_on(enum SP_TX_POWER_BLOCK sp_tx_pd_block)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_POWERD_CTRL_REG, &c);
+ if (sp_tx_pd_block == SP_TX_PWR_REG)
+ c &= ~SP_POWERD_REGISTER_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_HDCP)
+ c &= ~SP_POWERD_HDCP_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_AUDIO)
+ c &= ~SP_POWERD_AUDIO_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_VIDEO)
+ c &= ~SP_POWERD_VIDEO_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_LINK)
+ c &= ~SP_POWERD_LINK_REG;
+ else if (sp_tx_pd_block == SP_TX_PWR_TOTAL)
+ c &= ~SP_POWERD_TOTAL_REG;
+
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_POWERD_CTRL_REG, c);
+ pr_info("sp_tx_power_on");
+
+}
+
+void sp_tx_rst_aux(void)
+{
+ unchar c, c1;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, &c1);
+ c = c1;
+ /* clear HPD polling and Transmitter polling */
+ c1 &= 0xdd;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, c1);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, &c1);
+ c1 |= SP_TX_AUX_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, c1);
+ mdelay(1);
+ c1 &= ~SP_TX_AUX_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, c1);
+
+ /* enable polling after reset AUX-ANX.Fei-2011.9.19 */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, c);
+}
+
+static unchar sp_tx_wait_aux_finished(void)
+{
+ unchar c;
+ unchar cCnt;
+ cCnt = 0;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_STATUS, &c);
+
+ while (c & 0x10) {
+ cCnt++;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_STATUS, &c);
+ if (cCnt > 100) {
+ pr_err("AUX Operaton does not finished, and time out.");
+ break;
+ }
+ }
+
+ if (c & 0x0F) {
+ pr_err("aux operation failed %.2x\n", (uint)c);
+ return 0;
+ } else
+ return 1;
+
+}
+
+static unchar sp_tx_aux_dpcdread_bytes(unchar addrh, unchar addrm,
+ unchar addrl, unchar cCount,
+ unchar *pBuf)
+{
+ unchar c, i;
+ unchar bOK;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_COUNT_REG, 0x80);
+ c = ((cCount - 1) << 4) | 0x09;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, addrl);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_15_8_REG, addrm);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, &c);
+ c = (c & 0xf0) | addrh;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ c |= 0x01;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, c);
+
+ mdelay(2);
+
+ bOK = sp_tx_wait_aux_finished();
+
+ if (!bOK) {
+ pr_err("aux read failed");
+ sp_tx_rst_aux();
+ return AUX_ERR;
+ }
+
+ for (i = 0; i < cCount; i++) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG + i, &c);
+
+ *(pBuf + i) = c;
+
+ if (i >= MAX_BUF_CNT)
+ break;
+ }
+
+ return AUX_OK;
+}
+
+static unchar sp_tx_aux_dpcdwrite_bytes(unchar addrh, unchar addrm,
+ unchar addrl, unchar cCount,
+ unchar *pBuf)
+{
+ unchar c, i;
+ unchar bOK;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_COUNT_REG, 0x80);
+
+ c = ((cCount - 1) << 4) | 0x08;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, addrl);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_15_8_REG, addrm);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, &c);
+ c = (c & 0xf0) | addrh;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, c);
+
+ for (i = 0; i < cCount; i++) {
+ c = *pBuf;
+ pBuf++;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG + i, c);
+
+ if (i >= MAX_BUF_CNT)
+ break;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ c |= 0x01;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, c);
+
+ bOK = sp_tx_wait_aux_finished();
+
+ if (bOK)
+ return AUX_OK;
+ else
+ return AUX_ERR;
+}
+
+static void sp_tx_aux_dpcdwrite_byte(unchar addrh, unchar addrm,
+ unchar addrl, unchar data1)
+{
+ unchar c;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_COUNT_REG, 0x80);
+ c = (0 << 4) | 0x08;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, addrl);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_15_8_REG, addrm);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, &c);
+ c = (c & 0xf0) | addrh;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG, data1);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ c |= 0x01;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, c);
+
+ sp_tx_wait_aux_finished();
+
+ return;
+}
+
+void sp_tx_set_colorspace(void)
+{
+ unchar c;
+ unchar Color_Space;
+
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_AVI_DATA00_REG, &Color_Space);
+ Color_Space &= 0x60;
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, &c);
+ c = (c & 0xfc) | Color_Space >> 5;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, c);
+}
+
+static void sp_tx_vsi_setup(void)
+{
+ unchar c;
+ int i;
+
+ for (i = 0; i < 13; i++) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, (HDMI_RX_MPEG_DATA00_REG + i), &c);
+ SP_TX_Packet_MPEG.MPEG_data[i] = c;
+ }
+}
+
+static void sp_tx_mpeg_setup(void)
+{
+ unchar c;
+ int i;
+
+ for (i = 0; i < 13; i++) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, (HDMI_RX_MPEG_DATA00_REG + i), &c);
+ SP_TX_Packet_MPEG.MPEG_data[i] = c;
+ }
+}
+
+static void sp_tx_get_int_status(enum INTStatus IntIndex, unchar *cStatus)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_STATUS1 + IntIndex, &c);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_STATUS1 + IntIndex, c);
+
+ *cStatus = c;
+}
+
+static unchar sp_tx_get_pll_lock_status(void)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_DEBUG_REG1, &c);
+ if (c & SP_TX_DEBUG_PLL_LOCK)
+ return 1;
+ else
+ return 0;
+}
+
+void sp_tx_set_3d_packets(void)
+{
+ unchar c;
+ unchar hdmi_video_format, vsi_header, v3d_structure;
+
+ if (g_VSI_Got) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_3D_VSC_CTRL, &c);
+
+ if (!(c & 0x01)) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_MPEG_TYPE_REG,
+ &vsi_header);
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_MPEG_DATA03_REG,
+ &hdmi_video_format);
+
+ if ((vsi_header == 0x81)
+ && ((hdmi_video_format & 0xe0) == 0x40)) {
+ pr_info("3D VSI packet is detected. Config VSI and VSC packet");
+
+ sp_tx_vsi_setup();
+ sp_tx_config_packets(VSI_PACKETS);
+
+ sp_tx_read_reg(HDMI_PORT1_ADDR,
+ HDMI_RX_MPEG_DATA05_REG,
+ &v3d_structure);
+
+ switch (v3d_structure & 0xf0) {
+ case 0x00:/* frame packing */
+ v3d_structure = 0x02;
+ break;
+ case 0x20:/* Line alternative */
+ v3d_structure = 0x03;
+ break;
+ case 0x30: /* Side-by-side(full) */
+ v3d_structure = 0x04;
+ break;
+ default:
+ v3d_structure = 0x00;
+ pr_warn("3D structure is not supported");
+ break;
+ }
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_VSC_DBYTE1, v3d_structure);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_3D_VSC_CTRL, &c);
+ c = c|0x01;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_3D_VSC_CTRL, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c = c & 0xfe;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c = c|0x10;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c = c|0x01;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+ }
+ }
+ g_No_VSI_Counter = 0;
+ g_VSI_Got = 0;
+ } else {
+ g_No_VSI_Counter++;
+
+ if (g_No_VSI_Counter > 5) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, 0xea, &c);
+ if (c & 0x01) {
+ pr_info("No new VSI is received, disable VSC packet");
+ /* disable VSC */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xea, 0x00);
+ sp_tx_mpeg_setup();
+ sp_tx_config_packets(MPEG_PACKETS);
+ }
+ g_No_VSI_Counter = 0;
+ }
+ }
+}
+
+static void sp_tx_lvttl_bit_mapping(void)
+{
+ enum HDMI_color_depth hdmi_input_color_depth = Hdmi_legacy;
+ unchar c, c1;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VIDEO_STATUS_REG1, &c1);
+ c1 &= 0xf0;
+ if (c1 == 0x00)
+ hdmi_input_color_depth = Hdmi_legacy;
+ else if (c1 == 0x40)
+ hdmi_input_color_depth = Hdmi_24bit;
+ else if (c1 == 0x50)
+ hdmi_input_color_depth = Hdmi_30bit;
+ else if (c1 == 0x60)
+ hdmi_input_color_depth = Hdmi_36bit;
+ else
+ pr_warn("HDMI input color depth is not supported .\n");
+
+ switch (hdmi_input_color_depth) {
+ case Hdmi_legacy:
+ case Hdmi_24bit:
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c = c & ~0x04;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, &c);
+ c = (c & 0x8f) | 0x10;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, c);
+
+ for (c = 0; c < 24; c++)
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (0x40 + c), (0x00 + c));
+
+ break;
+ case Hdmi_30bit:
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c = c & ~0x04;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, &c);
+ c = (c & 0x8f) | 0x20;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, c);
+
+ for (c = 0; c < 10; c++)
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (0x40 + c), (0x02 + c));
+
+ for (c = 0; c < 10; c++)
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (c + 0x4a), (c + 0x0E));
+
+ for (c = 0; c < 10; c++)
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (0x54 + c), (0x1A + c));
+
+ break;
+ case Hdmi_36bit:
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c = c & ~0x04;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, &c);
+ c = ((c & 0x8f) | 0x30);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL2_REG, c);
+
+ for (c = 0; c < 36; c++)
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (0x40 + c), (0x00 + c));
+
+ break;
+ default:
+ break;
+ }
+
+ /* config blank with YUV color space video */
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_AVI_DATA00_REG, &c);
+ if (c & 0x60) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0x2c, 0x80);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0x2d, 0x00);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0x2e, 0x80);
+ }
+}
+
+static void sp_tx_enable_video_input(unchar Enable)
+{
+ unchar c;
+
+ if (Enable) {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c = (c & 0xf7) | SP_TX_VID_CTRL1_VID_EN;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK1, 0xf5);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_STATUS1, 0x0a);
+ pr_info("Slimport Video is Enabled!");
+
+ } else {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c &= ~SP_TX_VID_CTRL1_VID_EN;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+ pr_info("Slimport Video is disabled!");
+
+ }
+}
+
+static void sp_tx_enhacemode_set(void)
+{
+ unchar c;
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, DPCD_MAX_LANE_COUNT, 1, &c);
+
+ if (c & 0x80) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL4_REG, &c);
+ c |= SP_TX_SYS_CTRL4_ENHANCED;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL4_REG, c);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x01, DPCD_LANE_COUNT_SET, 1, &c);
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x01, DPCD_LANE_COUNT_SET, c | 0x80);
+
+ pr_info("Enhance mode enabled");
+ } else {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL4_REG, &c);
+ c &= ~SP_TX_SYS_CTRL4_ENHANCED;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL4_REG, c);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x01, DPCD_LANE_COUNT_SET, 1, &c);
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x01, DPCD_LANE_COUNT_SET, c & (~0x80));
+
+ pr_info("Enhance mode disabled");
+ }
+}
+
+static void sp_tx_hdcp_reauth(void)
+{
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, 0x23);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, 0x03);
+}
+
+static void sp_tx_clean_hdcp_status(void)
+{
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, 0x00);
+ sp_tx_hdcp_reauth();
+}
+
+static void sp_tx_hdcp_encryption_disable(void)
+{
+ unchar c;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, &c);
+ c &= ~SP_TX_HDCP_CTRL0_ENC_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, c);
+}
+
+static void sp_tx_hdcp_encryption_enable(void)
+{
+ unchar c;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, &c);
+ c |= SP_TX_HDCP_CTRL0_ENC_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, c);
+}
+
+static void sp_tx_hw_hdcp_enable(void)
+{
+ unchar c;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, &c);
+ c &= 0xf3;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, c);
+ c |= 0x08;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_CTRL0_REG, c);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0x40, 0xb0);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0x42, 0xc8);
+
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK2, 0xfc);
+ pr_info("Hardware HDCP is enabled.");
+}
+
+void sp_tx_clean_hdcp(void)
+{
+ sp_tx_hdcp_auth_fail_counter = 0;
+ sp_tx_hdcp_auth_pass = 0;
+ sp_tx_hw_hdcp_en = 0;
+ sp_tx_hdcp_capable_chk = 0;
+ sp_tx_hdcp_auth_done = 0;
+ sp_tx_clean_hdcp_status();
+}
+
+static void sp_tx_pclk_calc(unchar *hbr_rbr)
+{
+ long int str_clk = 0;
+ unchar c;
+ unchar link_bw_current = *hbr_rbr;
+
+ switch (link_bw_current) {
+
+ case BW_54G:
+ str_clk = 540;
+ break;
+ case BW_27G:
+ str_clk = 270;
+ break;
+ case BW_162G:
+ str_clk = 162;
+ break;
+ default:
+ break;
+
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, M_VID_2, &c);
+ M_val = c * 0x10000;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, M_VID_1, &c);
+ M_val = M_val + c * 0x100;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, M_VID_0, &c);
+ M_val = M_val + c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, N_VID_2, &c);
+ N_val = c * 0x10000;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, N_VID_1, &c);
+ N_val = N_val + c * 0x100;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, N_VID_0, &c);
+ N_val = N_val + c;
+
+ str_clk = str_clk * M_val;
+ pclk = str_clk;
+ pclk = pclk / N_val;
+}
+
+void sp_tx_show_infomation(void)
+{
+ unchar c, c1;
+ uint h_res, h_act, v_res, v_act;
+ uint h_fp, h_sw, h_bp, v_fp, v_sw, v_bp;
+ ulong fresh_rate;
+
+ pr_info("\n*******SP Video Information*******\n");
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, &c);
+ if (c == 0x06) {
+ pr_info(" BW = 1.62G");
+ sp_tx_pclk_calc(&c);
+ } else if (c == 0x0a) {
+ pr_info(" BW = 2.7G");
+ sp_tx_pclk_calc(&c);
+ } else if (c == 0x14) {
+ pr_info(" BW = 5.4G");
+ sp_tx_pclk_calc(&c);
+ }
+#ifdef SSC_EN
+ pr_info(" SSC On");
+#else
+ pr_info(" SSC Off");
+#endif
+
+ pr_info(" M = %lu, N = %lu, PCLK = %ld MHz\n", M_val, N_val, pclk);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_TOTAL_LINE_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_TOTAL_LINE_STA_H, &c1);
+
+ v_res = c1;
+ v_res = v_res << 8;
+ v_res = v_res + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_ACT_LINE_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_ACT_LINE_STA_H, &c1);
+
+ v_act = c1;
+ v_act = v_act << 8;
+ v_act = v_act + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_TOTAL_PIXEL_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_TOTAL_PIXEL_STA_H, &c1);
+
+ h_res = c1;
+ h_res = h_res << 8;
+ h_res = h_res + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_ACT_PIXEL_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_ACT_PIXEL_STA_H, &c1);
+
+ h_act = c1;
+ h_act = h_act << 8;
+ h_act = h_act + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_F_PORCH_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_F_PORCH_STA_H, &c1);
+
+ h_fp = c1;
+ h_fp = h_fp << 8;
+ h_fp = h_fp + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_SYNC_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_SYNC_STA_H, &c1);
+
+ h_sw = c1;
+ h_sw = h_sw << 8;
+ h_sw = h_sw + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_B_PORCH_STA_L, &c);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_H_B_PORCH_STA_H, &c1);
+
+ h_bp = c1;
+ h_bp = h_bp << 8;
+ h_bp = h_bp + c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_V_F_PORCH_STA, &c);
+ v_fp = c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_V_SYNC_STA, &c);
+ v_sw = c;
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_V_B_PORCH_STA, &c);
+ v_bp = c;
+
+ pr_info(" Total resolution is %d * %d \n", h_res, v_res);
+
+ pr_info(" HF=%d, HSW=%d, HBP=%d\n", h_fp, h_sw, h_bp);
+ pr_info(" VF=%d, VSW=%d, VBP=%d\n", v_fp, v_sw, v_bp);
+ pr_info(" Active resolution is %d * %d ", h_act, v_act);
+
+ fresh_rate = pclk * 1000;
+ fresh_rate = fresh_rate / h_res;
+ fresh_rate = fresh_rate * 1000;
+ fresh_rate = fresh_rate / v_res;
+ pr_info(" @ %ldHz\n", fresh_rate);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_VID_CTRL, &c);
+
+ if ((c & 0x06) == 0x00)
+ pr_info(" ColorSpace: RGB,");
+ else if ((c & 0x06) == 0x02)
+ pr_info(" ColorSpace: YCbCr422,");
+ else if ((c & 0x06) == 0x04)
+ pr_info(" ColorSpace: YCbCr444,");
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_VID_CTRL, &c);
+
+ if ((c & 0xe0) == 0x00)
+ pr_info(" 6 BPC");
+ else if ((c & 0xe0) == 0x20)
+ pr_info(" 8 BPC");
+ else if ((c & 0xe0) == 0x40)
+ pr_info(" 10 BPC");
+ else if ((c & 0xe0) == 0x60)
+ pr_info(" 12 BPC");
+
+ pr_info("\n***************************\n");
+
+}
+
+static void sp_tx_aux_wr(unchar offset)
+{
+ unchar c, cnt;
+ cnt = 0;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG, offset);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x04);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x01);
+ mdelay(10);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ while (c & 0x01) {
+ mdelay(10);
+ cnt++;
+
+ if (cnt == 10) {
+ pr_err("write break");
+ cnt = 0;
+ bEDID_break = 1;
+ break;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ }
+
+}
+
+static void sp_tx_aux_rd(unchar len_cmd)
+{
+ unchar c, cnt;
+ cnt = 0;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, len_cmd);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x01);
+ mdelay(10);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+ while (c & 0x01) {
+ mdelay(10);
+ cnt++;
+
+ if (cnt == 10) {
+ pr_err("read break");
+ sp_tx_rst_aux();
+ bEDID_break = 1;
+ break;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ }
+
+}
+
+unchar sp_tx_chip_located(void)
+{
+ unchar c1, c2;
+
+ sp_tx_hardware_poweron();
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_DEV_IDL_REG, &c1);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_DEV_IDH_REG, &c2);
+ if ((c1 == 0x06) && (c2 == 0x78)) {
+ pr_info("ANX7808 is found. \n");
+ return 1;
+ } else {
+ pr_info("ANX7808 is not found. \n");
+ return 0;
+ }
+}
+
+void sp_tx_vbus_poweron(void)
+{
+ unchar c;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ /* power down macro */
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_ANALOG_POWER_DOWN_REG, &c);
+ c |= SP_TX_ANALOG_POWER_DOWN_MACRO_PD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_ANALOG_POWER_DOWN_REG, c);
+ /* Power up 5V detect and short portect circuit */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, &c);
+ c &= ~0x30;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, c);
+
+ /* Enable power 3.3v out */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, &c);
+ c &= 0xFd;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, c);
+ c |= 0x02;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, c);
+
+ mdelay(100);
+
+ /* power on macro */
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_ANALOG_POWER_DOWN_REG, &c);
+ c &= ~SP_TX_ANALOG_POWER_DOWN_MACRO_PD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_ANALOG_POWER_DOWN_REG, c);
+
+ pr_info("Try to enable VBUS power");
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, &c);
+ if (!(c & 0xc0)) {
+ pr_info("3.3V output enabled");
+ return;
+ }
+ msleep(100);
+ }
+}
+
+void sp_tx_vbus_powerdown(void)
+{
+ unchar c;
+
+ /* Disableable power 3.3v out */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, &c);
+ c &= ~SP_TX_V33_SWITCH_ON;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL11, c);
+
+ /* Power down 5V detect and short portect circuit */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, &c);
+ c |= 0x30;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_PLL_FILTER_CTRL6, c);
+ pr_info("3.3V output disabled");
+}
+
+static void sp_tx_spread_enable(unchar bEnable)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SSC_CTRL_REG1, &c);
+
+ if (bEnable) {
+ c |= SPREAD_AMP;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SSC_CTRL_REG1, c);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, &c);
+ c |= SP_TX_RST_SSC;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, c);
+ c &= ~SP_TX_RST_SSC;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL2_REG, c);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x01, DPCD_DOWNSPREAD_CTRL, 1, &c);
+ c |= 0x10;
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x01, DPCD_DOWNSPREAD_CTRL, c);
+
+ } else {
+
+ c &= ~SPREAD_AMP;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SSC_CTRL_REG1, c);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x01, DPCD_DOWNSPREAD_CTRL, 1, &c);
+ c &= 0xef;
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x01, DPCD_DOWNSPREAD_CTRL, c);
+ }
+
+}
+
+static void sp_tx_config_ssc(enum SP_LINK_BW linkbw)
+{
+ unchar c;
+
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SSC_CTRL_REG1, 0x00);
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, DPCD_MAX_DOWNSPREAD, 1, &c);
+
+#ifndef SSC_1
+ /* pr_info("*** Config SSC 0.4% ***");*/
+
+ if (linkbw == BW_54G) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0xc0);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x00);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x75);
+ } else if (linkbw == BW_27G) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0x5f);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x00);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x75);
+ } else {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0x9e);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x00);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x6d);
+ }
+#else
+ /* pr_info("*** Config SSC 1% ***");*/
+ if (linkbw == BW_54G) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0xdd);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x01);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x76);
+ } else if (linkbw == BW_27G) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0xef);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x00);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x76);
+ } else {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL1, 0x8e);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL2, 0x01);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_DOWN_SPREADING_CTRL3, 0x6d);
+ }
+#endif
+ sp_tx_spread_enable(1);
+}
+
+static void sp_tx_audioinfoframesetup(void)
+{
+ int i;
+ unchar c;
+ sp_tx_read_reg(HDMI_PORT1_ADDR, 0xc0, &c);
+ SP_TX_AudioInfoFrmae.type = c;
+ sp_tx_read_reg(HDMI_PORT1_ADDR, 0xc1, &c);
+ SP_TX_AudioInfoFrmae.version = c;
+ sp_tx_read_reg(HDMI_PORT1_ADDR, 0xc2, &c);
+ SP_TX_AudioInfoFrmae.length = c;
+ for (i = 0; i < 11; i++) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, (0xc4 + i), &c);
+ SP_TX_AudioInfoFrmae.pb_byte[i] = c;
+ }
+}
+
+static void sp_tx_infoframeupdate(struct AudiInfoframe *pAudioInfoFrame)
+{
+ unchar c;
+
+ c = pAudioInfoFrame->type;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_TYPE, c);
+
+ c = pAudioInfoFrame->version;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_VER, c);
+
+ c = pAudioInfoFrame->length;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_LEN, c);
+
+ c = pAudioInfoFrame->pb_byte[0];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB0, c);
+
+ c = pAudioInfoFrame->pb_byte[1];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB1, c);
+
+ c = pAudioInfoFrame->pb_byte[2];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB2, c);
+
+ c = pAudioInfoFrame->pb_byte[3];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB3, c);
+
+ c = pAudioInfoFrame->pb_byte[4];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB4, c);
+
+ c = pAudioInfoFrame->pb_byte[5];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB5, c);
+
+ c = pAudioInfoFrame->pb_byte[6];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB6, c);
+
+ c = pAudioInfoFrame->pb_byte[7];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB7, c);
+
+ c = pAudioInfoFrame->pb_byte[8];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB8, c);
+
+ c = pAudioInfoFrame->pb_byte[9];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB9, c);
+
+ c = pAudioInfoFrame->pb_byte[10];
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_DB10, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_AUD_UP;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_AUD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+}
+
+static void sp_tx_enable_audio_output(unchar bEnable)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUD_CTRL, &c);
+
+ if (bEnable) {
+ c |= SP_TX_AUD_CTRL_AUD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUD_CTRL, c);
+
+ sp_tx_audioinfoframesetup();
+ sp_tx_infoframeupdate(&SP_TX_AudioInfoFrmae);
+ } else {
+ c &= ~SP_TX_AUD_CTRL_AUD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUD_CTRL, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c &= ~SP_TX_PKT_AUD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+ }
+}
+
+static void sp_tx_get_link_bw(unchar *bwtype)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, &c);
+
+ *bwtype = c;
+}
+
+static void sp_tx_config_audio(void)
+{
+ unchar c, g_BW;
+ int i;
+ ulong M_AUD, LS_Clk = 0;
+ ulong AUD_Freq = 0;
+ pr_notice("##Config audio ##");
+ sp_tx_power_on(SP_TX_PWR_AUDIO);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, 0xCA, &c);
+
+ switch (c & 0x0f) {
+ case 0x00:
+ AUD_Freq = 44.1;
+ break;
+ case 0x02:
+ AUD_Freq = 48;
+ break;
+ case 0x03:
+ AUD_Freq = 32;
+ break;
+ case 0x08:
+ AUD_Freq = 88.2;
+ break;
+ case 0x0a:
+ AUD_Freq = 96;
+ break;
+ case 0x0c:
+ AUD_Freq = 176.4;
+ break;
+ case 0x0e:
+ AUD_Freq = 192;
+ break;
+ default:
+ break;
+ }
+
+ sp_tx_get_link_bw(&g_BW);
+
+ switch (g_BW) {
+ case BW_162G:
+ LS_Clk = 162000;
+ break;
+ case BW_27G:
+ LS_Clk = 270000;
+ break;
+ case BW_54G:
+ LS_Clk = 540000;
+ break;
+ default:
+ break;
+ }
+
+ pr_info("AUD_Freq = %ld , LS_CLK = %ld\n", AUD_Freq, LS_Clk);
+
+ M_AUD = ((512 * AUD_Freq) / LS_Clk) * 32768;
+ M_AUD = M_AUD + 0x05;
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_AUD_INTERFACE_CTRL4, (M_AUD & 0xff));
+ M_AUD = M_AUD >> 8;
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_AUD_INTERFACE_CTRL5, (M_AUD & 0xff));
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_AUD_INTERFACE_CTRL6, 0x00);
+
+ /* let hdmi audio sample into DP */
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_AUD_INTERFACE_CTRL0, 0x00);
+
+ /* enable audio auto adjust */
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_AUD_INTERFACE_CTRL2, 0x04);
+
+ /* configure layout and channel number */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, &c);
+
+ if (c & 0x08) {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_CH_NUM_REG5, &c);
+ c |= 0xe1;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_CH_NUM_REG5, c);
+ } else {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_CH_NUM_REG5, &c);
+ c &= ~0xe1;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AUD_CH_NUM_REG5, c);
+ }
+
+ /* transfer audio chaneel status from HDMI Rx to Slinmport Tx */
+ for (i = 0; i < 5; i++) {
+ sp_tx_read_reg(HDMI_PORT0_ADDR, (0xc7 + i), &c);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, (0xD0 + i), c);
+ }
+
+ /* enable audio */
+ sp_tx_enable_audio_output(1);
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK1, &c);
+ c |= 0x04;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_COMMON_INT_MASK1, c);
+}
+
+
+static void sp_tx_get_rx_bw(unchar bMax, unchar *cBw)
+{
+ if (bMax)
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, DPCD_MAX_LINK_RATE, 1, cBw);
+ else
+ sp_tx_aux_dpcdread_bytes(0x00, 0x01, DPCD_LINK_BW_SET, 1, cBw);
+}
+
+static void sp_tx_edid_read_initial(void)
+{
+ unchar c;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, 0x50);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_15_8_REG, 0);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, &c);
+ c &= 0xf0;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_19_16_REG, c);
+}
+
+static unchar sp_tx_aux_edidread_byte(unchar offset)
+{
+
+ unchar c, i, edid[16], data_cnt, cnt;
+ unchar bReturn = 0;
+
+ cnt = 0;
+
+ sp_tx_aux_wr(offset);
+ sp_tx_aux_rd(0xf5);
+
+ data_cnt = 0;
+ while (data_cnt < 16) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_COUNT_REG, &c);
+ c = c & 0x1f;
+ if (c != 0) {
+ for (i = 0; i < c; i++) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR,
+ SP_TX_BUF_DATA_0_REG + i,
+ &edid[i + data_cnt]);
+ }
+ } else {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x01);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ while (c & 0x01) {
+ mdelay(2);
+ cnt++;
+
+ if (cnt == 10) {
+ pr_err("read break");
+ sp_tx_rst_aux();
+ bEDID_break = 1;
+ bReturn = 0x01;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR,
+ SP_TX_AUX_CTRL_REG2, &c);
+ }
+
+ bReturn = 0x02;
+ return bReturn;
+ }
+
+ data_cnt = data_cnt + c;
+ if (data_cnt < 16) {
+ sp_tx_rst_aux();
+ mdelay(10);
+ c = 0x05 | ((0x0f - data_cnt) << 4);
+ sp_tx_aux_rd(c);
+ }
+ }
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x01);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+ while (c & 0x01)
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+ if (offset < 0x80) {
+
+ for (i = 0; i < 16; i++)
+ bEDID_firstblock[offset + i] = edid[i];
+ } else if (offset >= 0x80) {
+
+ for (i = 0; i < 16; i++)
+ bEDID_extblock[offset - 0x80 + i] = edid[i];
+ }
+
+#ifdef EDID_DEBUG_PRINT
+
+ for (i = 0; i < 16; i++) {
+ if ((i & 0x0f) == 0)
+ pr_info("\n edid: [%.2x] %.2x ",
+ (unsigned int)offset, (uint)edid[i]);
+ else
+ pr_info("%.2x ", (uint)edid[i]);
+
+ if ((i & 0x0f) == 0x0f)
+ pr_info("\n");
+ }
+
+#endif
+
+ return bReturn;
+}
+
+static void sp_tx_parse_segments_edid(unchar segment, unchar offset)
+{
+ unchar c, cnt;
+ int i;
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x04);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, 0x30);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ sp_tx_wait_aux_finished();
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, &c);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG, segment);
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x04);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x01);
+ cnt = 0;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ while (c & 0x01) {
+ mdelay(10);
+ cnt++;
+ if (cnt == 10) {
+ pr_err("write break");
+ sp_tx_rst_aux();
+ cnt = 0;
+ bEDID_break = 1;
+ return;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+ }
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_ADDR_7_0_REG, 0x50);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_aux_wr(offset);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_aux_rd(0xf5);
+ cnt = 0;
+ for (i = 0; i < 16; i++) {
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_COUNT_REG, &c);
+ while ((c & 0x1f) == 0) {
+ mdelay(2);
+ cnt++;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR,
+ SP_TX_BUF_DATA_COUNT_REG, &c);
+
+ if (cnt == 10) {
+ pr_err("read break");
+ sp_tx_rst_aux();
+ bEDID_break = 1;
+ return;
+ }
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG + i, &c);
+ }
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x01);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x03);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+ while (c & 0x01)
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+
+}
+
+static unchar sp_tx_get_edid_block(void)
+{
+ unchar c;
+ sp_tx_aux_wr(0x00);
+ sp_tx_aux_rd(0x01);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG, &c);
+
+
+ sp_tx_aux_wr(0x7e);
+ sp_tx_aux_rd(0x01);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_BUF_DATA_0_REG, &c);
+ pr_info("EDID Block = %d\n", (int)(c + 1));
+
+ if (c > 3)
+ bEDID_break = 1;
+
+ return c;
+}
+
+static void sp_tx_addronly_set(unchar bSet)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, &c);
+ if (bSet) {
+ c |= SP_TX_ADDR_ONLY_BIT;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, c);
+ } else {
+ c &= ~SP_TX_ADDR_ONLY_BIT;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, c);
+ }
+}
+
+static void sp_tx_load_packet(enum PACKETS_TYPE type)
+{
+ int i;
+ unchar c;
+
+ switch (type) {
+ case AVI_PACKETS:
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AVI_TYPE, 0x82);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AVI_VER, 0x02);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AVI_LEN, 0x0d);
+
+ for (i = 0; i < 13; i++) {
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_AVI_DB0 + i,
+ SP_TX_Packet_AVI.AVI_data[i]);
+ }
+
+ break;
+
+ case SPD_PACKETS:
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_SPD_TYPE, 0x83);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_SPD_VER, 0x01);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_SPD_LEN, 0x19);
+
+ for (i = 0; i < 25; i++) {
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_SPD_DATA1 + i,
+ SP_TX_Packet_SPD.SPD_data[i]);
+ }
+
+ break;
+
+ case VSI_PACKETS:
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_TYPE, 0x81);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_VER, 0x01);
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_MPEG_LEN_REG, &c);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_LEN, c);
+
+ for (i = 0; i < 13; i++) {
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_DATA0 + i,
+ SP_TX_Packet_MPEG.MPEG_data[i]);
+ }
+
+ break;
+ case MPEG_PACKETS:
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_TYPE, 0x85);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_VER, 0x01);
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_LEN, 0x0d);
+
+ for (i = 0; i < 13; i++) {
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_MPEG_DATA0 + i,
+ SP_TX_Packet_MPEG.MPEG_data[i]);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+void sp_tx_config_packets(enum PACKETS_TYPE bType)
+{
+ unchar c;
+
+ switch (bType) {
+ case AVI_PACKETS:
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c &= ~SP_TX_PKT_AVI_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+ sp_tx_load_packet(AVI_PACKETS);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_AVI_UD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_AVI_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ break;
+
+ case SPD_PACKETS:
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c &= ~SP_TX_PKT_SPD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+ sp_tx_load_packet(SPD_PACKETS);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_SPD_UD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_SPD_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ break;
+
+ case VSI_PACKETS:
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c &= ~SP_TX_PKT_MPEG_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_load_packet(VSI_PACKETS);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_MPEG_UD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_MPEG_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ break;
+ case MPEG_PACKETS:
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c &= ~SP_TX_PKT_MPEG_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+
+ sp_tx_load_packet(MPEG_PACKETS);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_MPEG_UD;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, &c);
+ c |= SP_TX_PKT_MPEG_EN;
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_PKT_EN_REG, c);
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+void sp_tx_avi_setup(void)
+{
+ unchar c;
+ int i;
+ for (i = 0; i < 13; i++) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, (HDMI_RX_AVI_DATA00_REG + i), &c);
+ SP_TX_Packet_AVI.AVI_data[i] = c;
+ }
+}
+
+static unchar sp_tx_bw_lc_sel(void)
+{
+ unchar over_bw = 0;
+ uint pixel_clk = 0;
+ enum HDMI_color_depth hdmi_input_color_depth = Hdmi_legacy;
+ unchar c;
+
+ pr_info("input pclk = %d\n", (unsigned int)pclk);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VIDEO_STATUS_REG1, &c);
+ c &= 0xf0;
+
+ if (c == 0x00)
+ hdmi_input_color_depth = Hdmi_legacy;
+ else if (c == 0x40)
+ hdmi_input_color_depth = Hdmi_24bit;
+ else if (c == 0x50)
+ hdmi_input_color_depth = Hdmi_30bit;
+ else if (c == 0x60)
+ hdmi_input_color_depth = Hdmi_36bit;
+ else
+ pr_warn("HDMI input color depth is not supported .\n");
+
+ switch (hdmi_input_color_depth) {
+ case Hdmi_legacy:
+ case Hdmi_24bit:
+ pixel_clk = pclk;
+ break;
+ case Hdmi_30bit:
+ pixel_clk = pclk * 5 / 4;
+ break;
+ case Hdmi_36bit:
+ pixel_clk = pclk * 3 / 2;
+ break;
+ default:
+ break;
+ }
+
+ if (pixel_clk <= 54) {
+ sp_tx_bw = BW_162G;
+ over_bw = 0;
+ } else if ((54 < pixel_clk) && (pixel_clk <= 90)) {
+ if (sp_tx_bw >= BW_27G) {
+ sp_tx_bw = BW_27G;
+ over_bw = 0;
+ } else
+ over_bw = 1;
+ } else if ((90 < pixel_clk) && (pixel_clk <= 180)) {
+ if (sp_tx_bw >= BW_54G) {
+ sp_tx_bw = BW_54G;
+ over_bw = 0;
+ } else
+ over_bw = 1;
+ } else
+ over_bw = 1;
+
+ if (over_bw)
+ pr_err("over bw!\n");
+ else
+ pr_notice("The optimized BW =%.2x\n", sp_tx_bw);
+
+ return over_bw;
+
+}
+
+unchar sp_tx_hw_link_training(void)
+{
+
+ unchar c;
+
+ if (!sp_tx_hw_lt_enable) {
+
+ pr_notice("Hardware link training");
+#ifdef SSC_EN
+ sp_tx_config_ssc(sp_tx_bw);
+#else
+ sp_tx_spread_enable(0);
+#endif
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, sp_tx_bw);
+
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xc8, 0x01);
+ mdelay(2);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xc8, 0x00);
+
+ sp_tx_enhacemode_set();
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x06, 0x00, 0x01, &c);
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x06, 0x00, (c | 0x01));
+
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_TRAINING_LANE0_SET_REG, 0x09);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_TRAINING_CTRL_REG,
+ SP_TX_LINK_TRAINING_CTRL_EN);
+
+ sp_tx_hw_lt_enable = 1;
+ return 1;
+
+ }
+
+
+ if (sp_tx_hw_lt_done) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x02, 1, ByteBuf);
+
+
+ if (ByteBuf[0] != 0x07) {
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ return 1;
+ } else {
+ sp_tx_hw_lt_done = 1;
+
+ /* if there is link error, adjust pre-emphsis to check error again.
+ If there is no error,keep the setting, otherwise use 400mv0db */
+ if (sp_tx_link_err_check()) {
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_TRAINING_LANE0_SET_REG, 0x09);
+
+ if (sp_tx_link_err_check())
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_TRAINING_LANE0_SET_REG, 0x01);
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, &c);
+
+ if (c != sp_tx_bw) {
+ sp_tx_hw_lt_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ return 1;
+ }
+
+ sp_tx_set_system_state(SP_TX_CONFIG_SLIMPORT_OUTPUT);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+uint sp_tx_link_err_check(void)
+{
+ uint errl = 0, errh = 0;
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x10, 2, ByteBuf);
+ mdelay(5);
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x10, 2, ByteBuf);
+ errh = ByteBuf[1];
+
+ if (errh & 0x80) {
+ errl = ByteBuf[0];
+ errh = (errh & 0x7f) << 8;
+ errl = errh + errl;
+ }
+
+ pr_err(" Err of Lane = %d\n", errl);
+ return errl;
+}
+
+unchar sp_tx_lt_pre_config(void)
+{
+ unchar legel_bw, c;
+ unchar link_bw = 0;
+
+ legel_bw = 1;
+
+ if (!sp_tx_get_pll_lock_status()) {
+ pr_err("PLL not lock!");
+ return 1;
+ }
+
+ if (!sp_tx_link_config_done) {
+ sp_tx_get_rx_bw(1, &c);
+ sp_tx_bw = c;
+
+ if ((sp_tx_bw != BW_27G) && (sp_tx_bw != BW_162G)
+ && (sp_tx_bw != BW_54G))
+ return 1;
+
+ sp_tx_power_on(SP_TX_PWR_VIDEO);
+ sp_tx_video_mute(1);
+
+ sp_tx_enable_video_input(1);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL2_REG, &c);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL2_REG, c);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL2_REG, &c);
+
+ if (c & SP_TX_SYS_CTRL2_CHA_STA) {
+ pr_err("Stream clock not stable!");
+ return 1;
+ }
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL3_REG, &c);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL3_REG, c);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_SYS_CTRL3_REG, &c);
+
+ if (!(c & SP_TX_SYS_CTRL3_STRM_VALID)) {
+ pr_err("video stream not valid!");
+ return 1;
+ }
+
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, 0x14);
+ sp_tx_get_link_bw(&link_bw);
+ sp_tx_pclk_calc(&link_bw);
+
+ /* Optimize the LT to get minimum power consumption */
+ if (sp_tx_bw_lc_sel()) {
+ pr_err("****Over bandwidth****");
+ return 1;
+ }
+
+ sp_tx_link_config_done = 1;
+ }
+
+ return 0;
+}
+
+void sp_tx_video_mute(unchar enable)
+{
+ unchar c;
+
+ if (enable) {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c |= SP_TX_VID_CTRL1_VID_MUTE;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+ } else {
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, &c);
+ c &= ~SP_TX_VID_CTRL1_VID_MUTE;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL1_REG, c);
+ }
+
+}
+
+void sp_tx_send_message(enum SP_TX_SEND_MSG message)
+{
+ unchar c;
+
+ switch (message) {
+ case MSG_OCM_EN:
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, 0x25, 0x5a);
+ break;
+
+ case MSG_INPUT_HDMI:
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, 0x26, 0x01);
+ break;
+
+ case MSG_INPUT_DVI:
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, 0x26, 0x00);
+ break;
+
+ case MSG_LINK_TRAINING:
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, 0x27, 0x01);
+ break;
+
+ case MSG_CLEAR_IRQ:
+ sp_tx_aux_dpcdread_bytes(0x00, 0x04, 0x10, 1, &c);
+ c |= 0x01;
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x04, 0x10, c);
+ break;
+ }
+
+}
+
+
+unchar sp_tx_get_cable_type(void)
+{
+ unchar SINK_OUI[8] = { 0 };
+ unchar ds_port_preset = 0;
+ unchar ds_port_recoginze = 0;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, 0x05, 1, &ds_port_preset);
+ switch (ds_port_preset & 0x07) {
+ case 0x00:
+ sp_tx_rx_mydp = 1;
+ sp_tx_rx_anx7730 = 0;
+ ds_port_recoginze = 1;
+ pr_notice("Downstream is DP dongle.");
+ break;
+ case 0x03:
+ sp_tx_aux_dpcdread_bytes(0x00, 0x04, 0x00, 8, SINK_OUI);
+
+ if ((SINK_OUI[0] == 0x00) && (SINK_OUI[1] == 0x22)
+ && (SINK_OUI[2] == 0xb9)
+ && (SINK_OUI[3] == 0x61) && (SINK_OUI[4] == 0x39)
+ && (SINK_OUI[5] == 0x38)
+ && (SINK_OUI[6] == 0x33)) {
+ pr_notice("Downstream is VGA dongle.");
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ ds_port_recoginze = 1;
+ }
+ break;
+ case 0x05:
+ sp_tx_aux_dpcdread_bytes(0x00, 0x04, 0x00, 8, SINK_OUI);
+
+ if ((SINK_OUI[0] == 0xb9) && (SINK_OUI[1] == 0x22)
+ && (SINK_OUI[2] == 0x00)
+ && (SINK_OUI[3] == 0x00) && (SINK_OUI[4] == 0x00)
+ && (SINK_OUI[5] == 0x00)
+ && (SINK_OUI[6] == 0x00)) {
+ pr_notice("Downstream is HDMI dongle.");
+ sp_tx_send_message(MSG_OCM_EN);
+ sp_tx_rx_anx7730 = 1;
+ sp_tx_rx_mydp = 0;
+ ds_port_recoginze = 1;
+ }
+ break;
+ default:
+ msleep(1000);
+ pr_err("Downstream can not recognized.");
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ ds_port_recoginze = 0;
+ break;
+ }
+
+ if (ds_port_recoginze)
+ return 1;
+
+ }
+
+ return 0;
+}
+
+unchar sp_tx_get_hdmi_connection(void)
+{
+ unchar c;
+ msleep(200);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x18, 1, &c);
+ if ((c & 0x41) == 0x41) {
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, 0xf3, 0x70);
+ return 1;
+ } else
+ return 0;
+}
+
+unchar sp_tx_get_vga_connection(void)
+{
+ unchar c;
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x00, 1, &c);
+ if (c & 0x01)
+ return 1;
+ else
+ return 0;
+}
+
+static unchar sp_tx_get_ds_video_status(void)
+{
+ unchar c;
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x27, 1, &c);
+ if (c & 0x01)
+ return 1;
+ else
+ return 0;
+}
+
+unchar sp_tx_get_dp_connection(void)
+{
+ unchar c;
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x00, 1, &c);
+ if (c & 0x01) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, 0x04, 1, &c);
+ if (c & 0x20)
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x06, 0x00, 0x20);
+ return 1;
+ } else
+ return 0;
+}
+
+void sp_tx_edid_read(void)
+{
+ unchar i, j, edid_block = 0, segment = 0, offset = 0;
+
+ sp_tx_edid_read_initial();
+
+ bEDID_break = 0;
+
+ sp_tx_addronly_set(1);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG, 0x04);
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, SP_TX_AUX_CTRL_REG2, 0x01);
+ sp_tx_wait_aux_finished();
+
+ edid_block = sp_tx_get_edid_block();
+
+ if (edid_block < 2) {
+ edid_block = 8 * (edid_block + 1);
+ for (i = 0; i < edid_block; i++) {
+ if (!bEDID_break)
+ sp_tx_aux_edidread_byte(i * 16);
+ mdelay(10);
+ }
+
+ sp_tx_addronly_set(0);
+
+ } else {
+
+ for (i = 0; i < 16; i++) {
+ if (!bEDID_break)
+ sp_tx_aux_edidread_byte(i * 16);
+ }
+
+ sp_tx_addronly_set(0);
+
+ if (!bEDID_break) {
+ edid_block = (edid_block + 1);
+
+ for (i = 0; i < ((edid_block - 1) / 2); i++) {
+ pr_notice("EXT 256 EDID block");
+ segment = i + 1;
+
+ for (j = 0; j < 16; j++) {
+ sp_tx_parse_segments_edid(segment,
+ offset);
+ offset = offset + 0x10;
+ }
+ }
+
+ if (edid_block % 2) {
+ pr_notice("Last block");
+ segment = segment + 1;
+
+ for (j = 0; j < 8; j++) {
+ sp_tx_parse_segments_edid(segment,
+ offset);
+ offset = offset + 0x10;
+ }
+ }
+ }
+ }
+
+ sp_tx_addronly_set(0);
+ sp_tx_rst_aux();
+
+}
+
+static void sp_tx_pll_changed_int_handler(void)
+{
+
+ if (sp_tx_system_state > SP_TX_PARSE_EDID) {
+ if (!sp_tx_get_pll_lock_status()) {
+ pr_err("PLL:_______________PLL not lock!");
+ sp_tx_clean_hdcp();
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ }
+ }
+}
+
+static void sp_tx_auth_done_int_handler(void)
+{
+ unchar c;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_HDCP_STATUS, &c);
+
+ if (c & SP_TX_HDCP_AUTH_PASS) {
+ sp_tx_aux_dpcdread_bytes(0x06, 0x80, 0x2A, 2, ByteBuf);
+ c = ByteBuf[1];
+
+ if (c & 0x08) {
+ /* max cascade read, fail */
+ sp_tx_video_mute(1);
+ sp_tx_clean_hdcp();
+ pr_err("Re-authentication!");
+ } else {
+ pr_notice("Authentication pass in Auth_Done");
+ sp_tx_hdcp_auth_pass = 1;
+ sp_tx_hdcp_auth_fail_counter = 0;
+ }
+
+ } else {
+ pr_err("Authentication failed in AUTH_done");
+ sp_tx_hdcp_auth_pass = 0;
+ sp_tx_hdcp_auth_fail_counter++;
+
+ if (sp_tx_hdcp_auth_fail_counter >= SP_TX_HDCP_FAIL_THRESHOLD) {
+ sp_tx_video_mute(1);
+ sp_tx_clean_hdcp();
+ } else {
+ sp_tx_video_mute(1);
+ sp_tx_clean_hdcp();
+ pr_err("Re-authentication!");
+
+ if (sp_tx_system_state > SP_TX_CONFIG_SLIMPORT_OUTPUT) {
+ sp_tx_set_system_state
+ (SP_TX_HDCP_AUTHENTICATION);
+ return;
+ }
+
+ }
+ }
+
+ sp_tx_hdcp_auth_done = 1;
+}
+
+static void sp_tx_lt_done_int_handler(void)
+{
+ unchar c, c1;
+
+ if ((sp_tx_hw_lt_done) || (sp_tx_system_state != SP_TX_LINK_TRAINING))
+ return;
+
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_TRAINING_CTRL_REG, &c);
+ if (c & 0x80) {
+ c = (c & 0x70) >> 4;
+ pr_err("HW LT failed in interrupt, ERR code = %.2x\n", (uint) c);
+
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+
+ } else {
+
+ sp_tx_hw_lt_done = 1;
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_TRAINING_LANE0_SET_REG, &c);
+ sp_tx_read_reg(SP_TX_PORT0_ADDR, SP_TX_LINK_BW_SET_REG, &c1);
+ pr_notice("HW LT succeed,LANE0_SET = %.2x, link_bw = %.2x\n", (uint) c,
+ (uint) c1);
+ }
+}
+
+static void sp_tx_link_change_int_handler(void)
+{
+ unchar lane0_1_status, sl_cr, al;
+
+ if (sp_tx_system_state < SP_TX_CONFIG_SLIMPORT_OUTPUT)
+ return;
+
+ sp_tx_link_err_check();
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, DPCD_LANE_ALIGN_STATUS_UPDATED, 1,
+ ByteBuf);
+ al = ByteBuf[0];
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, DPCD_LANE0_1_STATUS, 1, ByteBuf);
+ lane0_1_status = ByteBuf[0];
+
+ if (((lane0_1_status & 0x01) == 0) || ((lane0_1_status & 0x04) == 0))
+ sl_cr = 0;
+ else
+ sl_cr = 1;
+ if (((al & 0x01) == 0) || (sl_cr == 0)) {
+ if ((al & 0x01) == 0)
+ pr_err("Lane align not done\n");
+
+ if (sl_cr == 0)
+ pr_err("Lane clock recovery not done\n");
+
+ if ((sp_tx_system_state > SP_TX_LINK_TRAINING)
+ && sp_tx_link_config_done) {
+ sp_tx_link_config_done = 0;
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+ pr_err("IRQ:____________re-LT request!");
+ }
+ }
+
+}
+
+static void sp_tx_polling_err_int_handler(void)
+{
+ unchar c;
+ int i;
+
+ if ((sp_tx_system_state < SP_TX_WAIT_SLIMPORT_PLUGIN) || sp_tx_pd_mode)
+ return;
+
+ for (i = 0; i < 5; i++) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x00, 0x00, 1, &c);
+
+ if (c == 0x11)
+ return;
+
+ mdelay(10);
+ }
+
+ if (sp_tx_pd_mode == 0) {
+ pr_err("Cwire polling is corrupted,power down ANX7808.\n");
+ sp_tx_clean_hdcp();
+ sp_tx_vbus_powerdown();
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_hardware_powerdown();
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_rx_anx7730 = 0;
+ sp_tx_rx_mydp = 0;
+ }
+}
+
+static void sp_tx_irq_isp(void)
+{
+ unchar c, c1, lane0_1_status, sl_cr, al;
+ unchar IRQ_Vector, Int_vector1, Int_vector2;
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, DPCD_DEVICE_SERVICE_IRQ_VECTOR, 1,
+ ByteBuf);
+ IRQ_Vector = ByteBuf[0];
+ sp_tx_aux_dpcdwrite_bytes(0x00, 0x02, DPCD_DEVICE_SERVICE_IRQ_VECTOR, 1,
+ ByteBuf);
+
+ /* HDCP IRQ */
+ if (IRQ_Vector & 0x04) {
+ if (sp_tx_hdcp_auth_pass) {
+ sp_tx_aux_dpcdread_bytes(0x06, 0x80, 0x29, 1, &c1);
+ if (c1 & 0x04) {
+ if (sp_tx_system_state >
+ SP_TX_HDCP_AUTHENTICATION) {
+ sp_tx_set_system_state
+ (SP_TX_HDCP_AUTHENTICATION);
+ sp_tx_clean_hdcp();
+ pr_err("IRQ:____________HDCP Sync lost!");
+ }
+ }
+ }
+ }
+
+ /* specific int */
+ if ((IRQ_Vector & 0x40) && (sp_tx_rx_anx7730)) {
+
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, DPCD_SPECIFIC_INTERRUPT_1,
+ 1, &Int_vector1);
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, DPCD_SPECIFIC_INTERRUPT_1,
+ Int_vector1);
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, DPCD_SPECIFIC_INTERRUPT_2,
+ 1, &Int_vector2);
+ sp_tx_aux_dpcdwrite_byte(0x00, 0x05, DPCD_SPECIFIC_INTERRUPT_2,
+ Int_vector2);
+
+ if ((Int_vector1 & 0x01) == 0x01) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x18, 1, &c);
+ if (c & 0x01)
+ pr_notice("Downstream HDMI is pluged!\n");
+ }
+
+ if ((Int_vector1 & 0x02) == 0x02) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x18, 1, &c);
+ if ((c & 0x01) != 0x01) {
+ pr_notice("Downstream HDMI is unpluged!\n");
+
+ if ((sp_tx_system_state >
+ SP_TX_WAIT_SLIMPORT_PLUGIN)
+ && (!sp_tx_pd_mode)) {
+ sp_tx_clean_hdcp();
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_hardware_powerdown();
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ }
+ }
+ }
+
+ if (((Int_vector1 & 0x04) == 0x04)
+ && (sp_tx_system_state > SP_TX_CONFIG_SLIMPORT_OUTPUT)) {
+
+ pr_err("Rx specific IRQ: Link is down!\n");
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02,
+ DPCD_LANE_ALIGN_STATUS_UPDATED,
+ 1, ByteBuf);
+ al = ByteBuf[0];
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02,
+ DPCD_LANE0_1_STATUS, 1,
+ ByteBuf);
+ lane0_1_status = ByteBuf[0];
+
+ if (((lane0_1_status & 0x01) == 0)
+ || ((lane0_1_status & 0x04) == 0))
+ sl_cr = 0;
+ else
+ sl_cr = 1;
+
+ if (((al & 0x01) == 0) || (sl_cr == 0)) {
+ if ((al & 0x01) == 0)
+ pr_err("Lane align not done\n");
+
+ if (sl_cr == 0)
+ pr_err("Lane clock recovery not done\n");
+
+ if ((sp_tx_system_state > SP_TX_LINK_TRAINING)
+ && sp_tx_link_config_done) {
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+ pr_err("IRQ:____________re-LT request!");
+ }
+ }
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x18, 1, &c);
+ if (!(c & 0x40)) {
+ if ((sp_tx_system_state > SP_TX_WAIT_SLIMPORT_PLUGIN)
+ && (!sp_tx_pd_mode)) {
+ sp_tx_clean_hdcp();
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_hardware_powerdown();
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ }
+ }
+
+ }
+
+ if ((Int_vector1 & 0x08) == 0x08) {
+ pr_info("Downstream HDCP is done!\n");
+
+ if ((Int_vector1 & 0x10) != 0x10)
+ pr_info("Downstream HDCP is passed!\n");
+ else {
+ if (sp_tx_system_state > SP_TX_CONFIG_SLIMPORT_OUTPUT) {
+ sp_tx_video_mute(1);
+ sp_tx_clean_hdcp();
+ sp_tx_set_system_state(SP_TX_HDCP_AUTHENTICATION);
+ pr_err("Re-authentication due to downstream HDCP failure!");
+ }
+ }
+ }
+
+ if ((Int_vector1 & 0x20) == 0x20) {
+ pr_err(" Downstream HDCP link integrity check fail!");
+
+ if (sp_tx_system_state > SP_TX_HDCP_AUTHENTICATION) {
+ sp_tx_set_system_state(SP_TX_HDCP_AUTHENTICATION);
+ sp_tx_clean_hdcp();
+ pr_err("IRQ:____________HDCP Sync lost!");
+ }
+ }
+
+ if ((Int_vector1 & 0x40) == 0x40)
+ pr_info("Receive CEC command from upstream done!");
+
+
+ if ((Int_vector1 & 0x80) == 0x80)
+ pr_info("CEC command transfer to downstream done!");
+
+
+ if ((Int_vector2 & 0x04) == 0x04) {
+ sp_tx_aux_dpcdread_bytes(0x00, 0x05, 0x18, 1, &c);
+
+ if ((c & 0x40) == 0x40)
+ pr_notice("Downstream HDMI termination is detected!\n");
+ }
+
+ /* specific int */
+ } else if ((IRQ_Vector & 0x40) && (!sp_tx_rx_anx7730)) {
+
+ sp_tx_send_message(MSG_CLEAR_IRQ);
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, 0x00, 1, &c);
+ if (!(c & 0x01)) {
+ if ((sp_tx_system_state > SP_TX_WAIT_SLIMPORT_PLUGIN)
+ && (!sp_tx_pd_mode)) {
+ sp_tx_power_down(SP_TX_PWR_TOTAL);
+ sp_tx_power_down(SP_TX_PWR_REG);
+ sp_tx_vbus_powerdown();
+ sp_tx_hardware_powerdown();
+ sp_tx_clean_hdcp();
+ sp_tx_pd_mode = 1;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_set_system_state(SP_TX_WAIT_SLIMPORT_PLUGIN);
+ }
+ }
+
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, DPCD_LANE_ALIGN_STATUS_UPDATED, 1, ByteBuf);
+ al = ByteBuf[0];
+ sp_tx_aux_dpcdread_bytes(0x00, 0x02, DPCD_LANE0_1_STATUS, 1, ByteBuf);
+ lane0_1_status = ByteBuf[0];
+
+ if (((lane0_1_status & 0x01) == 0)
+ || ((lane0_1_status & 0x04) == 0))
+ sl_cr = 0;
+ else
+ sl_cr = 1;
+ if (((al & 0x01) == 0) || (sl_cr == 0)) {
+ if ((al & 0x01) == 0)
+ pr_err("Lane align not done\n");
+
+ if (sl_cr == 0)
+ pr_err("Lane clock recovery not done\n");
+
+ if ((sp_tx_system_state > SP_TX_LINK_TRAINING)
+ && sp_tx_link_config_done) {
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+ pr_err("IRQ:____________re-LT request!");
+ }
+ }
+ }
+}
+
+static void sp_tx_sink_irq_int_handler(void)
+{
+ sp_tx_irq_isp();
+}
+
+void sp_tx_hdcp_process(void)
+{
+ unchar c;
+
+ if (!sp_tx_hdcp_capable_chk) {
+ sp_tx_hdcp_capable_chk = 1;
+
+ sp_tx_aux_dpcdread_bytes(0x06, 0x80, 0x28, 1, &c);
+ if (!(c & 0x01)) {
+ pr_err("Sink is not capable HDCP");
+ sp_tx_video_mute(1);
+ sp_tx_set_system_state(SP_TX_PLAY_BACK);
+ return;
+ }
+ }
+
+ if (!sp_tx_get_ds_video_status())
+ return;
+
+ if (!sp_tx_hw_hdcp_en) {
+ sp_tx_power_on(SP_TX_PWR_HDCP);
+ mdelay(50);
+ sp_tx_hw_hdcp_enable();
+ sp_tx_hw_hdcp_en = 1;
+ }
+
+ if (sp_tx_hdcp_auth_done) {
+ sp_tx_hdcp_auth_done = 0;
+
+ if (sp_tx_hdcp_auth_pass) {
+
+ sp_tx_hdcp_encryption_enable();
+ sp_tx_video_mute(0);
+ pr_notice("@@@@@@@hdcp_auth_pass@@@@@@\n");
+
+ } else {
+ sp_tx_hdcp_encryption_disable();
+ sp_tx_video_mute(1);
+ pr_notice("*********hdcp_auth_failed*********\n");
+ return;
+ }
+
+ sp_tx_set_system_state(SP_TX_PLAY_BACK);
+ sp_tx_show_infomation();
+ }
+}
+
+void sp_tx_set_system_state(enum SP_TX_System_State ss)
+{
+
+ pr_notice("SP_TX To System State: ");
+
+ switch (ss) {
+ case SP_TX_INITIAL:
+ sp_tx_system_state = SP_TX_INITIAL;
+ pr_notice("SP_TX_INITIAL");
+ break;
+ case SP_TX_WAIT_SLIMPORT_PLUGIN:
+ sp_tx_system_state = SP_TX_WAIT_SLIMPORT_PLUGIN;
+ pr_notice("SP_TX_WAIT_SLIMPORT_PLUGIN");
+ break;
+ case SP_TX_PARSE_EDID:
+ sp_tx_system_state = SP_TX_PARSE_EDID;
+ pr_notice("SP_TX_READ_PARSE_EDID");
+ break;
+ case SP_TX_CONFIG_HDMI_INPUT:
+ sp_tx_system_state = SP_TX_CONFIG_HDMI_INPUT;
+ pr_notice("SP_TX_CONFIG_HDMI_INPUT");
+ break;
+ case SP_TX_CONFIG_SLIMPORT_OUTPUT:
+ sp_tx_system_state = SP_TX_CONFIG_SLIMPORT_OUTPUT;
+ pr_notice("SP_TX_CONFIG_SLIMPORT_OUTPUT");
+ break;
+ case SP_TX_LINK_TRAINING:
+ sp_tx_system_state = SP_TX_LINK_TRAINING;
+ sp_tx_link_config_done = 0;
+ sp_tx_hw_lt_enable = 0;
+ sp_tx_hw_lt_done = 0;
+ pr_notice("SP_TX_LINK_TRAINING");
+ break;
+ case SP_TX_HDCP_AUTHENTICATION:
+ sp_tx_system_state = SP_TX_HDCP_AUTHENTICATION;
+ pr_notice("SP_TX_HDCP_AUTHENTICATION");
+ break;
+ case SP_TX_PLAY_BACK:
+ sp_tx_system_state = SP_TX_PLAY_BACK;
+ pr_notice("SP_TX_PLAY_BACK");
+ break;
+ default:
+ break;
+ }
+}
+
+void sp_tx_int_irq_handler(void)
+{
+ unchar c1, c2, c3, c4, c5;
+
+ sp_tx_get_int_status(COMMON_INT_1, &c1);
+ sp_tx_get_int_status(COMMON_INT_2, &c2);
+ sp_tx_get_int_status(COMMON_INT_3, &c3);
+ sp_tx_get_int_status(COMMON_INT_4, &c4);
+ sp_tx_get_int_status(SP_INT_STATUS, &c5);
+
+
+ if (c1 & SP_COMMON_INT1_PLL_LOCK_CHG)
+ sp_tx_pll_changed_int_handler();
+
+ if (c2 & SP_COMMON_INT2_AUTHDONE)
+ sp_tx_auth_done_int_handler();
+
+ if (c5 & SP_TX_INT_DPCD_IRQ_REQUEST)
+ sp_tx_sink_irq_int_handler();
+
+ if (c5 & SP_TX_INT_STATUS1_POLLING_ERR)
+ sp_tx_polling_err_int_handler();
+
+ if (c5 & SP_TX_INT_STATUS1_TRAINING_Finish)
+ sp_tx_lt_done_int_handler();
+
+ if (c5 & SP_TX_INT_STATUS1_LINK_CHANGE)
+ sp_tx_link_change_int_handler();
+
+}
+
+#ifdef EYE_TEST
+void sp_tx_eye_diagram_test(void)
+{
+ unchar c;
+ int i;
+
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, 0x05, 0x00);
+
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, &c);
+ c |= SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+ c &= ~SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG0, 0x16);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG4, 0x1b);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG7, 0x22);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG9, 0x23);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG14, 0x09);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG17, 0x16);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG19, 0x1F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG1, 0x26);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG5, 0x28);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG8, 0x2F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG15, 0x10);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG18, 0x1F);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG2, 0x36);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG6, 0x3c);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG16, 0x10);
+ sp_tx_write_reg(SP_TX_PORT1_ADDR, SP_TX_LT_CTRL_REG3, 0x3F);
+ /* set link bandwidth 5.4G */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xa0, 0x14);
+ /* set swing 400mv3.5db */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xa3, 0x09);
+ /* send link error measurement patterns */
+ sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xa2, 0x08);
+
+ pr_info
+ (" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
+
+ for (i = 0; i < 256; i++) {
+ sp_tx_read_reg(0x72, i, &c);
+
+ if ((i & 0x0f) == 0)
+ pr_info("\n [%.2x] %.2x ", (unsigned int)i,
+ (unsigned int)c);
+ else
+ pr_info("%.2x ", (unsigned int)c);
+
+ if ((i & 0x0f) == 0x0f)
+ pr_info("\n-------------------------------------");
+ }
+ pr_info("\n");
+ pr_info
+ (" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
+
+ for (i = 0; i < 256; i++) {
+ sp_tx_read_reg(0x70, i, &c);
+
+ if ((i & 0x0f) == 0)
+ pr_info("\n [%.2x] %.2x ", (unsigned int)i,
+ (unsigned int)c);
+ else
+ pr_info("%.2x ", (unsigned int)c);
+
+ if ((i & 0x0f) == 0x0f)
+ pr_info("\n-------------------------------------");
+ }
+
+ pr_info("*******Eye Diagram Test Pattern is sent********\n");
+
+}
+#endif
+
+/* ***************************************************************** */
+/* Functions defination for HDMI Input */
+/* ***************************************************************** */
+
+void hdmi_rx_set_hpd(unchar Enable)
+{
+ unchar c;
+
+ if (Enable) {
+ /* set HPD high */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL3_REG, &c);
+ c |= SP_TX_VID_CTRL3_HPD_OUT;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL3_REG, c);
+ msleep(100);
+ pr_notice("HPD high is issued\n");
+ } else {
+ /* set HPD low */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL3_REG, &c);
+ c &= ~SP_TX_VID_CTRL3_HPD_OUT;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_VID_CTRL3_REG, c);
+ msleep(100);
+ pr_notice("HPD low is issued\n");
+ }
+}
+
+void hdmi_rx_set_termination(unchar Enable)
+{
+ unchar c;
+
+ if (Enable) {
+ /* set termination high */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG6, &c);
+ c &= ~0x01;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG6, c);
+ mdelay(10);
+ pr_notice("Termination high is issued\n");
+ } else {
+ /* set termination low */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG6, &c);
+ c |= 0x01;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG6, c);
+ mdelay(10);
+ pr_notice("Termination low is issued\n");
+ }
+}
+
+void hdmi_rx_tmds_en(void)
+{
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_PORT_SEL_REG, 0x11);
+ pr_notice("TMDS and DDC are enabled\n");
+}
+
+static void hdmi_rx_restart_audio_chk(void)
+{
+ if (hdmi_system_state == HDMI_AUDIO_CONFIG) {
+ pr_info("WAIT_AUDIO: HDMI_RX_Restart_Audio_Chk.");
+ g_CTS_Got = 0;
+ g_Audio_Got = 0;
+ }
+}
+
+static void hdmi_rx_set_sys_state(unchar ss)
+{
+ if (hdmi_system_state != ss) {
+ pr_notice("");
+ hdmi_system_state = ss;
+
+ switch (ss) {
+ case HDMI_CLOCK_DET:
+ pr_notice("HDMI_RX: HDMI_CLOCK_DET");
+ break;
+ case HDMI_SYNC_DET:
+ pr_notice("HDMI_RX: HDMI_SYNC_DET");
+ break;
+ case HDMI_VIDEO_CONFIG:
+ pr_notice("HDMI_RX: HDMI_VIDEO_CONFIG");
+ break;
+ case HDMI_AUDIO_CONFIG:
+ pr_notice("HDMI_RX: HDMI_AUDIO_CONFIG");
+ hdmi_rx_restart_audio_chk();
+ break;
+ case HDMI_PLAYBACK:
+ pr_notice("HDMI_RX: HDMI_PLAYBACK");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void hdmi_rx_mute_video(void)
+{
+ unchar c;
+
+ pr_info("Mute Video.");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, &c);
+ c |= HDMI_RX_VID_MUTE;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, c);
+ g_Video_Muted = 1;
+}
+
+static void hdmi_rx_unmute_video(void)
+{
+ unchar c;
+
+ pr_info("Unmute Video.");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, &c);
+ c &= ~HDMI_RX_VID_MUTE;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, c);
+ g_Video_Muted = 0;
+}
+
+static void hdmi_rx_mute_audio(void)
+{
+ unchar c;
+
+ pr_info("Mute Audio.");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, &c);
+ c |= HDMI_RX_AUD_MUTE;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, c);
+ g_Audio_Muted = 1;
+}
+
+static void hdmi_rx_unmute_audio(void)
+{
+ unchar c;
+
+ pr_info("Unmute Audio.");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, &c);
+ c &= ~HDMI_RX_AUD_MUTE;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, c);
+ g_Audio_Muted = 0;
+}
+
+static unchar hdmi_rx_is_video_change(void)
+{
+ unchar ch, cl;
+ ulong n;
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HTOTAL_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HTOTAL_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+
+ if ((g_Cur_H_Res < (n - 10)) || (g_Cur_H_Res > (n + 10))) {
+ pr_err("H_Res changed.");
+ pr_err("Current H_Res = %ld\n", n);
+ return 1;
+ }
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VTOTAL_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VTOTAL_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+
+ if ((g_Cur_V_Res < (n - 10)) || (g_Cur_V_Res > (n + 10))) {
+ pr_err("V_Res changed.\n");
+ pr_err("Current V_Res = %ld\n", n);
+ return 1;
+ }
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, &cl);
+
+ cl &= HDMI_RX_HDMI_MODE;
+
+ if (g_HDMI_DVI_Status != cl) {
+ pr_err("DVI to HDMI or HDMI to DVI Change.");
+ return 1;
+ }
+
+ return 0;
+}
+
+static void hdmi_rx_get_video_info(void)
+{
+ unchar ch, cl;
+ uint n;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HTOTAL_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HTOTAL_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+ g_Cur_H_Res = n;
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VTOTAL_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VTOTAL_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+ g_Cur_V_Res = n;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VID_PCLK_CNTR_REG, &cl);
+ g_Cur_Pix_Clk = cl;
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, &cl);
+ g_HDMI_DVI_Status = ((cl & HDMI_RX_HDMI_MODE) == HDMI_RX_HDMI_MODE);
+}
+
+static void hdmi_rx_show_video_info(void)
+{
+ unchar c, c1;
+ unchar cl, ch;
+ ulong n;
+ ulong h_res, v_res;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HACT_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HACT_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+ h_res = n;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VACT_LOW, &cl);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VACT_HIGH, &ch);
+ n = ch;
+ n = (n << 8) + cl;
+ v_res = n;
+
+ pr_info("");
+ pr_info("*****************HDMI_RX Info*******************");
+ pr_info("HDMI_RX Is Normally Play Back.\n");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, &c);
+
+ if (c & HDMI_RX_HDMI_MODE)
+ pr_info("HDMI_RX Mode = HDMI Mode.\n");
+ else
+ pr_info("HDMI_RX Mode = DVI Mode.\n");
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VIDEO_STATUS_REG1, &c);
+ if (c & HDMI_RX_VIDEO_TYPE)
+ v_res += v_res;
+
+ pr_info("HDMI_RX Video Resolution = %ld * %ld ", h_res, v_res);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VIDEO_STATUS_REG1, &c);
+
+ if (c & HDMI_RX_VIDEO_TYPE)
+ pr_info(" Interlace Video.");
+ else
+ pr_info(" Progressive Video.");
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_CTRL1_REG, &c);
+
+ if ((c & 0x30) == 0x00)
+ pr_info("Input Pixel Clock = Not Repeated.\n");
+ else if ((c & 0x30) == 0x10)
+ pr_info("Input Pixel Clock = 2x Video Clock. Repeated.\n");
+ else if ((c & 0x30) == 0x30)
+ pr_info("Input Pixel Clock = 4x Vvideo Clock. Repeated.\n");
+
+ if ((c & 0xc0) == 0x00)
+ pr_info("Output Video Clock = Not Divided.\n");
+ else if ((c & 0xc0) == 0x40)
+ pr_info("Output Video Clock = Divided By 2.\n");
+ else if ((c & 0xc0) == 0xc0)
+ pr_info("Output Video Clock = Divided By 4.\n");
+
+ if (c & 0x02)
+ pr_info("Output Video Using Rising Edge To Latch Data.\n");
+ else
+ pr_info("Output Video Using Falling Edge To Latch Data.\n");
+
+ pr_info("Input Video Color Depth = ");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, 0x70, &c1);
+ c1 &= 0xf0;
+
+ if (c1 == 0x00)
+ pr_info("Legacy Mode.\n");
+ else if (c1 == 0x40)
+ pr_info("24 Bit Mode.\n");
+ else if (c1 == 0x50)
+ pr_info("30 Bit Mode.\n");
+ else if (c1 == 0x60)
+ pr_info("36 Bit Mode.\n");
+ else if (c1 == 0x70)
+ pr_info("48 Bit Mode.\n");
+
+ pr_info("Input Video Color Space = ");
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_AVI_DATA00_REG, &c);
+ c &= 0x60;
+
+ if (c == 0x20)
+ pr_info("YCbCr4:2:2 .\n");
+ else if (c == 0x40)
+ pr_info("YCbCr4:4:4 .\n");
+ else if (c == 0x00)
+ pr_info("RGB.\n");
+ else
+ pr_info("Unknow 0x44 = 0x%.2x\n", (int)c);
+
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_HDCP_STATUS_REG, &c);
+
+ if (c & HDMI_RX_AUTHEN)
+ pr_info("Authentication is attempted.");
+ else
+ pr_info("Authentication is not attempted.");
+
+ for (cl = 0; cl < 20; cl++) {
+ sp_tx_read_reg(HDMI_PORT1_ADDR, HDMI_RX_HDCP_STATUS_REG, &c);
+
+ if (c & HDMI_RX_DECRYPT)
+ break;
+ else
+ mdelay(10);
+ }
+
+ if (cl < 20)
+ pr_info("Decryption is active.");
+ else
+ pr_info("Decryption is not active.");
+
+
+ pr_info("********************************************************");
+ pr_info("");
+}
+
+static void hdmi_rx_show_audio_info(void)
+{
+ unchar c;
+
+ pr_info("Audio Fs = ");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_AUD_IN_SPDIF_CH_STATUS4_REG,
+ &c);
+ c &= 0x0f;
+
+ switch (c) {
+ case 0x00:
+ pr_info("44.1 KHz.");
+ break;
+ case 0x02:
+ pr_info("48 KHz.");
+ break;
+ case 0x03:
+ pr_info("32 KHz.");
+ break;
+ case 0x08:
+ pr_info("88.2 KHz.");
+ break;
+ case 0x0a:
+ pr_info("96 KHz.");
+ break;
+ case 0x0e:
+ pr_info("192 KHz.");
+ break;
+ default:
+ break;
+ }
+
+ pr_info("");
+}
+
+static void hdmi_rx_init_var(void)
+{
+ hdmi_rx_set_sys_state(HDMI_CLOCK_DET);
+ g_Cur_H_Res = 0;
+ g_Cur_V_Res = 0;
+ g_Cur_Pix_Clk = 0;
+ g_Video_Muted = 1;
+ g_Audio_Muted = 1;
+ g_Audio_Stable_Cntr = 0;
+ g_Video_Stable_Cntr = 0;
+ g_Sync_Expire_Cntr = 0;
+ g_HDCP_Err_Cnt = 0;
+ g_HDMI_DVI_Status = DVI_MODE;
+ g_CTS_Got = 0;
+ g_Audio_Got = 0;
+ g_VSI_Got = 0;
+ g_No_VSI_Counter = 0;
+}
+
+void hdmi_rx_initialize(void)
+{
+ unchar c;
+
+ hdmi_rx_init_var();
+
+ /* Mute audio and video output */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_MUTE_CTRL_REG, 0x03);
+
+ /* Enable pll_lock, digital clock detect, disable analog clock detect */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_CHIP_CTRL_REG, 0xe5);
+
+ /* enable HW AVMUTE control */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, &c);
+ c |= HDMI_RX_AVC_OE;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, c);
+
+ /* change HDCP enable criteria value to meet HDCP CTS */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDCP_EN_CRITERIA_REG, 0x08);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, &c);
+ c |= HDMI_RX_HDCP_MAN_RST;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, c);
+ mdelay(10);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, &c);
+ c &= ~HDMI_RX_HDCP_MAN_RST;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, c);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, &c);
+ c |= HDMI_RX_SW_MAN_RST;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, c);
+ mdelay(10);
+ c &= ~HDMI_RX_SW_MAN_RST;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, c);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, &c);
+ c |= HDMI_RX_TMDS_RST;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SRST_REG, c);
+
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK1_REG, 0xff);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK2_REG, 0xf3);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK3_REG, 0x3f);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK4_REG, 0x17);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK5_REG, 0xff);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK6_REG, 0xff);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_MASK7_REG, 0x07);
+
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_EN0_REG, 0xe7);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_EN1_REG, 0x17);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_EN2_REG, 0xf0);
+
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_VID_OUTPUT_CTRL3_REG, 0X00);
+
+ /* # Enable AVC and AAC */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, &c);
+ c |= HDMI_RX_AVC_EN;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, c);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, &c);
+ c |= HDMI_RX_AAC_EN;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_AEC_CTRL_REG, c);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_PWDN1_REG, &c);
+ c &= ~HDMI_RX_PWDN_CTRL;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_PWDN1_REG, c);
+
+ /* Set EQ Value */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG2, 0x00);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG4, 0X28);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG5, 0xe3);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG7, 0X50);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG21, 0x04);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG22, 0x38);
+
+ /* force 5V detection */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_CHIP_CTRL_REG, &c);
+ c |= HDMI_RX_MAN_HDMI5V_DET;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_CHIP_CTRL_REG, c);
+
+ /* software reset for HDMI key load issue */
+ sp_tx_read_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, &c);
+ c |= SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+ c &= ~SP_TX_RST_SW_RST;
+ sp_tx_write_reg(SP_TX_PORT2_ADDR, SP_TX_RST_CTRL_REG, c);
+
+ /* Range limitation for RGB input */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_VID_DATA_RNG_CTRL_REG, &c);
+ c |= HDMI_RX_R2Y_INPUT_LIMIT;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_VID_DATA_RNG_CTRL_REG, c);
+
+ /* set GPIO control by HPD */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_PIO_CTRL, 0x02);
+
+ /* generate interrupt on any received HDMI Vendor Specific packet; */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_PKT_RX_INDU_INT_CTRL, 0x80);
+
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_CEC_CTRL_REG, 0x01);
+ /* CEC SPPED to 27MHz */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_CEC_SPEED_CTRL_REG, 0x40);
+ /* Set CEC Logic address to 15,unregistered, and enable CEC receiver */
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_CEC_CTRL_REG, 0x08);
+ hdmi_rx_set_hpd(0);
+ hdmi_rx_set_termination(0);
+ pr_notice("HDMI Rx is initialized...");
+}
+
+static void hdmi_rx_clk_detected_int(void)
+{
+ unchar c;
+
+ pr_notice("*HDMI_RX Interrupt: Pixel Clock Change.\n");
+ if (sp_tx_system_state > SP_TX_CONFIG_HDMI_INPUT) {
+ hdmi_rx_mute_audio();
+ hdmi_rx_mute_video();
+ sp_tx_video_mute(1);
+ sp_tx_enable_video_input(0);
+ sp_tx_enable_audio_output(0);
+ sp_tx_set_system_state(SP_TX_CONFIG_HDMI_INPUT);
+
+ if (hdmi_system_state > HDMI_CLOCK_DET)
+ hdmi_rx_set_sys_state(HDMI_CLOCK_DET);
+ }
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &c);
+
+ if (c & HDMI_RX_CLK_DET) {
+ pr_err("Pixel clock existed. \n");
+
+ if (hdmi_system_state == HDMI_CLOCK_DET)
+ hdmi_rx_set_sys_state(HDMI_SYNC_DET);
+ } else {
+ if (hdmi_system_state > HDMI_CLOCK_DET)
+ hdmi_rx_set_sys_state(HDMI_CLOCK_DET);
+ pr_err("Pixel clock lost. \n");
+ g_Sync_Expire_Cntr = 0;
+ }
+}
+
+static void hdmi_rx_sync_det_int(void)
+{
+ unchar c;
+
+ pr_notice("*hdmi_rx interrupt: Sync Detect.");
+
+ if (sp_tx_system_state > SP_TX_CONFIG_HDMI_INPUT) {
+ hdmi_rx_mute_audio();
+ hdmi_rx_mute_video();
+ sp_tx_video_mute(1);
+ sp_tx_enable_video_input(0);
+ sp_tx_enable_audio_output(0);
+ sp_tx_set_system_state(SP_TX_CONFIG_HDMI_INPUT);
+
+ if (hdmi_system_state > HDMI_SYNC_DET)
+ hdmi_rx_set_sys_state(HDMI_SYNC_DET);
+ }
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &c);
+ if (c & HDMI_RX_HDMI_DET) {
+ pr_notice("Sync found.");
+
+ if (hdmi_system_state == HDMI_SYNC_DET)
+ hdmi_rx_set_sys_state(HDMI_VIDEO_CONFIG);
+
+ g_Video_Stable_Cntr = 0;
+ hdmi_rx_get_video_info();
+ } else {
+ pr_err("Sync lost.");
+
+ if ((c & 0x02) && (hdmi_system_state > HDMI_SYNC_DET))
+ hdmi_rx_set_sys_state(HDMI_SYNC_DET);
+ else
+ hdmi_rx_set_sys_state(HDMI_CLOCK_DET);
+ }
+}
+
+static void hdmi_rx_hdmi_dvi_int(void)
+{
+ unchar c;
+
+ pr_notice("*HDMI_RX Interrupt: HDMI-DVI Mode Change.");
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, &c);
+ hdmi_rx_get_video_info();
+
+ if ((c & HDMI_RX_HDMI_MODE) == HDMI_RX_HDMI_MODE) {
+ pr_notice("HDMI_RX_HDMI_DVI_Int: HDMI MODE.");
+
+ if (hdmi_system_state == HDMI_PLAYBACK)
+ hdmi_rx_set_sys_state(HDMI_AUDIO_CONFIG);
+ } else {
+ hdmi_rx_unmute_audio();
+ }
+}
+
+static void hdmi_rx_av_mute_int(void)
+{
+ unchar AVMUTE_STATUS, c;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG,
+ &AVMUTE_STATUS);
+ if (AVMUTE_STATUS & HDMI_RX_MUTE_STAT) {
+ pr_notice("HDMI_RX AV mute packet received.");
+
+ if (!g_Video_Muted)
+ hdmi_rx_mute_video();
+
+ if (!g_Audio_Muted)
+ hdmi_rx_mute_audio();
+
+ c = AVMUTE_STATUS & (~HDMI_RX_MUTE_STAT);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG, c);
+ }
+}
+
+static void hdmi_rx_cts_rcv_int(void)
+{
+ unchar c;
+ g_CTS_Got = 1;
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &c);
+
+ if ((hdmi_system_state == HDMI_AUDIO_CONFIG) && (c & HDMI_RX_HDMI_DET)) {
+ if (g_CTS_Got && g_Audio_Got) {
+ if (g_Audio_Stable_Cntr >= AUDIO_STABLE_TH) {
+ hdmi_rx_unmute_audio();
+ hdmi_rx_unmute_video();
+ g_Audio_Stable_Cntr = 0;
+ hdmi_rx_show_audio_info();
+ hdmi_rx_set_sys_state(HDMI_PLAYBACK);
+ sp_tx_config_audio();
+ } else
+ g_Audio_Stable_Cntr++;
+ } else
+ g_Audio_Stable_Cntr = 0;
+ }
+}
+
+static void hdmi_rx_audio_rcv_int(void)
+{
+ unchar c;
+ g_Audio_Got = 1;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &c);
+
+ if ((hdmi_system_state == HDMI_AUDIO_CONFIG) && (c & HDMI_RX_HDMI_DET)) {
+ if (g_CTS_Got && g_Audio_Got) {
+ if (g_Audio_Stable_Cntr >= AUDIO_STABLE_TH) {
+ hdmi_rx_unmute_audio();
+ hdmi_rx_unmute_video();
+ g_Audio_Stable_Cntr = 0;
+ hdmi_rx_show_audio_info();
+ hdmi_rx_set_sys_state(HDMI_PLAYBACK);
+ sp_tx_config_audio();
+ } else
+ g_Audio_Stable_Cntr++;
+ } else
+ g_Audio_Stable_Cntr = 0;
+ }
+}
+
+static void hdmi_rx_hdcp_error_int(void)
+{
+ g_Audio_Got = 0;
+ g_CTS_Got = 0;
+
+ if (g_HDCP_Err_Cnt >= 40) {
+ g_HDCP_Err_Cnt = 0;
+ pr_err("Lots of hdcp error occured ...");
+ hdmi_rx_mute_audio();
+ hdmi_rx_mute_video();
+
+ /* issue hotplug */
+ hdmi_rx_set_hpd(0);
+ mdelay(100);
+ hdmi_rx_set_hpd(1);
+
+ } else if ((hdmi_system_state == HDMI_CLOCK_DET)
+ || (hdmi_system_state == HDMI_SYNC_DET)) {
+ g_HDCP_Err_Cnt = 0;
+ } else {
+ g_HDCP_Err_Cnt++;
+ }
+}
+
+static void hdmi_rx_new_avi_int(void)
+{
+ pr_notice("*HDMI_RX Interrupt: New AVI Packet.");
+ sp_tx_avi_setup();
+ sp_tx_config_packets(AVI_PACKETS);
+}
+
+static void hdmi_rx_new_vsi_int(void)
+{
+ /* sp_tx_set_3d_packets(); */
+ g_VSI_Got = 1;
+ /* pr_notice("New VSI packet is received."); */
+}
+
+static void hdmi_rx_no_vsi_int(void)
+{
+ /* unchar c; */
+ /* sp_tx_write_reg(SP_TX_PORT0_ADDR, 0xea, 0x00);//enable VSC */
+}
+
+void sp_tx_config_hdmi_input(void)
+{
+ unchar c;
+ unchar AVMUTE_STATUS, SYS_STATUS;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &SYS_STATUS);
+ if ((SYS_STATUS & HDMI_RX_CLK_DET)
+ && (hdmi_system_state == HDMI_CLOCK_DET))
+ hdmi_rx_set_sys_state(HDMI_SYNC_DET);
+
+ if (hdmi_system_state == HDMI_SYNC_DET) {
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_SYS_STATUS_REG, &c);
+
+ if (!(c & HDMI_RX_HDMI_DET)) {
+ if (g_Sync_Expire_Cntr >= SCDT_EXPIRE_TH) {
+ pr_err("No sync for long time.");
+ /* misc reset */
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG18, &c);
+ c |= 0x10;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG18, c);
+ mdelay(10);
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG18, &c);
+ c &= ~0x10;
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_TMDS_CTRL_REG18, c);
+ hdmi_rx_set_sys_state(HDMI_CLOCK_DET);
+ g_Sync_Expire_Cntr = 0;
+ } else
+ g_Sync_Expire_Cntr++;
+
+ return;
+ } else {
+ g_Sync_Expire_Cntr = 0;
+ hdmi_rx_set_sys_state(HDMI_VIDEO_CONFIG);
+ }
+ }
+
+ if (hdmi_system_state < HDMI_VIDEO_CONFIG)
+ return;
+
+ if (hdmi_rx_is_video_change()) {
+ pr_err("Video Changed , mute video and mute audio");
+ g_Video_Stable_Cntr = 0;
+
+ if (!g_Video_Muted)
+ hdmi_rx_mute_video();
+
+ if (!g_Audio_Muted)
+ hdmi_rx_mute_audio();
+
+ } else if (g_Video_Stable_Cntr < VIDEO_STABLE_TH) {
+ g_Video_Stable_Cntr++;
+ pr_notice("WAIT_VIDEO: Wait for video stable cntr.");
+ } else if (hdmi_system_state == HDMI_VIDEO_CONFIG) {
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_HDMI_STATUS_REG,
+ &AVMUTE_STATUS);
+
+ if (!(AVMUTE_STATUS & HDMI_RX_MUTE_STAT)) {
+ hdmi_rx_get_video_info();
+ hdmi_rx_unmute_video();
+ sp_tx_lvttl_bit_mapping();
+ sp_tx_set_system_state(SP_TX_LINK_TRAINING);
+ hdmi_rx_show_video_info();
+ sp_tx_power_down(SP_TX_PWR_AUDIO);
+
+ if (g_HDMI_DVI_Status) {
+ pr_notice("HDMI mode: Video is stable.");
+ sp_tx_send_message(MSG_INPUT_HDMI);
+ hdmi_rx_set_sys_state(HDMI_AUDIO_CONFIG);
+ } else {
+ pr_notice("DVI mode: Video is stable.");
+ sp_tx_send_message(MSG_INPUT_DVI);
+ hdmi_rx_unmute_audio();
+ hdmi_rx_set_sys_state(HDMI_PLAYBACK);
+ }
+ }
+ }
+
+ hdmi_rx_get_video_info();
+}
+
+void hdmi_rx_int_irq_handler(void)
+{
+ unchar c1, c2, c3, c4, c5, c6, c7;
+
+ if ((hdmi_system_state < HDMI_CLOCK_DET)
+ || (sp_tx_system_state < SP_TX_CONFIG_HDMI_INPUT))
+ return;
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS1_REG, &c1);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS1_REG, c1);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS2_REG, &c2);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS2_REG, c2);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS3_REG, &c3);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS3_REG, c3);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS4_REG, &c4);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS4_REG, c4);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS5_REG, &c5);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS5_REG, c5);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS6_REG, &c6);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS6_REG, c6);
+
+ sp_tx_read_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS7_REG, &c7);
+ sp_tx_write_reg(HDMI_PORT0_ADDR, HDMI_RX_INT_STATUS7_REG, c7);
+
+ if (c1 & HDMI_RX_CKDT_CHANGE)
+ hdmi_rx_clk_detected_int();
+
+ if (c1 & HDMI_RX_SCDT_CHANGE)
+ hdmi_rx_sync_det_int();
+
+ if (c1 & HDMI_RX_HDMI_DVI)
+ hdmi_rx_hdmi_dvi_int();
+
+ if (c1 & HDMI_RX_SET_MUTE)
+ hdmi_rx_av_mute_int();
+
+ if (c6 & HDMI_RX_NEW_AVI)
+ hdmi_rx_new_avi_int();
+
+ if (c7 & HDMI_RX_NEW_VS)
+ hdmi_rx_new_vsi_int();
+
+ if (c7 & HDMI_RX_NO_VSI)
+ hdmi_rx_no_vsi_int();
+
+ if ((c6 & HDMI_RX_NEW_AUD) || (c3 & HDMI_RX_AUD_MODE_CHANGE))
+ hdmi_rx_restart_audio_chk();
+
+ if (c6 & HDMI_RX_CTS_RCV)
+ hdmi_rx_cts_rcv_int();
+
+ if (c5 & HDMI_RX_AUDIO_RCV)
+ hdmi_rx_audio_rcv_int();
+
+ if (c2 & HDMI_RX_HDCP_ERR)
+ hdmi_rx_hdcp_error_int();
+
+}
+
+MODULE_DESCRIPTION("Slimport transmitter ANX7808 driver");
+MODULE_AUTHOR("FeiWang <fwang@analogixsemi.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/slimport_anx7808/slimport_tx_drv.h b/drivers/misc/slimport_anx7808/slimport_tx_drv.h
new file mode 100644
index 0000000..064d43f
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/slimport_tx_drv.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __SP_TX_DRV_H
+#define __SP_TX_DRV_H
+
+/*#define D(fmt, arg...) printk("<1>```%s:%d: " fmt, __func__, __LINE__, ##arg)*/
+
+#define MAX_BUF_CNT 6
+#define DVI_MODE 0x00
+#define HDMI_MODE 0x01
+#define VIDEO_STABLE_TH 3
+#define AUDIO_STABLE_TH 1
+#define SCDT_EXPIRE_TH 10
+#define SP_TX_HDCP_FAIL_THRESHOLD 10
+
+extern unchar bEDID_extblock[128];
+extern unchar bEDID_firstblock[128];
+
+enum SP_TX_System_State {
+ SP_TX_INITIAL = 1,
+ SP_TX_WAIT_SLIMPORT_PLUGIN,
+ SP_TX_PARSE_EDID,
+ SP_TX_CONFIG_HDMI_INPUT,
+ SP_TX_LINK_TRAINING,
+ SP_TX_CONFIG_SLIMPORT_OUTPUT,
+ SP_TX_HDCP_AUTHENTICATION,
+ SP_TX_PLAY_BACK
+};
+
+enum HDMI_RX_System_State {
+ HDMI_CLOCK_DET = 1,
+ HDMI_SYNC_DET,
+ HDMI_VIDEO_CONFIG,
+ HDMI_AUDIO_CONFIG,
+ HDMI_PLAYBACK
+};
+
+enum HDMI_color_depth {
+ Hdmi_legacy,
+ Hdmi_24bit,
+ Hdmi_30bit,
+ Hdmi_36bit
+};
+enum SP_TX_POWER_BLOCK {
+ SP_TX_PWR_REG,
+ SP_TX_PWR_HDCP,
+ SP_TX_PWR_AUDIO,
+ SP_TX_PWR_VIDEO,
+ SP_TX_PWR_LINK,
+ SP_TX_PWR_TOTAL
+};
+
+enum SP_TX_SEND_MSG {
+ MSG_OCM_EN,
+ MSG_INPUT_HDMI,
+ MSG_INPUT_DVI,
+ MSG_LINK_TRAINING,
+ MSG_CLEAR_IRQ,
+};
+
+enum PACKETS_TYPE {
+ AVI_PACKETS,
+ SPD_PACKETS,
+ MPEG_PACKETS,
+ VSI_PACKETS
+};
+
+struct Packet_AVI {
+ unchar AVI_data[13];
+};
+
+struct Packet_SPD {
+ unchar SPD_data[13];
+};
+
+struct Packet_MPEG {
+ unchar MPEG_data[13];
+};
+
+struct AudiInfoframe {
+ unchar type;
+ unchar version;
+ unchar length;
+ unchar pb_byte[11];
+};
+
+enum INTStatus {
+ COMMON_INT_1 = 0,
+ COMMON_INT_2 = 1,
+ COMMON_INT_3 = 2,
+ COMMON_INT_4 = 3,
+ SP_INT_STATUS = 6
+};
+
+enum SP_LINK_BW {
+ BW_54G = 0x14,
+ BW_27G = 0x0A,
+ BW_162G = 0x06,
+ BW_NULL = 0x00
+};
+
+void sp_tx_variable_init(void);
+void sp_tx_initialization(void);
+void sp_tx_show_infomation(void);
+void sp_tx_power_down(enum SP_TX_POWER_BLOCK sp_tx_pd_block);
+void sp_tx_power_on(enum SP_TX_POWER_BLOCK sp_tx_pd_block);
+void sp_tx_avi_setup(void);
+void sp_tx_clean_hdcp(void);
+unchar sp_tx_chip_located(void);
+void sp_tx_vbus_poweron(void);
+void sp_tx_vbus_powerdown(void);
+void sp_tx_rst_aux(void);
+void sp_tx_config_packets(enum PACKETS_TYPE bType);
+unchar sp_tx_hw_link_training(void);
+unchar sp_tx_lt_pre_config(void);
+void sp_tx_video_mute(unchar enable);
+void sp_tx_set_colorspace(void);
+void sp_tx_set_3d_packets(void);
+void sp_tx_int_irq_handler(void);
+void sp_tx_send_message(enum SP_TX_SEND_MSG message);
+void sp_tx_hdcp_process(void);
+void sp_tx_set_system_state(enum SP_TX_System_State ss);
+unchar sp_tx_get_cable_type(void);
+unchar sp_tx_get_dp_connection(void);
+unchar sp_tx_get_hdmi_connection(void);
+unchar sp_tx_get_vga_connection(void);
+void sp_tx_edid_read(void);
+uint sp_tx_link_err_check(void);
+void sp_tx_eye_diagram_test(void);
+
+/* ***************************************************************** */
+/* Functions protoype for HDMI Input */
+/* ***************************************************************** */
+
+void sp_tx_config_hdmi_input(void);
+void hdmi_rx_set_hpd(unchar Enable);
+void hdmi_rx_tmds_en(void);
+void hdmi_rx_initialize(void);
+void hdmi_rx_int_irq_handler(void);
+void hdmi_rx_set_termination(unchar Enable);
+
+#endif
diff --git a/drivers/misc/slimport_anx7808/slimport_tx_reg.h b/drivers/misc/slimport_anx7808/slimport_tx_reg.h
new file mode 100644
index 0000000..59d6b4e
--- /dev/null
+++ b/drivers/misc/slimport_anx7808/slimport_tx_reg.h
@@ -0,0 +1,1311 @@
+/*
+ * Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __SP_TX_REG_DEF_H
+#define __SP_TX_REG_DEF_H
+
+#define SP_TX_PORT0_ADDR 0x70
+#define SP_TX_PORT1_ADDR 0x7A
+#define SP_TX_PORT2_ADDR 0x72
+
+#define HDMI_PORT0_ADDR 0x7e
+#define HDMI_PORT1_ADDR 0x80
+
+/***************************************************************/
+/* DEV_ADDR = 0x7e , HDMI port register*/
+#define HDMI_RX_PORT_SEL_REG 0x10
+#define HDMI_RX_DDC0_EN 0x10
+#define HDMI_RX_TMDS0_EN 0x01
+
+#define HDMI_RX_SRST_REG 0x11
+#define HDMI_RX_VIDEO_RST 0x10
+#define HDMI_RX_HDCP_MAN_RST 0X04
+#define HDMI_RX_TMDS_RST 0X02
+#define HDMI_RX_SW_MAN_RST 0X01
+
+#define HDMI_RX_SRST2_REG 0X12
+#define HDMI_RX_VFIFO_RST 0X08
+#define HDMI_RX_DDC_RST 0X04
+#define HDMI_RX_MISC_RST 0X02
+#define HDMI_RX_HW_RST 0X01
+
+#define HDMI_RX_SARST_REG 0X13
+#define HDMI_RX_DDC_RST_CTRL 0X10
+#define HDMI_RX_HDCP_RST_CTRL 0X02
+#define HDMI_RX_SW_RST_CTRL 0X01
+
+#define HDMI_RX_SYS_STATUS_REG 0X14
+#define HDMI_RX_P0_PWR5V 0X80
+#define HDMI_RX_PWR5V 0X08
+#define HDMI_RX_VSYNC 0X04
+#define HDMI_RX_CLK_DET 0X02
+#define HDMI_RX_HDMI_DET 0X01
+
+#define HDMI_RX_HDMI_STATUS_REG 0X15
+#define HDMI_RX_DEEP_COLOR_MODE 0X40
+#define HDMI_RX_HDMI_AUD_LAYOUT 0X08
+#define HDMI_RX_MUTE_STAT 0X04
+#define HDMI_RX_HDMI_MODE 0X01
+
+#define HDMI_RX_HDMI_MUTE_CTRL_REG 0X16
+#define HDMI_RX_MUTE_POL 0X04
+#define HDMI_RX_AUD_MUTE 0X02
+#define HDMI_RX_VID_MUTE 0X01
+
+#define HDMI_RX_SYS_CTRL1_REG 0X17
+
+
+#define HDMI_RX_SYS_PWDN1_REG 0X18
+#define HDMI_RX_PWDN_CTRL 0X01
+
+#define HDMI_RX_SYS_PWDN2_REG 0X19
+#define HDMI_RX_PD_PCLK 0X80
+
+#define HDMI_RX_SYS_PWDN3_REG 0X1A
+#define HDMI_RX_PD_ALL 0X01
+#define HDMI_RX_PIO_CTRL 0X1B
+#define HDMI_RX_PIO_TEST_CLOCK_EN 0X02
+
+#define HDMI_RX_CLK_CTRL_REG 0X1C
+#define HDMI_RX_CLK_AUTO_SWITCH 0X01
+
+#define HDMI_RX_AEC_CTRL_REG 0X20
+#define HDMI_RX_AVC_OE 0x80
+#define HDMI_RX_AAC_OE 0X40
+#define HDMI_RX_AVC_EN 0X02
+#define HDMI_RX_AAC_EN 0X01
+
+#define HDMI_RX_AEC_EN0_REG 0X24
+#define HDMI_RX_AEC_EN07 0X80
+#define HDMI_RX_AEC_EN06 0X40
+#define HDMI_RX_AEC_EN05 0X20
+#define HDMI_RX_AEC_EN04 0X10
+#define HDMI_RX_AEC_EN03 0X08
+#define HDMI_RX_AEC_EN02 0X04
+#define HDMI_RX_AEC_EN01 0X02
+#define HDMI_RX_AEC_EN00 0X01
+
+#define HDMI_RX_AEC_EN1_REG 0X25
+#define HDMI_RX_AEC_EN15 0X80
+#define HDMI_RX_AEC_EN14 0X40
+#define HDMI_RX_AEC_EN13 0X20
+#define HDMI_RX_AEC_EN12 0X10
+#define HDMI_RX_AEC_EN11 0X08
+#define HDMI_RX_AEC_EN10 0X04
+#define HDMI_RX_AEC_EN09 0X02
+#define HDMI_RX_AEC_EN08 0X01
+
+#define HDMI_RX_AEC_EN2_REG 0X26
+#define HDMI_RX_AEC_EN23 0X80
+#define HDMI_RX_AEC_EN22 0X40
+#define HDMI_RX_AEC_EN21 0X20
+#define HDMI_RX_AEC_EN20 0X10
+#define HDMI_RX_AEC_EN19 0X08
+#define HDMI_RX_AEC_EN18 0X04
+#define HDMI_RX_AEC_EN17 0X02
+#define HDMI_RX_AEC_EN16 0X01
+
+#define HDMI_RX_INT_STATE_REG 0X30
+#define HDMI_RX_INTR 0X01
+
+#define HDMI_RX_INT_STATUS1_REG 0X31
+#define HDMI_RX_HDMI_DVI 0X80
+#define HDMI_RX_CKDT_CHANGE 0X40
+#define HDMI_RX_SCDT_CHANGE 0X20
+#define HDMI_RX_PCLK_CHANGE 0X10
+#define HDMI_RX_PLL_UNLOCK 0X08
+#define HDMI_RX_CABLE_UNPLUG 0X04
+#define HDMI_RX_SET_MUTE 0X02
+#define HDMI_RX_SW_INTR 0X01
+
+#define HDMI_RX_INT_STATUS2_REG 0X32
+#define HDMI_RX_AUTH_START 0X80
+#define HDMI_RX_AUTH_DONE 0X40
+#define HDMI_RX_HDCP_ERR 0X20
+#define HDMI_RX_ECC_ERR 0X10
+
+
+#define HDMI_RX_INT_STATUS3_REG 0X33
+#define HDMI_RX_AUD_MODE_CHANGE 0X01
+
+#define HDMI_RX_INT_STATUS4_REG 0X34
+#define HDMI_RX_VSYNC_DET 0X80
+#define HDMI_RX_SYNC_POL_CHANGE 0X40
+#define HDMI_RX_V_RES_CHANGE 0X20
+#define HDMI_RX_H_RES_CHANGE 0X10
+#define HDMI_RX_I_P_CHANGE 0X08
+#define HDMI_RX_DP_CHANGE 0X04
+#define HDMI_RX_COLOR_DEPTH_CHANGE 0X02
+#define HDMI_RX_COLOR_MODE_CHANGE 0X01
+
+#define HDMI_RX_INT_STATUS5_REG 0X35
+#define HDMI_RX_VFIFO_OVERFLOW 0X80
+#define HDMI_RX_VFIFO_UNDERFLOW 0X40
+#define HDMI_RX_CTS_N_ERR 0X08
+#define HDMI_RX_NO_AVI 0X02
+#define HDMI_RX_AUDIO_RCV 0X01
+
+#define HDMI_RX_INT_STATUS6_REG 0X36
+#define HDMI_RX_CTS_RCV 0X80
+#define HDMI_RX_NEW_UNR_PKT 0X40
+#define HDMI_RX_NEW_MPEG 0X20
+#define HDMI_RX_NEW_AUD 0X10
+#define HDMI_RX_NEW_SPD 0X08
+#define HDMI_RX_NEW_ACP 0X04
+#define HDMI_RX_NEW_AVI 0X02
+#define HDMI_RX_NEW_CP 0X01
+
+#define HDMI_RX_INT_STATUS7_REG 0X37
+#define HDMI_RX_NO_VSI 0X80
+#define HDMI_RX_HSYNC_DET 0X20
+#define HDMI_RX_NEW_VS 0X10
+#define HDMI_RX_NO_ACP 0X08
+#define HDMI_RX_REF_CLK_CHG 0X04
+#define HDMI_RX_CEC_RX_READY 0X02
+#define HDMI_RX_CEC_TX_DONE 0X01
+
+#define HDMI_RX_ECC_CTRL_REG 0X3E
+
+#define HDMI_RX_PKT_RX_INDU_INT_CTRL 0X3F
+#define HDMI_RX_NEW_VS_CTRL 0X80
+#define HDMI_RX_NEW_UNR 0X40
+#define HDMI_RX_NEW_MPEG 0X20
+#define HDMI_RX_NEW_AUD 0X10
+#define HDMI_RX_NEW_SPD 0X08
+#define HDMI_RX_NEW_ACP 0X04
+#define HDMI_RX_NEW_AVI 0X02
+
+#define HDMI_RX_INT_CTRL_REG 0X40
+#define HDMI_RX_SOFT_INTR 0X04
+#define HDMI_RX_INTR_TYPE 0X02
+#define HDMI_RX_INTR_POL 0X01
+
+#define HDMI_RX_INT_MASK1_REG 0X41
+#define HDMI_RX_INT_MASK2_REG 0X42
+#define HDMI_RX_INT_MASK3_REG 0X43
+#define HDMI_RX_INT_MASK4_REG 0X44
+#define HDMI_RX_INT_MASK5_REG 0X45
+#define HDMI_RX_INT_MASK6_REG 0X46
+#define HDMI_RX_INT_MASK7_REG 0X47
+
+#define HDMI_RX_TMDS_CTRL_REG1 0X50
+#define HDMI_RX_TMDS_CTRL_REG2 0X51
+#define HDMI_RX_TMDS_CTRL_REG3 0X52
+#define HDMI_RX_TMDS_CTRL_REG4 0X53
+#define HDMI_RX_TMDS_CTRL_REG5 0X54
+#define HDMI_RX_TMDS_CTRL_REG6 0X55
+
+
+#define HDMI_RX_TMDS_CTRL_REG7 0X56
+#define HDMI_RX_TMDS_CTRL_REG8 0X57
+#define HDMI_RX_TMDS_CTRL_REG9 0X58
+#define HDMI_RX_TMDS_CTRL_REG10 0X59
+#define HDMI_RX_TMDS_CTRL_REG11 0X5a
+#define HDMI_RX_TMDS_CTRL_REG12 0X5b
+#define HDMI_RX_TMDS_CTRL_REG13 0X5c
+#define HDMI_RX_TMDS_CTRL_REG14 0X5d
+#define HDMI_RX_TMDS_CTRL_REG15 0X5e
+#define HDMI_RX_TMDS_CTRL_REG16 0X5f
+#define HDMI_RX_TMDS_CTRL_REG17 0X60
+#define HDMI_RX_TMDS_CTRL_REG18 0X61
+#define HDMI_RX_TMDS_CTRL_REG19 0X62
+#define HDMI_RX_TMDS_CTRL_REG20 0X63
+#define HDMI_RX_TMDS_CTRL_REG21 0X64
+#define HDMI_RX_TMDS_CTRL_REG22 0X65
+#define HDMI_RX_TMDS_CTRL_REG23 0X66
+#define HDMI_RX_TMDS_CTRL_REG24 0X67
+
+
+#define HDMI_RX_VIDEO_STATUS_REG1 0X70
+#define HDMI_RX_DEFAULT_PHASE 0X08
+#define HDMI_RX_VIDEO_TYPE 0X04
+#define HDMI_RX_VSYNC_POL 0X02
+#define HDMI_RX_HSYNC_POL 0X01
+
+#define HDMI_RX_HTOTAL_LOW 0X71
+#define HDMI_RX_HTOTAL_HIGH 0X72
+#define HDMI_RX_VTOTAL_LOW 0X73
+#define HDMI_RX_VTOTAL_HIGH 0X74
+
+#define HDMI_RX_HACT_LOW 0X75
+#define HDMI_RX_HACT_HIGH 0X76
+#define HDMI_RX_VACT_LOW 0X77
+#define HDMI_RX_VACT_HIGH 0X78
+
+#define HDMI_RX_V_SYNC_WIDTH 0X79
+#define HDMI_RX_V_BACK_PORCH 0X7A
+#define HDMI_RX_H_FRONT_PORCH_LOW 0X7B
+#define HDMI_RX_H_FRONT_PORCH_HIGH 0X7C
+
+#define HDMI_RX_H_SYNC_WIDTH_LOW 0X7D
+#define HDMI_RX_H_SYNC_WIDTH_HIGH 0X7E
+
+#define HDMI_RX_VIDEO_STATUS_REG2 0X7F
+
+#define HDMI_RX_VIDEO_MODE1_REG 0X80
+#define HDMI_RX_CSC_BT709_EN 0X10
+#define HDMI_RX_RANGE_Y2R 0X08
+#define HDMI_RX_CSPACE_Y2R 0X04
+#define HDMI_RX_RANGE_R2Y 0X02
+#define HDMI_RX_CSPACE_R2Y 0X01
+
+#define HDMI_RX_VIDEO_MODE2_REG 0X81
+#define HDMI_RX_VID_DS_MODE 0X08
+#define HDMI_RX_VID_US_MODE 0X04
+#define HDMI_RX_UP_SAMPLE 0X02
+#define HDMI_RX_DOWN_SAMPLE 0X01
+
+#define HDMI_RX_VID_PROCESSING_CTRL_REG 0X82
+#define HDMI_RX_BRU_EN 0X80
+#define HDMI_RX_BRU_RND_DIR 0X10
+#define HDMI_RX_BACK_PORCH_MODE 0X04
+#define HDMI_RX_DE_DELAY 0X02
+#define HDMI_RX_INV_FIELD 0X01
+
+#define HDMI_RX_VID_DATA_RNG_CTRL_REG 0X83
+#define HDMI_RX_YC_LIMT 0X10
+#define HDMI_RX_OUTPUT_LIMIT_EN 0X08
+#define HDMI_RX_OUTPUT_LIMIT_RANGE 0X04
+#define HDMI_RX_R2Y_INPUT_LIMIT 0X02
+#define HDMI_RX_XVYCC_LIMIT 0X01
+
+#define HDMI_RX_VID_OUTPUT_CTRL1_REG 0X84
+#define HDMI_RX_INV_VSYNC 0X80
+#define HDMI_RX_INV_HSYNC 0X40
+#define HDMI_RX_CLK48B_POL 0X20
+#define HDMI_RX_EMBED_SYNC 0X02
+#define HDMI_RX_MUX_YC 0X01
+
+#define HDMI_RX_VID_OUTPUT_CTRL2_REG 0X85
+#define HDMI_RX_BIT_SWAP 0X08
+#define HDMI_RX_BUS_MODE 0X04
+#define HDMI_RX_O_YC422 0X02
+#define HDMI_RX_O_YCBCR 0X01
+
+#define HDMI_RX_VID_OUTPUT_CTRL3_REG 0X86
+
+
+#define HDMI_RX_CH1_VID_BLANK_REG 0X87
+#define HDMI_RX_CH2_VID_BLANK_REG 0X88
+#define HDMI_RX_CH3_VID_BLANK_REG 0X89
+
+#define HDMI_RX_VID_CH_MAP_REG 0X8A
+
+#define HDMI_RX_VID_PCLK_CNTR_REG 0X8B
+
+#define HDMI_RX_TMDS_CH0_SYNC_STATUS 0X90
+#define HDMI_RX_TMDS_CH1_SYNC_STATUS 0X91
+#define HDMI_RX_TMDS_CH2_SYNC_STATUS 0X92
+#define HDMI_RX_TMDS_CH_ALIGN_STATUS 0X93
+#define HDMI_RX_TMDS_PLL_PCLK_STATUS 0X94
+#define HDMI_RX_TMDS_CLK_DEBUG_REG 0X95
+
+
+#define HDMI_RX_ACR_N_HARDWARE_VALUE1_REG 0XA6
+#define HDMI_RX_ACR_N_HARDWARE_VALUE2_REG 0XA7
+#define HDMI_RX_ACR_N_HARDWARE_VALUE3_REG 0XA8
+
+#define HDMI_RX_ACR_CTS_HARDWARE_VALUE1_REG 0XAC
+#define HDMI_RX_ACR_CTS_HARDWARE_VALUE2_REG 0XAD
+#define HDMI_RX_ACR_CTS_HARDWARE_VALUE3_REG 0XAE
+
+#define HDMI_RX_AUD_IN_SPDIF_CH_STATUS1_REG 0XC7
+#define HDMI_RX_SW_CPRGT 0X04
+#define HDMI_RX_NON_PCM 0X02
+#define HDMI_RX_PROF_APP 0X01
+
+#define HDMI_RX_AUD_IN_SPDIF_CH_STATUS2_REG 0XC8
+#define HDMI_RX_AUD_IN_SPDIF_CH_STATUS3_REG 0XC9
+#define HDMI_RX_AUD_IN_SPDIF_CH_STATUS4_REG 0XCA
+#define HDMI_RX_AUD_IN_SPDIF_CH_STATUS5_REG 0XCB
+
+
+#define HDMI_RX_CEC_CTRL_REG 0XD0
+#define HDMI_RX_CEC_RX_EN 0X08
+#define HDMI_RX_CEC_TX_ST 0X04
+#define HDMI_RX_CEC_PIN_SEL 0X02
+#define HDMI_RX_CEC_RST 0X01
+
+#define HDMI_RX_CEC_RX_STATUS_REG 0XD1
+#define HDMI_RX_CEC_RX_BUSY 0X80
+#define HDMI_RX_CEC_RX_FULL 0X20
+#define HDMI_RX_CEC_RX_EMP 0X10
+
+#define HDMI_RX_CEC_TX_STATUS_REG 0XD2
+#define HDMI_RX_CEC_TX_BUSY 0X80
+#define HDMI_RX_CEC_TX_FAIL 0X40
+#define HDMI_RX_CEC_TX_FULL 0X20
+#define HDMI_RX_CEC_TX_EMP 0X10
+
+#define HDMI_RX_CEC_FIFO_REG 0XD3
+
+#define HDMI_RX_CEC_SPEED_CTRL_REG 0XD4
+
+#define HDMI_RX_HDMI_BIST_CTRL 0XDE
+#define HDMI_RX_VID_BIST_EN 0X80
+#define HDMI_RX_BIST_ERR_ST 0X40
+#define HDMI_RX_AUD_BIST_EN 0X20
+
+#define HDMI_RX_TMDS_PRBS_TEST_REG 0XE0
+#define HDMI_RX_PRBS_TEST_EN 0X80
+
+#define HDMI_RX_HDMI_CRITERIA_REG 0XE1
+
+#define HDMI_RX_HDCP_EN_CRITERIA_REG 0XE2
+#define HDMI_RX_ENC_EN_MODE 0X20
+
+#define HDMI_RX_CHIP_CTRL_REG 0XE3
+#define HDMI_RX_MAN_HDMI5V_DET 0X08
+#define HDMI_RX_PLLLOCK_CKDT_EN 0X04
+#define HDMI_RX_ANALOG_CKDT_EN 0X02
+#define HDMI_RX_DIGITAL_CKDT_EN 0X01
+
+#define HDMI_RX_HARDWARE_REG 0XE4
+#define HDMI_RX_MAN_OSCCLK_DET 0X80
+#define HDMI_RX_CHIP_DEBUG_SEL 0X40
+#define HDMI_RX_CHIP_DEBUG_EN 0X20
+
+#define HDMI_RX_PACKET_DECODE_CTRL_REG 0XE8
+#define HDMI_RX_AUTO_STOP_DEC_ON_HDCPERR 0X02
+#define HDMI_RX_STOP_DEC 0X01
+
+#define HDMI_RX_HDCP_KEY_STATUS_REG 0XE9
+#define HDMI_RX_BIST_ERR 0X02
+
+#define HDMI_RX_HDCP_KEY_COMMAND_REG 0XEA
+
+#define HDMI_RX_DEEP_COLOR_DEBUG_REG 0XEB
+#define HDMI_RX_VFIFO_OVERFLOW 0X80
+#define HDMI_RX_VFIFO_UNDERFLOW 0X40
+#define HDMI_RX_VFIFO_TMDS_PHASE_MATCH 0X20
+#define HDMI_RX_VFIFO_SYNC_ERR 0X10
+
+#define HDMI_RX_DEEP_COLOR_CTRL_REG 0XEC
+#define HDMI_RX_EN_MAN_DEEP_COLOR 0X08
+
+#define HDMI_RX_VID_FIFO_CTRL 0XED
+#define HDMI_RX_MAN_DEF_PHASE 0X08
+#define HDMI_RX_MAN_DEF_PHASE_VAL 0X04
+
+#define HDMI_RX_ECC_ERR_CTRL 0XF9
+
+#define HDMI_RX_EEPROM_ACCESS_CTRL 0XFC
+
+
+
+/*End for DEV_addr 0x7E*/
+/***************************************************************/
+/* DEV_ADDR = 0x80 , HDMI PORT1 and HDCP registers*/
+
+#define HDMI_RX_HDCP_BKSV1 0X00
+#define HDMI_RX_HDCP_BKSV2 0X01
+#define HDMI_RX_HDCP_BKSV3 0X02
+#define HDMI_RX_HDCP_BKSV4 0X03
+#define HDMI_RX_HDCP_BKSV5 0X04
+
+#define HDMI_RX_HDCP_RI1 0X05
+#define HDMI_RX_HDCP_RI2 0X06
+
+#define HDMI_RX_HDCP_PJ 0X07
+#define HDMI_RX_HDCP_AKSV1 0X08
+#define HDMI_RX_HDCP_AKSV2 0X09
+#define HDMI_RX_HDCP_AKSV3 0X0A
+#define HDMI_RX_HDCP_AKSV4 0X0B
+#define HDMI_RX_HDCP_AKSV5 0X0C
+
+#define HDMI_RX_HDCP_AINFO 0X0D
+#define HDMI_RX_11EN 0X02
+
+#define HDMI_RX_HDCP_AN1 0X0E
+#define HDMI_RX_HDCP_AN2 0X0F
+#define HDMI_RX_HDCP_AN3 0X10
+#define HDMI_RX_HDCP_AN4 0X11
+#define HDMI_RX_HDCP_AN5 0X12
+#define HDMI_RX_HDCP_AN6 0X13
+#define HDMI_RX_HDCP_AN7 0X14
+#define HDMI_RX_HDCP_AN8 0X15
+
+#define HDMI_RX_DS_VH0_0_REG 0X16
+#define HDMI_RX_DS_VH0_1_REG 0X17
+#define HDMI_RX_DS_VH0_2_REG 0X18
+#define HDMI_RX_DS_VH0_3_REG 0X19
+#define HDMI_RX_DS_VH1_0_REG 0X1A
+#define HDMI_RX_DS_VH1_1_REG 0X1B
+#define HDMI_RX_DS_VH1_2_REG 0X1C
+#define HDMI_RX_DS_VH1_3_REG 0X1D
+#define HDMI_RX_DS_VH2_0_REG 0X1E
+#define HDMI_RX_DS_VH2_1_REG 0X1F
+#define HDMI_RX_DS_VH2_2_REG 0X20
+#define HDMI_RX_DS_VH2_3_REG 0X21
+#define HDMI_RX_DS_VH3_0_REG 0X22
+#define HDMI_RX_DS_VH3_1_REG 0X23
+#define HDMI_RX_DS_VH3_2_REG 0X24
+#define HDMI_RX_DS_VH3_3_REG 0X25
+#define HDMI_RX_DS_VH4_0_REG 0X26
+#define HDMI_RX_DS_VH4_1_REG 0X27
+#define HDMI_RX_DS_VH4_2_REG 0X28
+#define HDMI_RX_DS_VH4_3_REG 0X29
+
+#define HDMI_RX_HDCP_BCAPS 0X2A
+#define HDMI_RX_HDMI_CAP 0X80
+#define HDMI_RX_REPERTER 0X40
+#define HDMI_RX_READY 0X20
+#define HDMI_RX_FAST 0X10
+#define HDMI_RX_11FEATURE 0X02
+#define HDMI_RX_FAST_REAUTH 0X01
+
+#define HDMI_RX_HDCP_BSTATUS1 0X2B
+#define HDMI_RX_DEV_EXC 0X80
+
+#define HDMI_RX_HDCP_BSTATUS2 0X2C
+#define HDMI_RX_HDMI_MODE_IN_BSTATUS 0X10
+#define HDMI_RX_CAS_EXC 0X08
+
+#define HDMI_RX_HDCP_REPEATER_KSV_FIFO 0X2D
+
+#define HDMI_RX_DEVICE_IDENTIFICATION 0X2E
+
+#define HDMI_RX_HDCP_KSV_SHA_STARTL_REG 0X2F
+#define HDMI_RX_HDCP_KSV_SHA_STARTH_REG 0X30
+
+#define HDMI_RX_HDCP_SHA_LENGTHL_REG 0X31
+#define HDMI_RX_HDCP_SHA_LENGTHH_REG 0X32
+
+#define HDMI_RX_HDCP_SHA_CTRL_REG 0X33
+#define HDMI_RX_SHA_MODE 0X02
+#define HDMI_RX_SHA_GO 0X01
+
+#define HDMI_RX_DS_BSTATUSL_REG 0X34
+#define HDMI_RX_DS_BSTATUSH_REG 0X35
+
+#define HDMI_RX_DS_M0_0_REG 0X36
+#define HDMI_RX_DS_M0_1_REG 0X37
+#define HDMI_RX_DS_M0_2_REG 0X38
+#define HDMI_RX_DS_M0_3_REG 0X39
+#define HDMI_RX_DS_M0_4_REG 0X3A
+#define HDMI_RX_DS_M0_5_REG 0X3B
+#define HDMI_RX_DS_M0_6_REG 0X3C
+#define HDMI_RX_DS_M0_7_REG 0X3D
+
+#define HDMI_RX_HDCP_DEBUG_REG 0X3E
+#define HDMI_RX_STOPHDCP 0X80
+#define HDMI_RX_BYPASSHDCP 0X40
+#define HDMI_RX_DDC_DLY_EN 0X10
+
+#define HDMI_RX_HDCP_STATUS_REG 0X3F
+#define HDMI_RX_ADV_CIPHER 0X80
+#define HDMI_RX_LOAD_KEY_DONE 0X40
+#define HDMI_RX_DECRYPT 0X20
+#define HDMI_RX_AUTHEN 0X10
+#define HDMI_RX_BKSV_DISABLE 0X02
+#define HDMI_RX_CLEAR_RI 0X01
+
+#define HDMI_RX_SPD_TYPE_REG 0X40
+#define HDMI_RX_SPD_VER_REG 0X41
+#define HDMI_RX_SPD_LEN_REG 0X42
+#define HDMI_RX_SPD_CHKSUM_REG 0X43
+#define HDMI_RX_SPD_DATA00_REG 0X44
+#define HDMI_RX_SPD_DATA01_REG 0X45
+#define HDMI_RX_SPD_DATA02_REG 0X46
+#define HDMI_RX_SPD_DATA03_REG 0X47
+#define HDMI_RX_SPD_DATA04_REG 0X48
+#define HDMI_RX_SPD_DATA05_REG 0X49
+#define HDMI_RX_SPD_DATA06_REG 0X4A
+#define HDMI_RX_SPD_DATA07_REG 0X4B
+#define HDMI_RX_SPD_DATA08_REG 0X4C
+#define HDMI_RX_SPD_DATA09_REG 0X4D
+#define HDMI_RX_SPD_DATA0A_REG 0X4E
+#define HDMI_RX_SPD_DATA0B_REG 0X4F
+#define HDMI_RX_SPD_DATA0C_REG 0X50
+#define HDMI_RX_SPD_DATA0D_REG 0X51
+#define HDMI_RX_SPD_DATA0E_REG 0X52
+#define HDMI_RX_SPD_DATA0F_REG 0X53
+#define HDMI_RX_SPD_DATA10_REG 0X54
+#define HDMI_RX_SPD_DATA11_REG 0X55
+#define HDMI_RX_SPD_DATA12_REG 0X56
+#define HDMI_RX_SPD_DATA13_REG 0X57
+#define HDMI_RX_SPD_DATA14_REG 0X58
+#define HDMI_RX_SPD_DATA15_REG 0X59
+#define HDMI_RX_SPD_DATA16_REG 0X5A
+#define HDMI_RX_SPD_DATA17_REG 0X5B
+#define HDMI_RX_SPD_DATA18_REG 0X5C
+#define HDMI_RX_SPD_DATA19_REG 0X5D
+#define HDMI_RX_SPD_DATA1A_REG 0X5E
+
+#define HDMI_RX_ACP_HB0_REG 0X60
+#define HDMI_RX_ACP_HB1_REG 0X61
+#define HDMI_RX_ACP_HB2_REG 0X62
+#define HDMI_RX_ACP_DATA00_REG 0X63
+#define HDMI_RX_ACP_DATA01_REG 0X64
+#define HDMI_RX_ACP_DATA02_REG 0X65
+#define HDMI_RX_ACP_DATA03_REG 0X66
+#define HDMI_RX_ACP_DATA04_REG 0X67
+#define HDMI_RX_ACP_DATA05_REG 0X68
+#define HDMI_RX_ACP_DATA06_REG 0X69
+#define HDMI_RX_ACP_DATA07_REG 0X6A
+#define HDMI_RX_ACP_DATA08_REG 0X6B
+#define HDMI_RX_ACP_DATA09_REG 0X6C
+#define HDMI_RX_ACP_DATA0A_REG 0X6D
+#define HDMI_RX_ACP_DATA0B_REG 0X6E
+#define HDMI_RX_ACP_DATA0C_REG 0X6F
+#define HDMI_RX_ACP_DATA0D_REG 0X70
+#define HDMI_RX_ACP_DATA0E_REG 0X71
+#define HDMI_RX_ACP_DATA0F_REG 0X72
+#define HDMI_RX_ACP_DATA10_REG 0X73
+#define HDMI_RX_ACP_DATA11_REG 0X74
+#define HDMI_RX_ACP_DATA12_REG 0X75
+#define HDMI_RX_ACP_DATA13_REG 0X76
+#define HDMI_RX_ACP_DATA14_REG 0X77
+#define HDMI_RX_ACP_DATA15_REG 0X78
+#define HDMI_RX_ACP_DATA16_REG 0X79
+#define HDMI_RX_ACP_DATA17_REG 0X7A
+#define HDMI_RX_ACP_DATA18_REG 0X7B
+#define HDMI_RX_ACP_DATA19_REG 0X7C
+#define HDMI_RX_ACP_DATA1A_REG 0X7D
+#define HDMI_RX_ACP_DATA1B_REG 0X7E
+
+#define HDMI_RX_UNRECOGNIZED_PACKET_REG 0X80
+
+#define HDMI_RX_AVI_TYPE_REG 0XA0
+#define HDMI_RX_AVI_VER_REG 0XA1
+#define HDMI_RX_AVI_LEN_REG 0XA2
+#define HDMI_RX_AVI_CHKSUM_REG 0XA3
+#define HDMI_RX_AVI_DATA00_REG 0XA4
+#define HDMI_RX_AVI_DATA01_REG 0XA5
+#define HDMI_RX_AVI_DATA02_REG 0XA6
+#define HDMI_RX_AVI_DATA03_REG 0XA7
+#define HDMI_RX_AVI_DATA04_REG 0XA8
+#define HDMI_RX_AVI_DATA05_REG 0XA9
+#define HDMI_RX_AVI_DATA06_REG 0XAA
+#define HDMI_RX_AVI_DATA07_REG 0XAB
+#define HDMI_RX_AVI_DATA08_REG 0XAC
+#define HDMI_RX_AVI_DATA09_REG 0XAD
+#define HDMI_RX_AVI_DATA0A_REG 0XAE
+#define HDMI_RX_AVI_DATA0B_REG 0XAF
+#define HDMI_RX_AVI_DATA0C_REG 0XB0
+#define HDMI_RX_AVI_DATA0D_REG 0XB1
+#define HDMI_RX_AVI_DATA0E_REG 0XB2
+
+#define HDMI_RX_AUDIO_TYPE_REG 0XC0
+#define HDMI_RX_AUDIO_VER_REG 0XC1
+#define HDMI_RX_AUDIO_LEN_REG 0XC2
+#define HDMI_RX_AUDIO_CHKSUM_REG 0XC3
+#define HDMI_RX_AUDIO_DATA00_REG 0XC4
+#define HDMI_RX_AUDIO_DATA01_REG 0XC5
+#define HDMI_RX_AUDIO_DATA02_REG 0XC6
+#define HDMI_RX_AUDIO_DATA03_REG 0XC7
+#define HDMI_RX_AUDIO_DATA04_REG 0XC8
+#define HDMI_RX_AUDIO_DATA05_REG 0XC9
+#define HDMI_RX_AUDIO_DATA06_REG 0XCA
+#define HDMI_RX_AUDIO_DATA07_REG 0XCB
+#define HDMI_RX_AUDIO_DATA08_REG 0XCC
+#define HDMI_RX_AUDIO_DATA09_REG 0XCD
+#define HDMI_RX_AUDIO_DATA0A_REG 0XCE
+#define HDMI_RX_AUDIO_DATA0B_REG 0XCF
+#define HDMI_RX_AUDIO_DATA0C_REG 0XD0
+#define HDMI_RX_AUDIO_DATA0D_REG 0XD1
+#define HDMI_RX_AUDIO_DATA0E_REG 0XD2
+#define HDMI_RX_AUDIO_DATA0F_REG 0XD3
+#define HDMI_RX_AUDIO_DATA10_REG 0XD4
+#define HDMI_RX_AUDIO_DATA11_REG 0XD5
+#define HDMI_RX_AUDIO_DATA12_REG 0XD6
+#define HDMI_RX_AUDIO_DATA13_REG 0XD6
+#define HDMI_RX_AUDIO_DATA14_REG 0XD7
+#define HDMI_RX_AUDIO_DATA15_REG 0XD9
+#define HDMI_RX_AUDIO_DATA16_REG 0XDA
+#define HDMI_RX_AUDIO_DATA17_REG 0XDB
+#define HDMI_RX_AUDIO_DATA18_REG 0XDC
+#define HDMI_RX_AUDIO_DATA19_REG 0XDD
+
+#define HDMI_RX_MPEG_TYPE_REG 0XE0
+#define HDMI_RX_MPEG_VER_REG 0XE1
+#define HDMI_RX_MPEG_LEN_REG 0XE2
+#define HDMI_RX_MPEG_CHKSUM_REG 0XE3
+#define HDMI_RX_MPEG_DATA00_REG 0XE4
+#define HDMI_RX_MPEG_DATA01_REG 0XE5
+#define HDMI_RX_MPEG_DATA02_REG 0XE6
+#define HDMI_RX_MPEG_DATA03_REG 0XE7
+#define HDMI_RX_MPEG_DATA04_REG 0XE8
+#define HDMI_RX_MPEG_DATA05_REG 0XE9
+#define HDMI_RX_MPEG_DATA06_REG 0XEA
+#define HDMI_RX_MPEG_DATA07_REG 0XEB
+#define HDMI_RX_MPEG_DATA08_REG 0XEC
+#define HDMI_RX_MPEG_DATA09_REG 0XED
+#define HDMI_RX_MPEG_DATA0A_REG 0XEF
+#define HDMI_RX_MPEG_DATA0B_REG 0XF0
+#define HDMI_RX_MPEG_DATA0C_REG 0XF1
+#define HDMI_RX_MPEG_DATA0D_REG 0XF2
+#define HDMI_RX_MPEG_DATA0E_REG 0XF3
+#define HDMI_RX_MPEG_DATA0F_REG 0XF4
+#define HDMI_RX_MPEG_DATA10_REG 0XF5
+#define HDMI_RX_MPEG_DATA11_REG 0XF6
+#define HDMI_RX_MPEG_DATA12_REG 0XF7
+#define HDMI_RX_MPEG_DATA13_REG 0XF8
+#define HDMI_RX_MPEG_DATA14_REG 0XF9
+#define HDMI_RX_MPEG_DATA15_REG 0XFA
+#define HDMI_RX_MPEG_DATA16_REG 0XFB
+#define HDMI_RX_MPEG_DATA17_REG 0XFC
+#define HDMI_RX_MPEG_DATA18_REG 0XFD
+#define HDMI_RX_MPEG_DATA19_REG 0XFE
+
+#define HDMI_RX_SPD_INFO_CTRL 0X5F
+#define HDMI_RX_ACP_INFO_CTRL 0X7F
+#define HDMI_RX_GENERAL_CTRL 0X9F
+#define HDMI_RX_MPEG_VS_CTRL 0XDF
+#define HDMI_RX_MPEG_VS_INFO_CTRL 0XFF
+
+
+/***************************************************************/
+/* DEV_ADDR = 0x70, Displayport mode and HDCP registers*/
+#define SP_TX_HDCP_STATUS 0x00
+#define SP_TX_HDCP_AUTH_PASS 0x02
+
+#define SP_TX_HDCP_CTRL0_REG 0x01
+#define SP_TX_HDCP_CTRL0_STORE_AN 0x80
+#define SP_TX_HDCP_CTRL0_RX_REPEATER 0x40
+#define SP_TX_HDCP_CTRL0_RE_AUTH 0x20
+#define SP_TX_HDCP_CTRL0_SW_AUTH_OK 0x10
+#define SP_TX_HDCP_CTRL0_HARD_AUTH_EN 0x08
+#define SP_TX_HDCP_CTRL0_ENC_EN 0x04
+#define SP_TX_HDCP_CTRL0_BKSV_SRM_PASS 0x02
+#define SP_TX_HDCP_CTRL0_KSVLIST_VLD 0x01
+
+
+#define SP_TX_HDCP_CTRL1_REG 0x02
+#define SP_TX_HDCP_CTRL1_AINFO_EN 0x04
+#define SP_TX_HDCP_CTRL1_RCV_11_EN 0x02
+#define SP_TX_HDCP_CTRL1_HDCP_11_EN 0x01
+
+#define SP_TX_HDCP_LINK_CHK_FRAME_NUM 0x03
+#define SP_TX_HDCP_CTRL2_REG 0x04
+
+#define SP_TX_HDCP_AKSV0 0x05
+#define SP_TX_HDCP_AKSV1 0x06
+#define SP_TX_HDCP_AKSV2 0x07
+#define SP_TX_HDCP_AKSV3 0x08
+#define SP_TX_HDCP_AKSV4 0x09
+
+
+#define SP_TX_HDCP_AN0 0x0A
+#define SP_TX_HDCP_AN1 0x0B
+#define SP_TX_HDCP_AN2 0x0C
+#define SP_TX_HDCP_AN3 0x0D
+#define SP_TX_HDCP_AN4 0x0E
+#define SP_TX_HDCP_AN5 0x0F
+#define SP_TX_HDCP_AN6 0x10
+#define SP_TX_HDCP_AN7 0x11
+
+#define SP_TX_HDCP_BKSV0 0x12
+#define SP_TX_HDCP_BKSV1 0x13
+#define SP_TX_HDCP_BKSV2 0x14
+#define SP_TX_HDCP_BKSV3 0x15
+#define SP_TX_HDCP_BKSV4 0x16
+
+#define SP_TX_HDCP_R0_L 0x17
+#define SP_TX_HDCP_R0_H 0x18
+
+#define M_VID_0 0xC0
+#define M_VID_1 0xC1
+#define M_VID_2 0xC2
+#define N_VID_0 0xC3
+#define N_VID_1 0xC4
+#define N_VID_2 0xC5
+
+#define SP_TX_SYS_CTRL1_REG 0x80
+#define SP_TX_SYS_CTRL1_CHIP_AUTH_RESET 0x80
+#define SP_TX_SYS_CTRL1_PD_BYPASS_CHIP_AUTH 0x40
+#define SP_TX_SYS_CTRL1_DET_STA 0x04
+#define SP_TX_SYS_CTRL1_FORCE_DET 0x02
+#define SP_TX_SYS_CTRL1_DET_CTRL 0x01
+
+#define SP_TX_SYS_CTRL2_REG 0x81
+#define SP_TX_SYS_CTRL2_CHA_STA 0x04
+#define SP_TX_SYS_CTRL2_FORCE_CHA 0x02
+#define SP_TX_SYS_CTRL2_CHA_CTRL 0x01
+
+#define SP_TX_SYS_CTRL3_REG 0x82
+#define SP_TX_SYS_CTRL3_HPD_STATUS 0x40
+#define SP_TX_SYS_CTRL3_F_HPD 0x20
+#define SP_TX_SYS_CTRL3_HPD_CTRL 0x10
+#define SP_TX_SYS_CTRL3_STRM_VALID 0x04
+#define SP_TX_SYS_CTRL3_F_VALID 0x02
+#define SP_TX_SYS_CTRL3_VALID_CTRL 0x01
+
+#define SP_TX_SYS_CTRL4_REG 0x83
+#define SP_TX_SYS_CTRL4_ENHANCED 0x08
+
+#define SP_TX_VID_CTRL 0x84
+
+#define SP_TX_AUD_CTRL 0x87
+#define SP_TX_AUD_CTRL_AUD_EN 0x01
+
+
+#define SP_TX_PKT_EN_REG 0x90
+#define SP_TX_PKT_AUD_UP 0x80
+#define SP_TX_PKT_AVI_UD 0x40
+#define SP_TX_PKT_MPEG_UD 0x20
+#define SP_TX_PKT_SPD_UD 0x10
+#define SP_TX_PKT_AUD_EN 0x08
+#define SP_TX_PKT_AVI_EN 0x04
+#define SP_TX_PKT_MPEG_EN 0x02
+#define SP_TX_PKT_SPD_EN 0x01
+
+
+#define SP_TX_HDCP_CTRL 0x92
+
+#define SP_TX_LINK_BW_SET_REG 0xA0
+
+#define SP_TX_TRAINING_PTN_SET_REG 0xA2
+#define SP_TX_SCRAMBLE_DISABLE 0x20
+
+#define SP_TX_TRAINING_LANE0_SET_REG 0xA3
+#define SP_TX_TRAINING_LANE0_SET_MAX_PRE_REACH 0x20
+#define SP_TX_TRAINING_LANE0_SET_MAX_DRIVE_REACH 0x04
+
+#define SSC_CTRL_REG1 0xA7
+#define SPREAD_AMP 0x10
+#define MODULATION_FREQ 0x01
+
+
+#define SP_TX_LINK_TRAINING_CTRL_REG 0xA8
+#define SP_TX_LINK_TRAINING_CTRL_EN 0x01
+
+
+#define SP_TX_DEBUG_REG1 0xB0
+#define SP_TX_DEBUG_HPD_POLLING_DET 0x40
+#define SP_TX_DEBUG_HPD_POLLING_EN 0x20
+#define SP_TX_DEBUG_PLL_LOCK 0x10
+
+
+#define SP_TX_DP_POLLING_PERIOD 0xB3
+
+
+#define SP_TX_DP_POLLING_CTRL_REG 0xB4
+#define SP_TX_AUTO_POLLING_DISABLE 0x01
+
+
+
+#define SP_TX_LINK_DEBUG_REG 0xB8
+#define SP_TX_LINK_DEBUG_INSERT_ER 0x02
+#define SP_TX_LINK_DEBUG_PRBS31_EN 0x01
+
+#define SP_TX_SINK_COUNT_REG 0xB9
+
+#define SP_TX_LINK_STATUS_REG1 0xBB
+
+#define SP_TX_SINK_STATUS_REG 0xBE
+#define SP_TX_SINK_STATUS_SINK_STATUS_1 0x02
+#define SP_TX_SINK_STATUS_SINK_STATUS_0 0x01
+
+
+#define SP_TX_PLL_CTRL_REG 0xC7
+#define SP_TX_PLL_CTRL_PLL_PD 0x80
+#define SP_TX_PLL_CTRL_PLL_RESET 0x40
+
+
+#define SP_TX_ANALOG_POWER_DOWN_REG 0xC8
+#define SP_TX_ANALOG_POWER_DOWN_MACRO_PD 0x20
+#define SP_TX_ANALOG_POWER_DOWN_AUX_PD 0x10
+#define SP_TX_ANALOG_POWER_DOWN_CH0_PD 0x01
+
+#define SP_TX_ANALOG_TEST_REG 0xC9
+
+#define SP_TX_GNS_CTRL_REG 0xCD
+#define SP_EQ_LOOP_CNT 0x40
+#define SP_TX_VIDEO_MAP_CTRL 0x02
+#define SP_TX_RS_CTRL 0x01
+
+#define SP_TX_DOWN_SPREADING_CTRL1 0xD0
+#define SP_TX_DOWN_SPREADING_CTRL2 0xD1
+#define SP_TX_DOWN_SPREADING_CTRL3 0xD2
+#define SP_TX_SSC_D_CTRL 0x40
+#define SP_TX_FS_CTRL_TH_CTRL 0x20
+
+#define SP_TX_M_CALCU_CTRL 0xD9
+#define M_GEN_CLK_SEL 0x01
+
+
+#define SP_TX_EXTRA_ADDR_REG 0xCE
+#define SP_TX_I2C_STRETCH_CTRL_REG 0xDB
+#define SP_TX_AUX_STATUS 0xE0
+#define SP_TX_DEFER_CTRL_REG 0xE2
+#define SP_TXL_DEFER_CTRL_EN 0x80
+
+#define SP_TX_BUF_DATA_COUNT_REG 0xE4
+#define SP_TX_AUX_CTRL_REG 0xE5
+#define SP_TX_AUX_ADDR_7_0_REG 0xE6
+#define SP_TX_AUX_ADDR_15_8_REG 0xE7
+#define SP_TX_AUX_ADDR_19_16_REG 0xE8
+
+#define SP_TX_AUX_CTRL_REG2 0xE9
+#define SP_TX_ADDR_ONLY_BIT 0x02
+
+
+#define SP_TX_3D_VSC_CTRL 0xEA
+#define SP_TX_VSC_DBYTE1 0xEB
+
+#define SP_TX_BUF_DATA_0_REG 0xf0
+#define SP_TX_BUF_DATA_1_REG 0xf1
+#define SP_TX_BUF_DATA_2_REG 0xf2
+#define SP_TX_BUF_DATA_3_REG 0xf3
+#define SP_TX_BUF_DATA_4_REG 0xf4
+#define SP_TX_BUF_DATA_5_REG 0xf5
+#define SP_TX_BUF_DATA_6_REG 0xf6
+#define SP_TX_BUF_DATA_7_REG 0xf7
+#define SP_TX_BUF_DATA_8_REG 0xf8
+#define SP_TX_BUF_DATA_9_REG 0xf9
+#define SP_TX_BUF_DATA_10_REG 0xfa
+#define SP_TX_BUF_DATA_11_REG 0xfb
+#define SP_TX_BUF_DATA_12_REG 0xfc
+#define SP_TX_BUF_DATA_13_REG 0xfd
+#define SP_TX_BUF_DATA_14_REG 0xfe
+#define SP_TX_BUF_DATA_15_REG 0xff
+
+/*End for Address 0x70 */
+
+/***************************************************************/
+/* DEV_ADDR = 0x72 , System control registers*/
+#define SP_TX_VND_IDL_REG 0x00
+#define SP_TX_VND_IDH_REG 0x01
+#define SP_TX_DEV_IDL_REG 0x02
+#define SP_TX_DEV_IDH_REG 0x03
+#define SP_TX_DEV_REV_REG 0x04
+
+#define SP_POWERD_CTRL_REG 0x05
+#define SP_POWERD_REGISTER_REG 0x80
+#define SP_POWERD_HDCP_REG 0x20
+#define SP_POWERD_AUDIO_REG 0x10
+#define SP_POWERD_VIDEO_REG 0x08
+#define SP_POWERD_LINK_REG 0x04
+#define SP_POWERD_TOTAL_REG 0x02
+
+
+#define SP_TX_RST_CTRL_REG 0x06
+#define SP_TX_RST_MISC_REG 0x80
+#define SP_TX_RST_VIDCAP_REG 0x40
+#define SP_TX_RST_VIDFIF_REG 0x20
+#define SP_TX_RST_AUDFIF_REG 0x10
+#define SP_TX_RST_AUDCAP_REG 0x08
+#define SP_TX_RST_HDCP_REG 0x04
+#define SP_TX_RST_SW_RST 0x02
+#define SP_TX_RST_HW_RST 0x01
+
+#define SP_TX_RST_CTRL2_REG 0x07
+#define SP_TX_RST_SSC 0x80
+#define SP_TX_AC_MODE 0x40
+#define SP_TX_AUX_RST 0x04
+#define SP_TX_SERDES_FIFO_RST 0x02
+#define SP_TX_I2C_REG_RST 0x01
+
+
+#define SP_TX_VID_CTRL1_REG 0x08
+#define SP_TX_VID_CTRL1_VID_EN 0x80
+#define SP_TX_VID_CTRL1_VID_MUTE 0x40
+#define SP_TX_VID_CTRL1_DE_GEN 0x20
+#define SP_TX_VID_CTRL1_DEMUX 0x10
+#define SP_TX_VID_CTRL1_IN_BIT 0x04
+#define SP_TX_VID_CTRL1_DDRCTRL 0x02
+#define SP_TX_VID_CTRL1_EDGE 0x01
+
+#define SP_TX_VID_CTRL2_REG 0x09
+#define SP_TX_VID_CTRL1_YCBIT_SEL 0x04
+
+#define SP_TX_VID_CTRL3_REG 0x0A
+#define SP_TX_VID_CTRL3_HPD_OUT 0x40
+
+#define SP_TX_VID_CTRL4_REG 0x0B
+#define SP_TX_VID_CTRL4_E_SYNC_EN 0x80
+#define SP_TX_VID_CTRL4_EX_E_SYNC 0x40
+#define SP_TX_VID_CTRL4_BIST 0x08
+#define SP_TX_VID_CTRL4_BIST_WIDTH 0x04
+
+#define SP_TX_VID_CTRL5_REG 0x0C
+
+#define SP_TX_VID_CTRL6_REG 0x0D
+#define SP_TX_VID_UPSAMPLE 0x02
+
+#define SP_TX_VID_CTRL7_REG 0x0E
+#define SP_TX_VID_CTRL8_REG 0x0F
+#define SP_TX_VID_CTRL9_REG 0x10
+
+#define SP_TX_VID_CTRL10_REG 0x11
+#define SP_TX_VID_CTRL10_INV_F 0x08
+#define SP_TX_VID_CTRL10_I_SCAN 0x04
+#define SP_TX_VID_CTRL10_VSYNC_POL 0x02
+#define SP_TX_VID_CTRL10_HSYNC_POL 0x01
+
+#define SP_TX_TOTAL_LINEL_REG 0x12
+#define SP_TX_TOTAL_LINEH_REG 0x13
+#define SP_TX_ACT_LINEL_REG 0x14
+#define SP_TX_ACT_LINEH_REG 0x15
+#define SP_TX_VF_PORCH_REG 0x16
+#define SP_TX_VSYNC_CFG_REG 0x17
+#define SP_TX_VB_PORCH_REG 0x18
+#define SP_TX_TOTAL_PIXELL_REG 0x19
+#define SP_TX_TOTAL_PIXELH_REG 0x1A
+#define SP_TX_ACT_PIXELL_REG 0x1B
+#define SP_TX_ACT_PIXELH_REG 0x1C
+#define SP_TX_HF_PORCHL_REG 0x1D
+#define SP_TX_HF_PORCHH_REG 0x1E
+#define SP_TX_HSYNC_CFGL_REG 0x1F
+#define SP_TX_HSYNC_CFGH_REG 0x20
+#define SP_TX_HB_PORCHL_REG 0x21
+#define SP_TX_HB_PORCHH_REG 0x22
+
+#define SP_TX_VID_STATUS 0x23
+
+#define SP_TX_TOTAL_LINE_STA_L 0x24
+#define SP_TX_TOTAL_LINE_STA_H 0x25
+#define SP_TX_ACT_LINE_STA_L 0x26
+#define SP_TX_ACT_LINE_STA_H 0x27
+#define SP_TX_V_F_PORCH_STA 0x28
+#define SP_TX_V_SYNC_STA 0x29
+#define SP_TX_V_B_PORCH_STA 0x2A
+#define SP_TX_TOTAL_PIXEL_STA_L 0x2B
+#define SP_TX_TOTAL_PIXEL_STA_H 0x2C
+#define SP_TX_ACT_PIXEL_STA_L 0x2D
+#define SP_TX_ACT_PIXEL_STA_H 0x2E
+#define SP_TX_H_F_PORCH_STA_L 0x2F
+#define SP_TX_H_F_PORCH_STA_H 0x30
+#define SP_TX_H_SYNC_STA_L 0x31
+#define SP_TX_H_SYNC_STA_H 0x32
+#define SP_TX_H_B_PORCH_STA_L 0x33
+#define SP_TX_H_B_PORCH_STA_H 0x34
+
+#define SP_TX_Video_Interface_BIST 0x35
+
+#define SPDIF_AUDIO_CTRL0 0x36
+#define SPDIF_AUDIO_CTRL0_SPDIF_IN 0x80
+
+#define SPDIF_AUDIO_STATUS0 0x38
+#define SPDIF_AUDIO_STATUS0_CLK_DET 0x80
+#define SPDIF_AUDIO_STATUS0_AUD_DET 0x01
+
+#define SPDIF_AUDIO_STATUS1 0x39
+
+#define AUDIO_BIST_CTRL 0x3c
+#define AUDIO_BIST_EN 0x01
+
+#define SP_TX_VIDEO_BIT_CTRL_0_REG 0x40
+#define SP_TX_VIDEO_BIT_CTRL_1_REG 0x41
+#define SP_TX_VIDEO_BIT_CTRL_2_REG 0x42
+#define SP_TX_VIDEO_BIT_CTRL_3_REG 0x43
+#define SP_TX_VIDEO_BIT_CTRL_4_REG 0x44
+#define SP_TX_VIDEO_BIT_CTRL_5_REG 0x45
+#define SP_TX_VIDEO_BIT_CTRL_6_REG 0x46
+#define SP_TX_VIDEO_BIT_CTRL_7_REG 0x47
+#define SP_TX_VIDEO_BIT_CTRL_8_REG 0x48
+#define SP_TX_VIDEO_BIT_CTRL_9_REG 0x49
+#define SP_TX_VIDEO_BIT_CTRL_10_REG 0x4a
+#define SP_TX_VIDEO_BIT_CTRL_11_REG 0x4b
+#define SP_TX_VIDEO_BIT_CTRL_12_REG 0x4c
+#define SP_TX_VIDEO_BIT_CTRL_13_REG 0x4d
+#define SP_TX_VIDEO_BIT_CTRL_14_REG 0x4e
+#define SP_TX_VIDEO_BIT_CTRL_15_REG 0x4f
+#define SP_TX_VIDEO_BIT_CTRL_16_REG 0x50
+#define SP_TX_VIDEO_BIT_CTRL_17_REG 0x51
+#define SP_TX_VIDEO_BIT_CTRL_18_REG 0x52
+#define SP_TX_VIDEO_BIT_CTRL_19_REG 0x53
+#define SP_TX_VIDEO_BIT_CTRL_20_REG 0x54
+#define SP_TX_VIDEO_BIT_CTRL_21_REG 0x55
+#define SP_TX_VIDEO_BIT_CTRL_22_REG 0x56
+#define SP_TX_VIDEO_BIT_CTRL_23_REG 0x57
+#define SP_TX_VIDEO_BIT_CTRL_24_REG 0x58
+#define SP_TX_VIDEO_BIT_CTRL_25_REG 0x59
+#define SP_TX_VIDEO_BIT_CTRL_26_REG 0x5a
+#define SP_TX_VIDEO_BIT_CTRL_27_REG 0x5b
+#define SP_TX_VIDEO_BIT_CTRL_28_REG 0x5c
+#define SP_TX_VIDEO_BIT_CTRL_29_REG 0x5d
+#define SP_TX_VIDEO_BIT_CTRL_30_REG 0x5e
+#define SP_TX_VIDEO_BIT_CTRL_31_REG 0x5f
+#define SP_TX_VIDEO_BIT_CTRL_32_REG 0x60
+#define SP_TX_VIDEO_BIT_CTRL_33_REG 0x61
+#define SP_TX_VIDEO_BIT_CTRL_34_REG 0x62
+#define SP_TX_VIDEO_BIT_CTRL_35_REG 0x63
+#define SP_TX_VIDEO_BIT_CTRL_36_REG 0x64
+#define SP_TX_VIDEO_BIT_CTRL_37_REG 0x65
+#define SP_TX_VIDEO_BIT_CTRL_38_REG 0x66
+#define SP_TX_VIDEO_BIT_CTRL_39_REG 0x67
+#define SP_TX_VIDEO_BIT_CTRL_40_REG 0x68
+#define SP_TX_VIDEO_BIT_CTRL_41_REG 0x69
+#define SP_TX_VIDEO_BIT_CTRL_42_REG 0x6a
+#define SP_TX_VIDEO_BIT_CTRL_43_REG 0x6b
+#define SP_TX_VIDEO_BIT_CTRL_44_REG 0x6c
+#define SP_TX_VIDEO_BIT_CTRL_45_REG 0x6d
+#define SP_TX_VIDEO_BIT_CTRL_46_REG 0x6e
+#define SP_TX_VIDEO_BIT_CTRL_47_REG 0x6f
+
+#define SP_TX_AVI_TYPE 0x70
+#define SP_TX_AVI_VER 0x71
+#define SP_TX_AVI_LEN 0x72
+#define SP_TX_AVI_DB0 0x73
+#define SP_TX_AVI_DB1 0x74
+#define SP_TX_AVI_DB2 0x75
+#define SP_TX_AVI_DB3 0x76
+#define SP_TX_AVI_DB4 0x77
+#define SP_TX_AVI_DB5 0x78
+#define SP_TX_AVI_DB6 0x79
+#define SP_TX_AVI_DB7 0x7A
+#define SP_TX_AVI_DB8 0x7B
+#define SP_TX_AVI_DB9 0x7C
+#define SP_TX_AVI_DB10 0x7D
+#define SP_TX_AVI_DB11 0x7E
+#define SP_TX_AVI_DB12 0x7F
+#define SP_TX_AVI_DB13 0x80
+#define SP_TX_AVI_DB14 0x81
+#define SP_TX_AVI_DB15 0x82
+
+#define SP_TX_AUD_TYPE 0x83
+#define SP_TX_AUD_VER 0x84
+#define SP_TX_AUD_LEN 0x85
+#define SP_TX_AUD_DB0 0x86
+#define SP_TX_AUD_DB1 0x87
+#define SP_TX_AUD_DB2 0x88
+#define SP_TX_AUD_DB3 0x89
+#define SP_TX_AUD_DB4 0x8A
+#define SP_TX_AUD_DB5 0x8B
+#define SP_TX_AUD_DB6 0x8C
+#define SP_TX_AUD_DB7 0x8D
+#define SP_TX_AUD_DB8 0x8E
+#define SP_TX_AUD_DB9 0x8F
+#define SP_TX_AUD_DB10 0x90
+
+#define SP_TX_SPD_TYPE 0x91
+#define SP_TX_SPD_VER 0x92
+#define SP_TX_SPD_LEN 0x93
+#define SP_TX_SPD_DATA0 0x94
+#define SP_TX_SPD_DATA1 0x95
+#define SP_TX_SPD_DATA2 0x96
+#define SP_TX_SPD_DATA3 0x97
+#define SP_TX_SPD_DATA4 0x98
+#define SP_TX_SPD_DATA5 0x99
+#define SP_TX_SPD_DATA6 0x9A
+#define SP_TX_SPD_DATA7 0x9B
+#define SP_TX_SPD_DATA8 0x9C
+#define SP_TX_SPD_DATA9 0x9D
+#define SP_TX_SPD_DATA10 0x9E
+#define SP_TX_SPD_DATA11 0x9F
+#define SP_TX_SPD_DATA12 0xA0
+#define SP_TX_SPD_DATA13 0xA1
+#define SP_TX_SPD_DATA14 0xA2
+#define SP_TX_SPD_DATA15 0xA3
+#define SP_TX_SPD_DATA16 0xA4
+#define SP_TX_SPD_DATA17 0xA5
+#define SP_TX_SPD_DATA18 0xA6
+#define SP_TX_SPD_DATA19 0xA7
+#define SP_TX_SPD_DATA20 0xA8
+#define SP_TX_SPD_DATA21 0xA9
+#define SP_TX_SPD_DATA22 0xAA
+#define SP_TX_SPD_DATA23 0xAB
+#define SP_TX_SPD_DATA24 0xAC
+#define SP_TX_SPD_DATA25 0xAD
+#define SP_TX_SPD_DATA26 0xAE
+#define SP_TX_SPD_DATA27 0xAF
+
+#define SP_TX_MPEG_TYPE 0xB0
+#define SP_TX_MPEG_VER 0xB1
+#define SP_TX_MPEG_LEN 0xB2
+#define SP_TX_MPEG_DATA0 0xB3
+#define SP_TX_MPEG_DATA1 0xB4
+#define SP_TX_MPEG_DATA2 0xB5
+#define SP_TX_MPEG_DATA3 0xB6
+#define SP_TX_MPEG_DATA4 0xB7
+#define SP_TX_MPEG_DATA5 0xB8
+#define SP_TX_MPEG_DATA6 0xB9
+#define SP_TX_MPEG_DATA7 0xBA
+#define SP_TX_MPEG_DATA8 0xBB
+#define SP_TX_MPEG_DATA9 0xBC
+#define SP_TX_MPEG_DATA10 0xBD
+#define SP_TX_MPEG_DATA11 0xBE
+#define SP_TX_MPEG_DATA12 0xBF
+#define SP_TX_MPEG_DATA13 0xC0
+#define SP_TX_MPEG_DATA14 0xC1
+#define SP_TX_MPEG_DATA15 0xC2
+#define SP_TX_MPEG_DATA16 0xC3
+#define SP_TX_MPEG_DATA17 0xC4
+#define SP_TX_MPEG_DATA18 0xC5
+#define SP_TX_MPEG_DATA19 0xC6
+#define SP_TX_MPEG_DATA20 0xC7
+#define SP_TX_MPEG_DATA21 0xC8
+#define SP_TX_MPEG_DATA22 0xC9
+#define SP_TX_MPEG_DATA23 0xCA
+#define SP_TX_MPEG_DATA24 0xCB
+#define SP_TX_MPEG_DATA25 0xCC
+#define SP_TX_MPEG_DATA26 0xCD
+#define SP_TX_MPEG_DATA27 0xCE
+
+#define SP_TX_AUD_CH_NUM_REG5 0xD5
+
+#define SP_TX_ANALOG_DEBUG_REG1 0xDC
+#define SP_TX_ANALOG_SEL_BG 0x40
+#define SP_TX_ANALOG_SWING_A_30PER 0x08
+
+#define SP_TX_ANALOG_DEBUG_REG2 0xDD
+#define SP_TX_ANALOG_24M_SEL 0x08
+
+
+#define SP_TX_ANALOG_DEBUG_REG3 0xDE
+
+#define SP_TX_PLL_FILTER_CTRL11 0xDF
+#define SP_TX_PD_RING_OSC 0x40
+#define SP_TX_V33_SWITCH_ON 0x02
+
+#define SP_TX_PLL_FILTER_CTRL2 0xE0
+#define SP_TX_PLL_FILTER_CTRL3 0xE1
+#define SP_TX_PLL_FILTER_CTRL4 0xE2
+#define SP_TX_PLL_FILTER_CTRL5 0xE3
+#define SP_TX_PLL_FILTER_CTRL6 0xE4
+
+#define SP_TX_ANALOG_CTRL 0xE5
+
+#define SP_TX_I2S_CTRL 0xE6
+#define SP_TX_I2S_FMT 0xD5
+#define SP_TX_I2S_CH_Status1 0xD0
+#define SP_TX_I2S_CH_Status2 0xD1
+#define SP_TX_I2S_CH_Status3 0xD2
+#define SP_TX_I2S_CH_Status4 0xD3
+#define SP_TX_I2S_CH_Status5 0xD4
+
+#define SP_COMMON_INT_STATUS1 0xF1
+#define SP_COMMON_INT1_PLL_LOCK_CHG 0x40
+#define SP_COMMON_INT1_VIDEO_FORMAT_CHG 0x08
+#define SP_COMMON_INT1_AUDIO_CLK_CHG 0x04
+#define SP_COMMON_INT1_VIDEO_CLOCK_CHG 0x02
+
+
+#define SP_COMMON_INT_STATUS2 0xF2
+#define SP_COMMON_INT2_AUTHCHG 0x02
+#define SP_COMMON_INT2_AUTHDONE 0x01
+
+#define SP_COMMON_INT_STATUS3 0xF3
+#define SP_COMMON_INT3_AFIFO_UNDER 0x80
+#define SP_COMMON_INT3_AFIFO_OVER 0x40
+
+#define SP_COMMON_INT_STATUS4 0xF4
+#define SP_COMMON_INT4_PLUG 0x01
+#define SP_COMMON_INT4_ESYNC_ERR 0x10
+#define SP_COMMON_INT4_HPDLOST 0x02
+#define SP_COMMON_INT4_HPD_CHANGE 0x04
+
+
+#define SP_TX_INT_STATUS1 0xF7
+#define SP_TX_INT_DPCD_IRQ_REQUEST 0x80
+#define SP_TX_INT_STATUS1_HPD 0x40
+#define SP_TX_INT_STATUS1_TRAINING_Finish 0x20
+#define SP_TX_INT_STATUS1_POLLING_ERR 0x10
+#define SP_TX_INT_STATUS1_LINK_CHANGE 0x04
+
+#define SP_TX_INT_SINK_CHG 0x08
+
+#define SP_COMMON_INT_MASK1 0xF8
+#define SP_COMMON_INT_MASK2 0xF9
+#define SP_COMMON_INT_MASK3 0xFA
+#define SP_COMMON_INT_MASK4 0xFB
+#define SP_INT_MASK 0xFE
+#define SP_TX_INT_CTRL_REG 0xFF
+/*End for dev_addr 0x72 or 0x76*/
+
+/***************************************************************/
+/* DEV_ADDR = 0x7a , control registers*/
+
+#define SP_TX_LT_CTRL_REG0 0x30
+#define SP_TX_LT_CTRL_REG1 0x31
+#define SP_TX_LT_CTRL_REG2 0x34
+#define SP_TX_LT_CTRL_REG3 0x35
+#define SP_TX_LT_CTRL_REG4 0x36
+#define SP_TX_LT_CTRL_REG5 0x37
+#define SP_TX_LT_CTRL_REG6 0x38
+#define SP_TX_LT_CTRL_REG7 0x39
+#define SP_TX_LT_CTRL_REG8 0x3A
+#define SP_TX_LT_CTRL_REG9 0x3B
+#define SP_TX_LT_CTRL_REG10 0x40
+#define SP_TX_LT_CTRL_REG11 0x41
+#define SP_TX_LT_CTRL_REG12 0x44
+#define SP_TX_LT_CTRL_REG13 0x45
+#define SP_TX_LT_CTRL_REG14 0x46
+#define SP_TX_LT_CTRL_REG15 0x47
+#define SP_TX_LT_CTRL_REG16 0x48
+#define SP_TX_LT_CTRL_REG17 0x49
+#define SP_TX_LT_CTRL_REG18 0x4A
+#define SP_TX_LT_CTRL_REG19 0x4B
+
+#define SP_TX_AUD_INTERFACE_CTRL0 0x5f
+#define SP_TX_AUD_INTERFACE_CTRL2 0x60
+#define SP_TX_AUD_INTERFACE_CTRL3 0x62
+#define SP_TX_AUD_INTERFACE_CTRL4 0x67
+#define SP_TX_AUD_INTERFACE_CTRL5 0x68
+#define SP_TX_AUD_INTERFACE_CTRL6 0x69
+#define SP_TX_AUD_INTERFACE_CTRL7 0x6A
+#define SP_TX_AUD_INTERFACE_CTRL8 0x6B
+
+#define SP_TX_M_AUD_ADJUST_REG0 0x6C
+#define SP_TX_M_AUD_ADJUST_REG1 0x6D
+
+
+
+/***************************************************************/
+
+/*DPCD regs*/
+#define DPCD_DPCD_REV 0x00
+#define DPCD_MAX_LINK_RATE 0x01
+#define DPCD_MAX_LANE_COUNT 0x02
+#define DPCD_MAX_DOWNSPREAD 0x03
+#define DPCD_NORP 0x04
+#define DPCD_DOWNSTREAMPORT_PRESENT 0x05
+
+#define DPCD_RECEIVE_PORT0_CAP_0 0x08
+#define DPCD_RECEIVE_PORT0_CAP_1 0x09
+#define DPCD_RECEIVE_PORT0_CAP_2 0x0a
+#define DPCD_RECEIVE_PORT0_CAP_3 0x0b
+
+#define DPCD_LINK_BW_SET 0x00
+#define DPCD_LANE_COUNT_SET 0x01
+#define DPCD_TRAINING_PATTERN_SET 0x02
+#define DPCD_TRAINNIG_LANE0_SET 0x03
+#define DPCD_TRAINNIG_LANE1_SET 0x04
+#define DPCD_TRAINNIG_LANE2_SET 0x05
+#define DPCD_TRAINNIG_LANE3_SET 0x06
+#define DPCD_DOWNSPREAD_CTRL 0x07
+
+#define DPCD_SINK_COUNT 0x00
+#define DPCD_DEVICE_SERVICE_IRQ_VECTOR 0x01
+#define DPCD_LANE0_1_STATUS 0x02
+#define DPCD_LANE2_3_STATUS 0x03
+#define DPCD_LANE_ALIGN_STATUS_UPDATED 0x04
+#define DPCD_SINK_STATUS 0x05
+#define DPCD_ADJUST_REQUEST_LANE0_1 0x06
+#define DPCD_ADJUST_REQUEST_LANE2_3 0x07
+#define DPCD_TRAINING_SCORE_LANE0 0x08
+#define DPCD_TRAINING_SCORE_LANE1 0x09
+#define DPCD_TRAINING_SCORE_LANE2 0x0a
+#define DPCD_TRAINING_SCORE_LANE3 0x0b
+
+#define DPCD_TEST_REQUEST 0x18
+#define DPCD_TEST_LINK_RATE 0x19
+
+#define DPCD_TEST_LANE_COUNT 0x20
+
+#define DPCD_TEST_Response 0x60
+#define TEST_ACK 0x01
+#define DPCD_TEST_EDID_Checksum_Write 0x04
+
+#define DPCD_TEST_EDID_Checksum 0x61
+
+
+#define DPCD_SPECIFIC_INTERRUPT_1 0x10
+#define DPCD_USER_COMM1 0x22
+
+#define DPCD_SPECIFIC_INTERRUPT_2 0x11
+
+#endif