From f02f265142eb627ef2e2b8f826b2801a0c549e0d Mon Sep 17 00:00:00 2001 From: yzq Date: Sat, 26 Jan 2013 15:54:28 +0800 Subject: [PATCH] it66121 hdmi support --- arch/arm/mach-rk30/board-rk3066b-sdk.c | 8 + drivers/video/rockchip/hdmi/chips/Kconfig | 9 + drivers/video/rockchip/hdmi/chips/Makefile | 1 + .../rockchip/hdmi/chips/cat66121/Kconfig | 1 + .../rockchip/hdmi/chips/cat66121/Makefile | 7 + .../hdmi/chips/cat66121/cat66121_hdmi.c | 340 +++ .../hdmi/chips/cat66121/cat66121_hdmi.h | 34 + .../hdmi/chips/cat66121/cat66121_hdmi_hw.c | 236 ++ .../hdmi/chips/cat66121/cat66121_hdmi_hw.h | 260 ++ .../hdmi/chips/cat66121/cat66121_sys.c | 217 ++ .../hdmi/chips/cat66121/cat66121_sys.h | 164 ++ .../rockchip/hdmi/chips/cat66121/config.h | 138 + .../video/rockchip/hdmi/chips/cat66121/csc.c | 83 + .../rockchip/hdmi/chips/cat66121/debug.h | 106 + .../rockchip/hdmi/chips/cat66121/hdmitx.h | 58 + .../rockchip/hdmi/chips/cat66121/hdmitx_drv.c | 2594 +++++++++++++++++ .../rockchip/hdmi/chips/cat66121/hdmitx_drv.h | 746 +++++ .../hdmi/chips/cat66121/hdmitx_hdcp.c | 1021 +++++++ .../hdmi/chips/cat66121/hdmitx_hdcp.h | 87 + .../hdmi/chips/cat66121/hdmitx_input.c | 190 ++ .../hdmi/chips/cat66121/hdmitx_input.h | 26 + .../rockchip/hdmi/chips/cat66121/hdmitx_sys.c | 1371 +++++++++ .../rockchip/hdmi/chips/cat66121/hdmitx_sys.h | 15 + .../video/rockchip/hdmi/chips/cat66121/sha1.c | 152 + .../video/rockchip/hdmi/chips/cat66121/sha1.h | 46 + .../rockchip/hdmi/chips/cat66121/typedef.h | 380 +++ 26 files changed, 8290 insertions(+) create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/Kconfig create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/Makefile create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h create mode 100644 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/config.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/csc.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/debug.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/sha1.c create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/sha1.h create mode 100755 drivers/video/rockchip/hdmi/chips/cat66121/typedef.h diff --git a/arch/arm/mach-rk30/board-rk3066b-sdk.c b/arch/arm/mach-rk30/board-rk3066b-sdk.c index 7e7dcae264b3..164de3b85f9e 100755 --- a/arch/arm/mach-rk30/board-rk3066b-sdk.c +++ b/arch/arm/mach-rk30/board-rk3066b-sdk.c @@ -1573,6 +1573,14 @@ static struct i2c_board_info __initdata i2c1_info[] = { .platform_data = &tps65910_data, }, #endif +#if defined(CONFIG_HDMI_CAT66121) + { + .type = "cat66121_hdmi", + .addr = 0x4c, + .flags = 0, + .irq = RK30_PIN1_PB7, + }, +#endif }; #endif diff --git a/drivers/video/rockchip/hdmi/chips/Kconfig b/drivers/video/rockchip/hdmi/chips/Kconfig index 589ed9929ad7..2ab2c527b341 100755 --- a/drivers/video/rockchip/hdmi/chips/Kconfig +++ b/drivers/video/rockchip/hdmi/chips/Kconfig @@ -18,6 +18,15 @@ if HDMI_RK2928 source "drivers/video/rockchip/hdmi/chips/rk2928/Kconfig" endif +config HDMI_CAT66121 + bool "CAT66121 HDMI support" + help + Support cat66121 hdmi if you say y here + +if HDMI_CAT66121 +source "drivers/video/rockchip/hdmi/chips/cat66121/Kconfig" +endif + config HDMI_RK610 bool "RK610 HDMI support" depends on MFD_RK610 diff --git a/drivers/video/rockchip/hdmi/chips/Makefile b/drivers/video/rockchip/hdmi/chips/Makefile index 38cb73e24fda..65872d19a944 100755 --- a/drivers/video/rockchip/hdmi/chips/Makefile +++ b/drivers/video/rockchip/hdmi/chips/Makefile @@ -7,3 +7,4 @@ ccflags-$(CONFIG_HDMI_RK30_DEBUG) = -DDEBUG -DHDMI_DEBUG obj-$(CONFIG_HDMI_RK30) += rk30/ obj-$(CONFIG_HDMI_RK2928) += rk2928/ obj-$(CONFIG_HDMI_RK610) += rk610/ +obj-$(CONFIG_HDMI_CAT66121) += cat66121/ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig b/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig new file mode 100755 index 000000000000..8b137891791f --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/Kconfig @@ -0,0 +1 @@ + diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/Makefile b/drivers/video/rockchip/hdmi/chips/cat66121/Makefile new file mode 100755 index 000000000000..7d0ffda6f61d --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_HDMI_CAT66121) += cat66121_hdmi.o \ + cat66121_hdmi_hw.o \ + hdmitx_sys.o \ + hdmitx_hdcp.o \ + hdmitx_input.o \ + hdmitx_drv.o + diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c new file mode 100755 index 000000000000..c3a6834bdeec --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.c @@ -0,0 +1,340 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "cat66121_hdmi.h" + +struct cat66121_hdmi_pdata *cat66121_hdmi = NULL; +struct hdmi *hdmi=NULL; + +extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name); +extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent); +extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi); + +int cat66121_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void), + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)) +{ + hdmi->hdcp_cb = hdcp_cb; + hdmi->hdcp_irq_cb = hdcp_irq_cb; + hdmi->hdcp_power_on_cb = hdcp_power_on_cb; + hdmi->hdcp_power_off_cb = hdcp_power_off_cb; + + return HDMI_ERROR_SUCESS; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void hdmi_early_suspend(struct early_suspend *h) +{ + hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state); + flush_delayed_work(&hdmi->delay_work); + mutex_lock(&hdmi->enable_mutex); + hdmi->suspend = 1; + if(!hdmi->enable) { + mutex_unlock(&hdmi->enable_mutex); + return; + } + + #ifdef HDMI_USE_IRQ + if(hdmi->irq) + disable_irq(hdmi->irq); + #endif + + mutex_unlock(&hdmi->enable_mutex); + hdmi->command = HDMI_CONFIG_ENABLE; + init_completion(&hdmi->complete); + hdmi->wait = 1; + queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0); + wait_for_completion_interruptible_timeout(&hdmi->complete, + msecs_to_jiffies(5000)); + flush_delayed_work(&hdmi->delay_work); + return; +} + +static void hdmi_early_resume(struct early_suspend *h) +{ + hdmi_dbg(hdmi->dev, "hdmi exit early resume\n"); + mutex_lock(&hdmi->enable_mutex); + + hdmi->suspend = 0; + #ifdef HDMI_USE_IRQ + if(hdmi->enable && hdmi->irq) { + enable_irq(hdmi->irq); + } + #else + queue_delayed_work(cat66121_hdmi->workqueue, &cat66121_hdmi->delay_work, 100); + #endif + queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); + mutex_unlock(&hdmi->enable_mutex); + return; +} +#endif + +static void cat66121_irq_work_func(struct work_struct *work) +{ + if(hdmi->suspend == 0) { + if(hdmi->enable == 1) { + cat66121_hdmi_interrupt(); + if(hdmi->hdcp_irq_cb) + hdmi->hdcp_irq_cb(0); + } + #ifndef HDMI_USE_IRQ + queue_delayed_work(cat66121_hdmi->workqueue, &cat66121_hdmi->delay_work, 50); + #endif + } +} + +#ifdef HDMI_USE_IRQ +static irqreturn_t cat66121_irq(int irq, void *dev_id) +{ + printk(KERN_INFO "cat66121 irq triggered.\n"); + schedule_work(&cat66121_hdmi->irq_work); + return IRQ_HANDLED; +} +#endif +static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val) +{ + return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; +} + +static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val) +{ + return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; +} +static ssize_t rk610_show_reg_attrs(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + + int i,size=0; + char val; + struct i2c_client *client=cat66121_hdmi->client; + + for(i=0;i<256;i++) + { + rk610_read_p0_reg(client, i, &val); + if(i%16==0) + size += sprintf(buf+size,"\n>>>rk610_hdmi %x:",i); + size += sprintf(buf+size," %2x",val); + } + + return size; +} +static ssize_t rk610_store_reg_attrs(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct i2c_client *client=NULL; + static char val=0,reg=0; + client = cat66121_hdmi->client; + printk("/**********rk610 reg config******/"); + + sscanf(buf, "%x%x", &val,®); + printk("reg=%x val=%x\n",reg,val); + rk610_write_p0_reg(client, reg, &val); + printk("val=%x\n",val); + return size; +} + +static struct device_attribute rk610_attrs[] = { + __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs), +}; +static int cat66121_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) +{ + int rc = 0; + + cat66121_hdmi = kzalloc(sizeof(struct cat66121_hdmi_pdata), GFP_KERNEL); + if(!cat66121_hdmi) + { + dev_err(&client->dev, "no memory for state\n"); + return -ENOMEM; + } + cat66121_hdmi->client = client; + i2c_set_clientdata(client, cat66121_hdmi); + + hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL); + if(!hdmi) + { + dev_err(&client->dev, "cat66121 hdmi kmalloc fail!"); + goto err_kzalloc_hdmi; + } + memset(hdmi, 0, sizeof(struct hdmi)); + hdmi->dev = &client->dev; + + if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0) + hdmi->lcdc = rk_get_lcdc_drv("lcdc0"); + else + hdmi->lcdc = rk_get_lcdc_drv("lcdc1"); + if(hdmi->lcdc == NULL) + { + dev_err(hdmi->dev, "can not connect to video source lcdc\n"); + rc = -ENXIO; + goto err_request_lcdc; + } + hdmi->xscale = 100; + hdmi->yscale = 100; + hdmi->insert = cat66121_hdmi_sys_insert; + hdmi->remove = cat66121_hdmi_sys_remove; + hdmi->control_output = cat66121_hdmi_sys_enalbe_output; + hdmi->config_video = cat66121_hdmi_sys_config_video; + hdmi->config_audio = cat66121_hdmi_sys_config_audio; + hdmi->detect_hotplug = cat66121_hdmi_sys_detect_hpd; + hdmi->read_edid = cat66121_hdmi_sys_read_edid; + hdmi_sys_init(); + + hdmi->workqueue = create_singlethread_workqueue("hdmi"); + INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work); + + #ifdef CONFIG_HAS_EARLYSUSPEND + hdmi->early_suspend.suspend = hdmi_early_suspend; + hdmi->early_suspend.resume = hdmi_early_resume; + hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10; + register_early_suspend(&hdmi->early_suspend); + #endif + + hdmi_register_display_sysfs(hdmi, NULL); + #ifdef CONFIG_SWITCH + hdmi->switch_hdmi.name="hdmi"; + switch_dev_register(&(hdmi->switch_hdmi)); + #endif + + spin_lock_init(&hdmi->irq_lock); + mutex_init(&hdmi->enable_mutex); + + cat66121_hdmi_sys_init(); + rc = gpio_request(client->irq, "cat66121 rst"); + if (rc != 0) { + gpio_free(client->irq); + printk("goodix power error\n"); + return -EIO; + } + gpio_direction_output(client->irq, GPIO_HIGH); + gpio_set_value(client->irq, GPIO_HIGH); + msleep(10); + gpio_set_value(client->irq, GPIO_LOW); + msleep(200); + gpio_set_value(client->irq, GPIO_HIGH); +#ifdef HDMI_USE_IRQ + if(client->irq != INVALID_GPIO) { + INIT_WORK(&cat66121_hdmi->irq_work, cat66121_irq_work_func); + schedule_work(&cat66121_hdmi->irq_work); + if((rc = gpio_request(client->irq, "hdmi gpio")) < 0) + { + dev_err(&client->dev, "fail to request gpio %d\n", client->irq); + goto err_request_lcdc; + } + hdmi->irq = gpio_to_irq(client->irq); + cat66121_hdmi->gpio = client->irq; + gpio_pull_updown(client->irq, GPIOPullUp); + gpio_direction_input(client->irq); + if((rc = request_irq(hdmi->irq, cat66121_irq, IRQF_TRIGGER_RISING, NULL, hdmi)) < 0) + { + dev_err(&client->dev, "fail to request hdmi irq\n"); + goto err_request_irq; + } + } + else +#else + { + cat66121_hdmi->workqueue = create_singlethread_workqueue("cat66121 irq"); + INIT_DELAYED_WORK(&(cat66121_hdmi->delay_work), cat66121_irq_work_func); + cat66121_irq_work_func(NULL); + } +#endif + + device_create_file(&(client->dev), &rk610_attrs[0]); + dev_info(&client->dev, "cat66121 hdmi i2c probe ok\n"); + + return 0; + +err_request_irq: + gpio_free(client->irq); +err_request_lcdc: + kfree(hdmi); + hdmi = NULL; +err_kzalloc_hdmi: + kfree(cat66121_hdmi); + cat66121_hdmi = NULL; + dev_err(&client->dev, "cat66121 hdmi probe error\n"); + return rc; + +} + +static int __devexit cat66121_hdmi_i2c_remove(struct i2c_client *client) +{ + hdmi_dbg(hdmi->dev, "%s\n", __func__); + if(hdmi) { + mutex_lock(&hdmi->enable_mutex); + if(!hdmi->suspend && hdmi->enable && hdmi->irq) + disable_irq(hdmi->irq); + mutex_unlock(&hdmi->enable_mutex); + if(hdmi->irq) + free_irq(hdmi->irq, NULL); + flush_workqueue(hdmi->workqueue); + destroy_workqueue(hdmi->workqueue); + #ifdef CONFIG_SWITCH + switch_dev_unregister(&(hdmi->switch_hdmi)); + #endif + hdmi_unregister_display_sysfs(hdmi); + #ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&hdmi->early_suspend); + #endif + fb_destroy_modelist(&hdmi->edid.modelist); + if(hdmi->edid.audio) + kfree(hdmi->edid.audio); + if(hdmi->edid.specs) + { + if(hdmi->edid.specs->modedb) + kfree(hdmi->edid.specs->modedb); + kfree(hdmi->edid.specs); + } + kfree(hdmi); + hdmi = NULL; + } + return 0; +} + +static void cat66121_hdmi_i2c_shutdown(struct i2c_client *client) +{ + if(hdmi) { + #ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&hdmi->early_suspend); + #endif + } + printk(KERN_INFO "cat66121 hdmi shut down.\n"); +} + +static const struct i2c_device_id cat66121_hdmi_id[] = { + { "cat66121_hdmi", 0 }, + { } +}; + +static struct i2c_driver cat66121_hdmi_i2c_driver = { + .driver = { + .name = "cat66121_hdmi", + .owner = THIS_MODULE, + }, + .probe = cat66121_hdmi_i2c_probe, + .remove = cat66121_hdmi_i2c_remove, + .shutdown = cat66121_hdmi_i2c_shutdown, + .id_table = cat66121_hdmi_id, +}; + +static int __init cat66121_hdmi_init(void) +{ + return i2c_add_driver(&cat66121_hdmi_i2c_driver); +} + +static void __exit cat66121_hdmi_exit(void) +{ + i2c_del_driver(&cat66121_hdmi_i2c_driver); +} + +module_init(cat66121_hdmi_init); +//fs_initcall(cat66121_init); +module_exit(cat66121_hdmi_exit); diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h new file mode 100755 index 000000000000..0a3bdc40148d --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi.h @@ -0,0 +1,34 @@ +#ifndef __cat66121_HDMI_H__ +#define __cat66121_HDMI_H__ +#include "../../rk_hdmi.h" + +#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0 +//#define HDMI_USE_IRQ + +struct cat66121_hdmi_pdata { + int gpio; + struct i2c_client *client; + struct delayed_work delay_work; + #ifdef HDMI_USE_IRQ + struct work_struct irq_work; + #else + struct workqueue_struct *workqueue; + #endif +}; + +extern struct cat66121_hdmi_pdata *cat66121_hdmi; + +extern int cat66121_hdmi_sys_init(void); +extern void cat66121_hdmi_interrupt(void); +extern int cat66121_hdmi_sys_detect_hpd(void); +extern int cat66121_hdmi_sys_insert(void); +extern int cat66121_hdmi_sys_remove(void); +extern int cat66121_hdmi_sys_read_edid(int block, unsigned char *buff); +extern int cat66121_hdmi_sys_config_video(struct hdmi_video_para *vpara); +extern int cat66121_hdmi_sys_config_audio(struct hdmi_audio *audio); +extern void cat66121_hdmi_sys_enalbe_output(int enable); +extern int cat66121_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void), + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)); +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c new file mode 100755 index 000000000000..cc8a625c7ae4 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.c @@ -0,0 +1,236 @@ +#include +#include "cat66121_hdmi.h" +#include "cat66121_hdmi_hw.h" +#include +#include +#include +#include + +#define HDMITX_INPUT_SIGNAL_TYPE 0 // for default(Sync Sep Mode) +#define INPUT_SPDIF_ENABLE 0 +extern int CAT66121_Interrupt_Process(void); +/******************************* + * Global Data + ******************************/ +static _XDATA AVI_InfoFrame AviInfo; +static _XDATA Audio_InfoFrame AudioInfo; +static unsigned long VideoPixelClock; +static unsigned int pixelrep; + +/* I2C read/write funcs */ +BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr) +{ + struct i2c_msg msgs[2]; + SYS_STATUS ret = -1; + BYTE buf[1]; + + buf[0] = RegAddr; + + /* Write device addr fisrt */ + msgs[0].addr = cat66121_hdmi->client->addr; + msgs[0].flags = !I2C_M_RD; + msgs[0].len = 1; + msgs[0].buf = &buf[0]; + msgs[0].scl_rate= 100*1000; + /* Then, begin to read data */ + msgs[1].addr = cat66121_hdmi->client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = 1; + msgs[1].buf = &buf[0]; + msgs[1].scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); + if(ret != 2) + printk("I2C transfer Error! ret = %d\n", ret); + + //ErrorF("Reg%02xH: 0x%02x\n", RegAddr, buf[0]); + return buf[0]; +} + +SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr, BYTE data) +{ + struct i2c_msg msg; + SYS_STATUS ret = -1; + BYTE buf[2]; + + buf[0] = RegAddr; + buf[1] = data; + + msg.addr = cat66121_hdmi->client->addr; + msg.flags = !I2C_M_RD; + msg.len = 2; + msg.buf = buf; + msg.scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); + if(ret != 1) + printk("I2C transfer Error!\n"); + + return ret; +} + +SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) +{ + struct i2c_msg msgs[2]; + SYS_STATUS ret = -1; + + pData[0] = RegAddr; + + msgs[0].addr = cat66121_hdmi->client->addr; + msgs[0].flags = !I2C_M_RD; + msgs[0].len = 1; + msgs[0].buf = &pData[0]; + msgs[0].scl_rate= 100*1000; + + msgs[1].addr = cat66121_hdmi->client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = N; + msgs[1].buf = pData; + msgs[1].scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); + if(ret != 2) + printk("I2C transfer Error! ret = %d\n", ret); + + return ret; +} + +SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) +{ + struct i2c_msg msg; + SYS_STATUS ret = -1; + BYTE buf[N + 1]; + + buf[0] = RegAddr; + memcpy(&buf[1], pData, N); + + msg.addr = cat66121_hdmi->client->addr; + msg.flags = !I2C_M_RD; + msg.len = N + 1; + msg.buf = buf; // gModify.Exp."Include RegAddr" + msg.scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); + if(ret != 1) + printk("I2C transfer Error! ret = %d\n", ret); + + return ret; +} +SYS_STATUS HDMITX_SetI2C_Byte(BYTE Reg,BYTE Mask,BYTE Value) +{ + BYTE Temp; + if( Mask != 0xFF ) + { + Temp=HDMITX_ReadI2C_Byte(Reg); + Temp&=(~Mask); + Temp|=Value&Mask; + } + else + { + Temp=Value; + } + return HDMITX_WriteI2C_Byte(Reg,Temp); +} +int cat66121_hdmi_sys_init(void) +{ + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); + rk30_mux_api_set(GPIO0C1_FLASHDATA9_NAME, GPIO0C_GPIO0C1); + if (gpio_request(RK30_PIN0_PC1, NULL)) { + printk("func %s, line %d: request gpio fail\n", __FUNCTION__, __LINE__); + return -1; + } + gpio_direction_output(RK30_PIN0_PC1, GPIO_LOW); + gpio_set_value(RK30_PIN0_PC1, GPIO_LOW); + msleep(200); + gpio_set_value(RK30_PIN0_PC1, GPIO_HIGH); + msleep(200); + + mdelay(5); + VideoPixelClock = 0; + pixelrep = 0; + InitHDMITX_Variable(); + InitHDMITX(); + msleep(100); + return HDMI_ERROR_SUCESS; +} + +void cat66121_hdmi_interrupt() +{ + char interrupt = 0; + + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); + if(hdmi->state == HDMI_SLEEP) + hdmi->state = WAIT_HOTPLUG; + queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); +} + +int cat66121_hdmi_sys_detect_hpd(void) +{ + char hdmi_status = 0; + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); + // BYTE sysstat; + + //sysstat = HDMITX_ReadI2C_Byte(REG_SYS_STATUS) ; + //*hpdstatus = ((sysstat & B_HPDETECT) == B_HPDETECT)?TRUE:FALSE ; + hdmi_status = HDMITX_DevLoopProc(); +; + return HDMI_HPD_ACTIVED; + if(hdmi_status) + return HDMI_HPD_ACTIVED; + else + return HDMI_HPD_REMOVED; +} + +int cat66121_hdmi_sys_read_edid(int block, unsigned char *buff) +{ + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); + return (getHDMITX_EDIDBlock(block, buff) == TRUE)?HDMI_ERROR_SUCESS:HDMI_ERROR_FALSE; +} + +static void cat66121_sys_config_avi(int VIC, int bOutputColorMode, int aspec, int Colorimetry, int pixelrep) +{ + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); +// AVI_InfoFrame AviInfo; + +} + +int cat66121_hdmi_sys_config_video(struct hdmi_video_para *vpara) +{ + printk( "[%s]\n", __FUNCTION__); + printk( "[%s]\n", __FUNCTION__); + HDMITX_ChangeDisplayOption(vpara->vic,HDMI_RGB444) ; + + return HDMI_ERROR_SUCESS; +} + +static void cat66121_hdmi_config_aai(void) +{ + printk( "[%s]\n", __FUNCTION__); +} + +int cat66121_hdmi_sys_config_audio(struct hdmi_audio *audio) +{ + printk( "[%s]\n", __FUNCTION__); + return HDMI_ERROR_SUCESS; +} + +void cat66121_hdmi_sys_enalbe_output(int enable) +{ + + printk( "[%s]\n", __FUNCTION__); +} + +int cat66121_hdmi_sys_insert(void) +{ + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); + printk( "[%s]\n", __FUNCTION__); + return 0; +} + +int cat66121_hdmi_sys_remove(void) +{ + hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); +// printk( "[%s]\n", __FUNCTION__); + + return 0; +} diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h new file mode 100755 index 000000000000..d22bed25acb9 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_hdmi_hw.h @@ -0,0 +1,260 @@ +#ifndef _CAT6611_HDMI_HW_H +#define _CAT6611_HDMI_HW_H + +#include "typedef.h" +#include "hdmitx_drv.h" +#include "hdmitx_sys.h" +#define CAT6611_SCL_RATE 100 * 1000 +#define I2S 0 +#define SPDIF 1 + +#ifndef I2S_FORMAT +#define I2S_FORMAT 0x01 // 32bit audio +#endif + +#ifndef INPUT_SAMPLE_FREQ + #define INPUT_SAMPLE_FREQ AUDFS_48KHz +#endif //INPUT_SAMPLE_FREQ + +#ifndef INPUT_SAMPLE_FREQ_HZ + #define INPUT_SAMPLE_FREQ_HZ 48000L +#endif //INPUT_SAMPLE_FREQ_HZ + +#ifndef OUTPUT_CHANNEL + #define OUTPUT_CHANNEL 2 +#endif //OUTPUT_CHANNEL + +#ifndef CNOFIG_INPUT_AUDIO_TYPE + #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_LPCM + // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_NLPCM + // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_HBR +#endif //CNOFIG_INPUT_AUDIO_TYPE + +#ifndef CONFIG_INPUT_AUDIO_SPDIF + #define CONFIG_INPUT_AUDIO_SPDIF I2S + // #define CONFIG_INPUT_AUDIO_SPDIF SPDIF +#endif //CONFIG_INPUT_AUDIO_SPDIF + +#ifndef INPUT_SIGNAL_TYPE +#define INPUT_SIGNAL_TYPE 0 // 24 bit sync seperate +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Internal Data Type +//////////////////////////////////////////////////////////////////////////////// + +typedef enum tagHDMI_Video_Type { + HDMI_Unkown = 0 , + HDMI_640x480p60 = 1 , + HDMI_480p60, + HDMI_480p60_16x9, + HDMI_720p60, + HDMI_1080i60, + HDMI_480i60, + HDMI_480i60_16x9, + HDMI_1080p60 = 16, + HDMI_576p50, + HDMI_576p50_16x9, + HDMI_720p50, + HDMI_1080i50, + HDMI_576i50, + HDMI_576i50_16x9, + HDMI_1080p50 = 31, + HDMI_1080p24, + HDMI_1080p25, + HDMI_1080p30, + HDMI_720p30 = 61, +} HDMI_Video_Type ; + +typedef enum tagHDMI_Aspec { + HDMI_4x3 , + HDMI_16x9 +} HDMI_Aspec; + +typedef enum tagHDMI_OutputColorMode { + HDMI_RGB444, + HDMI_YUV444, + HDMI_YUV422 +} HDMI_OutputColorMode ; + +typedef enum tagHDMI_Colorimetry { + HDMI_ITU601, + HDMI_ITU709 +} HDMI_Colorimetry ; + +struct VideoTiming { + ULONG VideoPixelClock ; + BYTE VIC ; + BYTE pixelrep ; + BYTE outputVideoMode ; +} ; + + + +typedef enum _TXVideo_State_Type { + TXVSTATE_Unplug = 0, + TXVSTATE_HPD, + TXVSTATE_WaitForMode, + TXVSTATE_WaitForVStable, + TXVSTATE_VideoInit, + TXVSTATE_VideoSetup, + TXVSTATE_VideoOn, + TXVSTATE_Reserved +} TXVideo_State_Type ; + + +typedef enum _TXAudio_State_Type { + TXASTATE_AudioOff = 0, + TXASTATE_AudioPrepare, + TXASTATE_AudioOn, + TXASTATE_AudioFIFOFail, + TXASTATE_Reserved +} TXAudio_State_Type ; +///////////////////////////////////////// +// RX Capability. +///////////////////////////////////////// +typedef struct { + BYTE b16bit:1 ; + BYTE b20bit:1 ; + BYTE b24bit:1 ; + BYTE Rsrv:5 ; +} LPCM_BitWidth ; + +typedef enum { + AUD_RESERVED_0 = 0 , + AUD_LPCM, + AUD_AC3, + AUD_MPEG1, + AUD_MP3, + AUD_MPEG2, + AUD_AAC, + AUD_DTS, + AUD_ATRAC, + AUD_ONE_BIT_AUDIO, + AUD_DOLBY_DIGITAL_PLUS, + AUD_DTS_HD, + AUD_MAT_MLP, + AUD_DST, + AUD_WMA_PRO, + AUD_RESERVED_15 +} AUDIO_FORMAT_CODE ; + +typedef union { + struct { + BYTE channel:3 ; + BYTE AudioFormatCode:4 ; + BYTE Rsrv1:1 ; + + BYTE b32KHz:1 ; + BYTE b44_1KHz:1 ; + BYTE b48KHz:1 ; + BYTE b88_2KHz:1 ; + BYTE b96KHz:1 ; + BYTE b176_4KHz:1 ; + BYTE b192KHz:1 ; + BYTE Rsrv2:1 ; + BYTE ucCode ; + } s ; + BYTE uc[3] ; +} AUDDESCRIPTOR ; + +typedef union { + struct { + BYTE FL_FR:1 ; + BYTE LFE:1 ; + BYTE FC:1 ; + BYTE RL_RR:1 ; + BYTE RC:1 ; + BYTE FLC_FRC:1 ; + BYTE RLC_RRC:1 ; + BYTE Reserve:1 ; + BYTE Unuse[2] ; + } s ; + BYTE uc[3] ; +} SPK_ALLOC ; + +#define CEA_SUPPORT_UNDERSCAN (1<<7) +#define CEA_SUPPORT_AUDIO (1<<6) +#define CEA_SUPPORT_YUV444 (1<<5) +#define CEA_SUPPORT_YUV422 (1<<4) +#define CEA_NATIVE_MASK 0xF + + +#define HDMI_DC_SUPPORT_AI (1<<7) +#define HDMI_DC_SUPPORT_48 (1<<6) +#define HDMI_DC_SUPPORT_36 (1<<5) +#define HDMI_DC_SUPPORT_30 (1<<4) +#define HDMI_DC_SUPPORT_Y444 (1<<3) +#define HDMI_DC_SUPPORT_DVI_DUAL 1 + +typedef union _tag_DCSUPPORT { + struct { + BYTE DVI_Dual:1 ; + BYTE Rsvd:2 ; + BYTE DC_Y444:1 ; + BYTE DC_30Bit:1 ; + BYTE DC_36Bit:1 ; + BYTE DC_48Bit:1 ; + BYTE SUPPORT_AI:1 ; + } info ; + BYTE uc ; +} DCSUPPORT ; + +typedef union _LATENCY_SUPPORT{ + struct { + BYTE Rsvd:6 ; + BYTE I_Latency_Present:1 ; + BYTE Latency_Present:1 ; + } info ; + BYTE uc ; +} LATENCY_SUPPORT ; + +#define HDMI_IEEEOUI 0x0c03 +#define MAX_VODMODE_COUNT 32 +#define MAX_AUDDES_COUNT 4 + +typedef struct _RX_CAP{ + BYTE VideoMode ; + BYTE NativeVDOMode ; + BYTE VDOMode[8] ; + BYTE AUDDesCount ; + AUDDESCRIPTOR AUDDes[MAX_AUDDES_COUNT] ; + BYTE PA[2] ; + ULONG IEEEOUI ; + DCSUPPORT dc ; + BYTE MaxTMDSClock ; + LATENCY_SUPPORT lsupport ; + SPK_ALLOC SpeakerAllocBlk ; + BYTE ValidCEA:1 ; + BYTE ValidHDMI:1 ; + BYTE Valid3D:1 ; +} RX_CAP ; + +/////////////////////////////////////////////////////////////////////// +// Output Mode Type +/////////////////////////////////////////////////////////////////////// + +#define RES_ASPEC_4x3 0 +#define RES_ASPEC_16x9 1 +#define F_MODE_REPT_NO 0 +#define F_MODE_REPT_TWICE 1 +#define F_MODE_REPT_QUATRO 3 +#define F_MODE_CSC_ITU601 0 +#define F_MODE_CSC_ITU709 1 + +BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr); +SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE d); +SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); +SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); +SYS_STATUS HDMITX_SetI2C_Byte(BYTE Reg,BYTE Mask,BYTE Value); + +void InitHDMITX_Variable(); +void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode); +void HDMITX_SetOutput(); +int HDMITX_DevLoopProc(); +void ConfigfHdmiVendorSpecificInfoFrame(BYTE _3D_Stru); +void HDMITX_ChangeAudioOption(BYTE Option, BYTE channelNum, BYTE AudioFs); +void HDMITX_SetAudioOutput(); +void HDMITX_ChangeColorDepth(BYTE colorDepth); + +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.c b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.c new file mode 100644 index 000000000000..c8b158228365 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.c @@ -0,0 +1,217 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file >cat66121_sys.c< +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2009/08/24 +// @fileversion: cat66121_SAMPLEINTERFACE_1.12 +//******************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// This is the sample program for cat66121 driver usage. +/////////////////////////////////////////////////////////////////////////////// + +#include "hdmitx.h" +#include "hdmitx_sys.h" +#include "cat66121_hdmi.h" + +#if 0 +BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr); +SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE d); +SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); +SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N); +SYS_STATUS HDMITX_SetI2C_Byte(BYTE Reg,BYTE Mask,BYTE Value); +#endif +/* I2C read/write funcs */ +BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr) +{ + struct i2c_msg msgs[2]; + SYS_STATUS ret = -1; + BYTE buf[1]; + + buf[0] = RegAddr; + + /* Write device addr fisrt */ + msgs[0].addr = cat66121_hdmi->client->addr; + msgs[0].flags = !I2C_M_RD; + msgs[0].len = 1; + msgs[0].buf = &buf[0]; + msgs[0].scl_rate= 100*1000; + /* Then, begin to read data */ + msgs[1].addr = cat66121_hdmi->client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = 1; + msgs[1].buf = &buf[0]; + msgs[1].scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); + if(ret != 2) + printk("I2C transfer Error! ret = %d\n", ret); + + //ErrorF("Reg%02xH: 0x%02x\n", RegAddr, buf[0]); + return buf[0]; +} + +SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr, BYTE data) +{ + struct i2c_msg msg; + SYS_STATUS ret = -1; + BYTE buf[2]; + + buf[0] = RegAddr; + buf[1] = data; + + msg.addr = cat66121_hdmi->client->addr; + msg.flags = !I2C_M_RD; + msg.len = 2; + msg.buf = buf; + msg.scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); + if(ret != 1) + printk("I2C transfer Error!\n"); + + return ret; +} + +SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) +{ + struct i2c_msg msgs[2]; + SYS_STATUS ret = -1; + + pData[0] = RegAddr; + + msgs[0].addr = cat66121_hdmi->client->addr; + msgs[0].flags = !I2C_M_RD; + msgs[0].len = 1; + msgs[0].buf = &pData[0]; + msgs[0].scl_rate= 100*1000; + + msgs[1].addr = cat66121_hdmi->client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = N; + msgs[1].buf = pData; + msgs[1].scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, msgs, 2); + if(ret != 2) + printk("I2C transfer Error! ret = %d\n", ret); + + return ret; +} + +SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr, BYTE *pData, int N) +{ + struct i2c_msg msg; + SYS_STATUS ret = -1; + BYTE buf[N + 1]; + + buf[0] = RegAddr; + memcpy(&buf[1], pData, N); + + msg.addr = cat66121_hdmi->client->addr; + msg.flags = !I2C_M_RD; + msg.len = N + 1; + msg.buf = buf; // gModify.Exp."Include RegAddr" + msg.scl_rate= 100*1000; + + ret = i2c_transfer(cat66121_hdmi->client->adapter, &msg, 1); + if(ret != 1) + printk("I2C transfer Error! ret = %d\n", ret); + + return ret; +} +static int cat66121_hdmi_i2c_read_reg(char reg, char *val) +{ + if(i2c_master_reg8_recv(cat66121_hdmi->client, reg, val, 1, 100*1000) > 0) + return 0; + else { + printk("[%s] reg %02x error\n", __FUNCTION__, reg); + return -EINVAL; + } +} +/******************************* + * Global Data + ******************************/ + +/******************************* + * Functions + ******************************/ +int cat66121_detect_device(void) +{ + printk(">>>%s \n",__func__); + return 0; +} + +int cat66121_sys_init(struct hdmi *hdmi) +{ + printk(">>>%s \n",__func__); + InitHDMITX_Variable(); + InitHDMITX(); + HDMITX_ChangeDisplayOption(HDMI_720p60,HDMI_RGB444) ; + HDMITX_DevLoopProc(); + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_unplug(struct hdmi *hdmi) +{ + printk(">>>%s \n",__func__); + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_detect_hpd(struct hdmi *hdmi, int *hpdstatus) +{ + printk(">>>%s \n",__func__); + *hpdstatus = TRUE; + + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_detect_sink(struct hdmi *hdmi, int *sink_status) +{ + printk(">>>%s \n",__func__); + *sink_status = TRUE; + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_read_edid(struct hdmi *hdmi, int block, unsigned char *buff) +{ + printk(">>>%s \n",__func__); + return HDMI_ERROR_SUCESS; +} + +static void cat66121_sys_config_avi(int VIC, int bOutputColorMode, int aspec, int Colorimetry, int pixelrep) +{ +} + +int cat66121_sys_config_video(struct hdmi *hdmi, int vic, int input_color, int output_color) +{ + printk(">>>%s \n",__func__); + HDMITX_DevLoopProc(); + return HDMI_ERROR_SUCESS ; +} + +static void cat66121_sys_config_aai(void) +{ + printk(">>>%s \n",__func__); +} + +int cat66121_sys_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio) +{ + printk(">>>%s \n",__func__); + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_config_hdcp(struct hdmi *hdmi, int enable) +{ + printk(">>>%s \n",__func__); + return HDMI_ERROR_SUCESS; +} + +int cat66121_sys_enalbe_output(struct hdmi *hdmi, int enable) +{ + printk(">>>%s \n",__func__); + return HDMI_ERROR_SUCESS; +} diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.h b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.h new file mode 100755 index 000000000000..38f1c9a67833 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/cat66121_sys.h @@ -0,0 +1,164 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file >cat66121_sys.h< +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2009/08/24 +// @fileversion: cat66121_SAMPLEINTERFACE_1.12 +//******************************************/ + +#ifndef _CAT66121_SYS_H_ +#define _CAT66121_SYS_H_ +//////////////////////////////////////////////////////////////////////////////// +// Internal Data Type +//////////////////////////////////////////////////////////////////////////////// + +typedef enum tagHDMI_Video_Type { + HDMI_Unkown = 0 , + HDMI_640x480p60 = 1 , + HDMI_480p60, + HDMI_480p60_16x9, + HDMI_720p60, + HDMI_1080i60, + HDMI_480i60, + HDMI_480i60_16x9, + HDMI_1080p60 = 16, + HDMI_576p50, + HDMI_576p50_16x9, + HDMI_720p50, + HDMI_1080i50, + HDMI_576i50, + HDMI_576i50_16x9, + HDMI_1080p50 = 31, + HDMI_1080p24, + HDMI_1080p25, + HDMI_1080p30, +} HDMI_Video_Type ; + +typedef enum tagHDMI_Aspec { + HDMI_4x3 , + HDMI_16x9 +} HDMI_Aspec; + +typedef enum tagHDMI_OutputColorMode { + HDMI_RGB444, + HDMI_YUV444, + HDMI_YUV422 +} HDMI_OutputColorMode ; + +typedef enum tagHDMI_Colorimetry { + HDMI_ITU601, + HDMI_ITU709 +} HDMI_Colorimetry ; + +typedef enum tagMODE_ID{ + CEA_640x480p60, + CEA_720x480p60, + CEA_1280x720p60, + CEA_1920x1080i60, + CEA_720x480i60, + CEA_720x240p60, + CEA_1440x480i60, + CEA_1440x240p60, + CEA_2880x480i60, + CEA_2880x240p60, + CEA_1440x480p60, + CEA_1920x1080p60, + CEA_720x576p50, + CEA_1280x720p50, + CEA_1920x1080i50, + CEA_720x576i50, + CEA_1440x576i50, + CEA_720x288p50, + CEA_1440x288p50, + CEA_2880x576i50, + CEA_2880x288p50, + CEA_1440x576p50, + CEA_1920x1080p50, + CEA_1920x1080p24, + CEA_1920x1080p25, + CEA_1920x1080p30, + VESA_640x350p85, + VESA_640x400p85, + VESA_720x400p85, + VESA_640x480p60, + VESA_640x480p72, + VESA_640x480p75, + VESA_640x480p85, + VESA_800x600p56, + VESA_800x600p60, + VESA_800x600p72, + VESA_800x600p75, + VESA_800X600p85, + VESA_840X480p60, + VESA_1024x768p60, + VESA_1024x768p70, + VESA_1024x768p75, + VESA_1024x768p85, + VESA_1152x864p75, + VESA_1280x768p60R, + VESA_1280x768p60, + VESA_1280x768p75, + VESA_1280x768p85, + VESA_1280x960p60, + VESA_1280x960p85, + VESA_1280x1024p60, + VESA_1280x1024p75, + VESA_1280X1024p85, + VESA_1360X768p60, + VESA_1400x768p60R, + VESA_1400x768p60, + VESA_1400x1050p75, + VESA_1400x1050p85, + VESA_1440x900p60R, + VESA_1440x900p60, + VESA_1440x900p75, + VESA_1440x900p85, + VESA_1600x1200p60, + VESA_1600x1200p65, + VESA_1600x1200p70, + VESA_1600x1200p75, + VESA_1600x1200p85, + VESA_1680x1050p60R, + VESA_1680x1050p60, + VESA_1680x1050p75, + VESA_1680x1050p85, + VESA_1792x1344p60, + VESA_1792x1344p75, + VESA_1856x1392p60, + VESA_1856x1392p75, + VESA_1920x1200p60R, + VESA_1920x1200p60, + VESA_1920x1200p75, + VESA_1920x1200p85, + VESA_1920x1440p60, + VESA_1920x1440p75, + UNKNOWN_MODE +} MODE_ID; +/////////////////////////////////////////////////////////////////////// +// Output Mode Type +/////////////////////////////////////////////////////////////////////// + +#define RES_ASPEC_4x3 0 +#define RES_ASPEC_16x9 1 +#define F_MODE_REPT_NO 0 +#define F_MODE_REPT_TWICE 1 +#define F_MODE_REPT_QUATRO 3 +#define F_MODE_CSC_ITU601 0 +#define F_MODE_CSC_ITU709 1 + +/* Follow prototypes need accomplish by ourself */ +int cat66121_detect_device(void); +int cat66121_sys_init(struct hdmi *hdmi); +int cat66121_sys_unplug(struct hdmi *hdmi); +int cat66121_sys_detect_hpd(struct hdmi *hdmi, int *hpdstatus); +int cat66121_sys_detect_sink(struct hdmi *hdmi, int *sink_status); +int cat66121_sys_read_edid(struct hdmi *hdmi, int block, unsigned char *buff); +int cat66121_sys_config_video(struct hdmi *hdmi, int vic, int input_color, int output_color); +int cat66121_sys_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio); +int cat66121_sys_config_hdcp(struct hdmi *hdmi, int enable); +int cat66121_sys_enalbe_output(struct hdmi *hdmi, int enable); +int cat66121_sys_check_status(struct hdmi *hdmi); +#endif // _cat66121_SYS_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/config.h b/drivers/video/rockchip/hdmi/chips/cat66121/config.h new file mode 100755 index 000000000000..5e13aa6aec6d --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/config.h @@ -0,0 +1,138 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ +#pragma message("config.h") + +#ifdef EXTERN_HDCPROM +#pragma message("Defined EXTERN_HDCPROM") +#endif // EXTERN_HDCPROM + +#define SUPPORT_EDID +#define SUPPORT_HDCP +//#define SUPPORT_SHA +//#define SUPPORT_AUDIO_MONITOR +#define AudioOutDelayCnt 250 + + + +////////////////////////////////////////////////////////////////////////////////////////// +// Video Configuration +////////////////////////////////////////////////////////////////////////////////////////// +// 2010/01/26 added a option to disable HDCP. +#define SUPPORT_OUTPUTYUV +#define SUPPORT_OUTPUTRGB +// #define DISABLE_HDMITX_CSC + +#define SUPPORT_INPUTRGB +#define SUPPORT_INPUTYUV444 +#define SUPPORT_INPUTYUV422 +// #define SUPPORT_SYNCEMBEDDED +// #define SUPPORT_DEGEN +#define NON_SEQUENTIAL_YCBCR422 + + + +#define INPUT_COLOR_MODE F_MODE_RGB444 +//#define INPUT_COLOR_MODE F_MODE_YUV422 +//#define INPUT_COLOR_MODE F_MODE_YUV444 + +#define INPUT_COLOR_DEPTH 24 +// #define INPUT_COLOR_DEPTH 30 +// #define INPUT_COLOR_DEPTH 36 + +//#define OUTPUT_COLOR_MODE F_MODE_YUV422 +//#define OUTPUT_COLOR_MODE F_MODE_YUV444 +#define OUTPUT_COLOR_MODE F_MODE_RGB444 + +//#define OUTPUT_3D_MODE Frame_Pcaking +//#define OUTPUT_3D_MODE Top_and_Botton +//#define OUTPUT_3D_MODE Side_by_Side + +// #define INV_INPUT_ACLK +#define INV_INPUT_PCLK + +#ifdef SUPPORT_SYNCEMBEDDED + // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB) // 16 bit sync embedded + // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB | T_MODE_CCIR656) // 8 bit sync embedded + #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB|T_MODE_INDDR|T_MODE_PCLKDIV2) // 16 bit sync embedded DDR + // #define INPUT_SIGNAL_TYPE (T_MODE_SYNCEMB|T_MODE_INDDR) // 8 bit sync embedded DDR + + #define SUPPORT_INPUTYUV422 + #ifdef INPUT_COLOR_MODE + #undef INPUT_COLOR_MODE + #endif // INPUT_COLOR_MODE + #define INPUT_COLOR_MODE F_MODE_YUV422 +#else + #pragma message ("Defined seperated sync.") + #define INPUT_SIGNAL_TYPE 0 // 24 bit sync seperate + //#define INPUT_SIGNAL_TYPE ( T_MODE_DEGEN ) + //#define INPUT_SIGNAL_TYPE ( T_MODE_INDDR) + //#define INPUT_SIGNAL_TYPE ( T_MODE_SYNCEMB) + //#define INPUT_SIGNAL_TYPE ( T_MODE_CCIR656 | T_MODE_SYNCEMB ) +#endif + + +#if defined(SUPPORT_INPUTYUV444) || defined(SUPPORT_INPUTYUV422) +#define SUPPORT_INPUTYUV +#endif + +#ifdef SUPPORT_SYNCEMBEDDED +#pragma message("defined SUPPORT_SYNCEMBEDDED for Sync Embedded timing input or CCIR656 input.") +#endif + + +////////////////////////////////////////////////////////////////////////////////////////// +// Audio Configuration +////////////////////////////////////////////////////////////////////////////////////////// + +// #define SUPPORT_HBR_AUDIO +#define USE_SPDIF_CHSTAT +#ifndef SUPPORT_HBR_AUDIO + #define INPUT_SAMPLE_FREQ AUDFS_48KHz + #define INPUT_SAMPLE_FREQ_HZ 48000L + #define OUTPUT_CHANNEL 2 // 3 // 4 // 5//6 //7 //8 + + #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_LPCM + // #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_NLPCM + #define CONFIG_INPUT_AUDIO_SPDIF FALSE // I2S + // #define CONFIG_INPUT_AUDIO_SPDIF TRUE // SPDIF + + // #define I2S_FORMAT 0x00 // 24bit I2S audio + #define I2S_FORMAT 0x01 // 32bit I2S audio + // #define I2S_FORMAT 0x02 // 24bit I2S audio, right justify + // #define I2S_FORMAT 0x03 // 32bit I2S audio, right justify + +#else // SUPPORT_HBR_AUDIO + + #define INPUT_SAMPLE_FREQ AUDFS_768KHz + #define INPUT_SAMPLE_FREQ_HZ 768000L + #define OUTPUT_CHANNEL 8 + #define CNOFIG_INPUT_AUDIO_TYPE T_AUDIO_HBR + #define CONFIG_INPUT_AUDIO_SPDIF FALSE // I2S + // #define CONFIG_INPUT_AUDIO_SPDIF TRUE // SPDIF + #define I2S_FORMAT 0x47 // 32bit audio +#endif + + + +////////////////////////////////////////////////////////////////////////////////////////// +// Audio Monitor Configuration +////////////////////////////////////////////////////////////////////////////////////////// +// #define HDMITX_AUTO_MONITOR_INPUT +// #define HDMITX_INPUT_INFO + +#ifdef HDMITX_AUTO_MONITOR_INPUT +#define HDMITX_INPUT_INFO +#endif + + +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/csc.c b/drivers/video/rockchip/hdmi/chips/cat66121/csc.c new file mode 100755 index 000000000000..6823a12dc2a4 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/csc.c @@ -0,0 +1,83 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/01/06 +// @fileversion: COMMON_2.00 +//******************************************/ + +#include "config.h" +#include "typedef.h" + +#if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB)) + + BYTE _CODE bCSCMtx_RGB2YUV_ITU601_16_235[] = + { + 0x00,0x80,0x00, + 0xB2,0x04,0x65,0x02,0xE9,0x00, + 0x93,0x3C,0x18,0x04,0x55,0x3F, + 0x49,0x3D,0x9F,0x3E,0x18,0x04 + } ; + + BYTE _CODE bCSCMtx_RGB2YUV_ITU601_0_255[] = + { + 0x10,0x80,0x10, + 0x09,0x04,0x0E,0x02,0xC9,0x00, + 0x0F,0x3D,0x84,0x03,0x6D,0x3F, + 0xAB,0x3D,0xD1,0x3E,0x84,0x03 + } ; + + BYTE _CODE bCSCMtx_RGB2YUV_ITU709_16_235[] = + { + 0x00,0x80,0x00, + 0xB8,0x05,0xB4,0x01,0x94,0x00, + 0x4a,0x3C,0x17,0x04,0x9F,0x3F, + 0xD9,0x3C,0x10,0x3F,0x17,0x04 + } ; + + BYTE _CODE bCSCMtx_RGB2YUV_ITU709_0_255[] = + { + 0x10,0x80,0x10, + 0xEa,0x04,0x77,0x01,0x7F,0x00, + 0xD0,0x3C,0x83,0x03,0xAD,0x3F, + 0x4B,0x3D,0x32,0x3F,0x83,0x03 + } ; +#endif + +#if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV)) + + BYTE _CODE bCSCMtx_YUV2RGB_ITU601_16_235[] = + { + 0x00,0x00,0x00, + 0x00,0x08,0x6B,0x3A,0x50,0x3D, + 0x00,0x08,0xF5,0x0A,0x02,0x00, + 0x00,0x08,0xFD,0x3F,0xDA,0x0D + } ; + + BYTE _CODE bCSCMtx_YUV2RGB_ITU601_0_255[] = + { + 0x04,0x00,0xA7, + 0x4F,0x09,0x81,0x39,0xDD,0x3C, + 0x4F,0x09,0xC4,0x0C,0x01,0x00, + 0x4F,0x09,0xFD,0x3F,0x1F,0x10 + } ; + + BYTE _CODE bCSCMtx_YUV2RGB_ITU709_16_235[] = + { + 0x00,0x00,0x00, + 0x00,0x08,0x55,0x3C,0x88,0x3E, + 0x00,0x08,0x51,0x0C,0x00,0x00, + 0x00,0x08,0x00,0x00,0x84,0x0E + } ; + + BYTE _CODE bCSCMtx_YUV2RGB_ITU709_0_255[] = + { + 0x04,0x00,0xA7, + 0x4F,0x09,0xBA,0x3B,0x4B,0x3E, + 0x4F,0x09,0x57,0x0E,0x02,0x00, + 0x4F,0x09,0xFE,0x3F,0xE8,0x10 + } ; +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/debug.h b/drivers/video/rockchip/hdmi/chips/cat66121/debug.h new file mode 100755 index 000000000000..bff9fc228838 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/debug.h @@ -0,0 +1,106 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#ifndef _DEBUG_H_ +#define _DEBUG_H_ +#define Debug_message 1 + +#pragma message("debug.h") + +#ifndef Debug_message +#define Debug_message 1 +#endif + +#if Debug_message + + #define HDMITX_DEBUG_PRINTF(x) printk x + #define HDCP_DEBUG_PRINTF(x) printk x + #define EDID_DEBUG_PRINTF(x) printk x + #define HDMITX_DEBUG_INFO(x) printk x +#else + #define HDMITX_DEBUG_PRINTF(x) + #define HDCP_DEBUG_PRINTF(x) + #define EDID_DEBUG_PRINTF(x) + #define HDMITX_DEBUG_INFO(x) +#endif + + +#if( Debug_message & (1<<1)) + #define HDMITX_DEBUG_PRINTF1(x) printk x + #define HDCP_DEBUG_PRINTF1(x) printk x + #define EDID_DEBUG_PRINTF1(x) printk x +#else + #define HDMITX_DEBUG_PRINTF1(x) + #define HDCP_DEBUG_PRINTF1(x) + #define EDID_DEBUG_PRINTF1(x) +#endif + +#if( Debug_message & (1<<2)) + #define HDMITX_DEBUG_PRINTF2(x) printk x + #define HDCP_DEBUG_PRINTF2(x) printk x + #define EDID_DEBUG_PRINTF2(x) printk x +#else + #define HDMITX_DEBUG_PRINTF2(x) + #define HDCP_DEBUG_PRINTF2(x) + #define EDID_DEBUG_PRINTF2(x) +#endif + +#if( Debug_message & (1<<3)) + #define HDMITX_DEBUG_PRINTF3(x) printk x + #define HDCP_DEBUG_PRINTF3(x) printk x + #define EDID_DEBUG_PRINTF3(x) printk x +#else + #define HDMITX_DEBUG_PRINTF3(x) + #define HDCP_DEBUG_PRINTF3(x) + #define EDID_DEBUG_PRINTF3(x) +#endif + +#if( Debug_message & (1<<4)) + #define HDMITX_DEBUG_PRINTF4(x) printk x + #define HDCP_DEBUG_PRINTF4(x) printk x + #define EDID_DEBUG_PRINTF4(x) printk x +#else + #define HDMITX_DEBUG_PRINTF4(x) + #define HDCP_DEBUG_PRINTF4(x) + #define EDID_DEBUG_PRINTF4(x) +#endif + +#if( Debug_message & (1<<5)) + #define HDMITX_DEBUG_PRINTF5(x) printk x + #define HDCP_DEBUG_PRINTF5(x) printk x + #define EDID_DEBUG_PRINTF5(x) printk x +#else + #define HDMITX_DEBUG_PRINTF5(x) + #define HDCP_DEBUG_PRINTF5(x) + #define EDID_DEBUG_PRINTF5(x) +#endif + +#if( Debug_message & (1<<6)) + #define HDMITX_DEBUG_PRINTF6(x) printk x + #define HDCP_DEBUG_PRINTF6(x) printk x + #define EDID_DEBUG_PRINTF6(x) printk x +#else + #define HDMITX_DEBUG_PRINTF6(x) + #define HDCP_DEBUG_PRINTF6(x) + #define EDID_DEBUG_PRINTF6(x) +#endif + +#if( Debug_message & (1<<7)) + #define HDMITX_DEBUG_PRINTF7(x) printk x + #define HDCP_DEBUG_PRINTF7(x) printk x + #define EDID_DEBUG_PRINTF7(x) printk x +#else + #define HDMITX_DEBUG_PRINTF7(x) + #define HDCP_DEBUG_PRINTF7(x) + #define EDID_DEBUG_PRINTF7(x) +#endif + + +#endif// _DEBUG_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h new file mode 100755 index 000000000000..ec2670e1f431 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx.h @@ -0,0 +1,58 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +#ifndef _HDMITX_H_ +#define _HDMITX_H_ +#include +#include +#include +#include +#include + +#include "debug.h" +#include "config.h" +#include "typedef.h" +#include "hdmitx_drv.h" + +#define HDMITX_MAX_DEV_COUNT 1 + + +/////////////////////////////////////////////////////////////////////// +// Output Mode Type +/////////////////////////////////////////////////////////////////////// + +#define RES_ASPEC_4x3 0 +#define RES_ASPEC_16x9 1 +#define F_MODE_REPT_NO 0 +#define F_MODE_REPT_TWICE 1 +#define F_MODE_REPT_QUATRO 3 +#define F_MODE_CSC_ITU601 0 +#define F_MODE_CSC_ITU709 1 + + +#define TIMER_LOOP_LEN 10 +#define MS(x) (((x)+(TIMER_LOOP_LEN-1))/TIMER_LOOP_LEN); // for timer loop + +// #define SUPPORT_AUDI_AudSWL 16 // Jeilin case. +#define SUPPORT_AUDI_AudSWL 24 // Jeilin case. + +#if(SUPPORT_AUDI_AudSWL==16) + #define CHTSTS_SWCODE 0x02 +#elif(SUPPORT_AUDI_AudSWL==18) + #define CHTSTS_SWCODE 0x04 +#elif(SUPPORT_AUDI_AudSWL==20) + #define CHTSTS_SWCODE 0x03 +#else + #define CHTSTS_SWCODE 0x0B +#endif + +#endif // _HDMITX_H_ + diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c new file mode 100755 index 000000000000..37d7ae6ce98b --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.c @@ -0,0 +1,2594 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +///////////////////////////////////////////////////////////////////// +// HDMITX.C +// Driver code for platform independent +///////////////////////////////////////////////////////////////////// +#include "hdmitx.h" +#include "hdmitx_drv.h" +#define FALLING_EDGE_TRIGGER + +#define MSCOUNT 1000 +#define LOADING_UPDATE_TIMEOUT (3000/32) // 3sec +// USHORT u8msTimer = 0 ; +// USHORT TimerServF = TRUE ; + +////////////////////////////////////////////////////////////////////// +// Authentication status +////////////////////////////////////////////////////////////////////// + +// #define TIMEOUT_WAIT_AUTH MS(2000) + +HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; + +#ifndef INV_INPUT_PCLK +#define PCLKINV 0 +#else +#define PCLKINV B_TX_VDO_LATCH_EDGE +#endif + +#ifndef INV_INPUT_ACLK + #define InvAudCLK 0 +#else + #define InvAudCLK B_TX_AUDFMT_FALL_EDGE_SAMPLE_WS +#endif + +#define INIT_CLK_HIGH +// #define INIT_CLK_LOW + +_CODE RegSetEntry HDMITX_Init_Table[] = { + + {0x0F, 0x40, 0x00}, + + {0x62, 0x08, 0x00}, + {0x64, 0x04, 0x00}, + {0x01,0x00,0x00},//idle(100); + + {0x04, 0x20, 0x20}, + {0x04, 0x1D, 0x1D}, + {0x01,0x00,0x00},//idle(100); + {0x0F, 0x01, 0x00}, // bank 0 ; + #ifdef INIT_CLK_LOW + {0x62, 0x90, 0x10}, + {0x64, 0x89, 0x09}, + {0x68, 0x10, 0x10}, + #endif + + {0xD1, 0x0E, 0x0C}, + {0x65, 0x03, 0x00}, + #ifdef NON_SEQUENTIAL_YCBCR422 // for ITE HDMIRX + {0x71, 0xFC, 0x1C}, + #else + {0x71, 0xFC, 0x18}, + #endif + + {0x8D, 0xFF, CEC_I2C_SLAVE_ADDR}, + {0x0F, 0x08, 0x08}, + + {0xF8,0xFF,0xC3}, + {0xF8,0xFF,0xA5}, + {0x20, 0x80, 0x80}, + {0x37, 0x01, 0x00}, + {0x20, 0x80, 0x00}, + {0xF8,0xFF,0xFF}, + + {0x59, 0xD8, 0x40|PCLKINV}, + {0xE1, 0x20, InvAudCLK}, + {0x05, 0xC0, 0x40}, + {REG_TX_INT_MASK1, 0xFF, ~(B_TX_RXSEN_MASK|B_TX_HPD_MASK)}, + {REG_TX_INT_MASK2, 0xFF, ~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)}, + {REG_TX_INT_MASK3, 0xFF, ~(B_TX_VIDSTABLE_MASK)}, + {0x0C, 0xFF, 0xFF}, + {0x0D, 0xFF, 0xFF}, + {0x0E, 0x03, 0x03}, + + {0x0C, 0xFF, 0x00}, + {0x0D, 0xFF, 0x00}, + {0x0E, 0x02, 0x00}, + {0x09, 0x03, 0x00}, // Enable HPD and RxSen Interrupt + {0,0,0} +}; + +_CODE RegSetEntry HDMITX_DefaultVideo_Table[] = { + + //////////////////////////////////////////////////// + // Config default output format. + //////////////////////////////////////////////////// + {0x72, 0xff, 0x00}, + {0x70, 0xff, 0x00}, +#ifndef DEFAULT_INPUT_YCBCR +// GenCSC\RGB2YUV_ITU709_16_235.c + {0x72, 0xFF, 0x02}, + {0x73, 0xFF, 0x00}, + {0x74, 0xFF, 0x80}, + {0x75, 0xFF, 0x00}, + {0x76, 0xFF, 0xB8}, + {0x77, 0xFF, 0x05}, + {0x78, 0xFF, 0xB4}, + {0x79, 0xFF, 0x01}, + {0x7A, 0xFF, 0x93}, + {0x7B, 0xFF, 0x00}, + {0x7C, 0xFF, 0x49}, + {0x7D, 0xFF, 0x3C}, + {0x7E, 0xFF, 0x18}, + {0x7F, 0xFF, 0x04}, + {0x80, 0xFF, 0x9F}, + {0x81, 0xFF, 0x3F}, + {0x82, 0xFF, 0xD9}, + {0x83, 0xFF, 0x3C}, + {0x84, 0xFF, 0x10}, + {0x85, 0xFF, 0x3F}, + {0x86, 0xFF, 0x18}, + {0x87, 0xFF, 0x04}, +#else +// GenCSC\YUV2RGB_ITU709_16_235.c + {0x0F, 0x01, 0x00}, + {0x72, 0xFF, 0x03}, + {0x73, 0xFF, 0x00}, + {0x74, 0xFF, 0x80}, + {0x75, 0xFF, 0x00}, + {0x76, 0xFF, 0x00}, + {0x77, 0xFF, 0x08}, + {0x78, 0xFF, 0x53}, + {0x79, 0xFF, 0x3C}, + {0x7A, 0xFF, 0x89}, + {0x7B, 0xFF, 0x3E}, + {0x7C, 0xFF, 0x00}, + {0x7D, 0xFF, 0x08}, + {0x7E, 0xFF, 0x51}, + {0x7F, 0xFF, 0x0C}, + {0x80, 0xFF, 0x00}, + {0x81, 0xFF, 0x00}, + {0x82, 0xFF, 0x00}, + {0x83, 0xFF, 0x08}, + {0x84, 0xFF, 0x00}, + {0x85, 0xFF, 0x00}, + {0x86, 0xFF, 0x87}, + {0x87, 0xFF, 0x0E}, +#endif + // 2012/12/20 added by Keming's suggestion test + {0x88, 0xF0, 0x00}, + //~jauchih.tseng@ite.com.tw + {0x04, 0x08, 0x00}, + {0,0,0} +}; +_CODE RegSetEntry HDMITX_SetHDMI_Table[] = { + + //////////////////////////////////////////////////// + // Config default HDMI Mode + //////////////////////////////////////////////////// + {0xC0, 0x01, 0x01}, + {0xC1, 0x03, 0x03}, + {0xC6, 0x03, 0x03}, + {0,0,0} +}; + +_CODE RegSetEntry HDMITX_SetDVI_Table[] = { + + //////////////////////////////////////////////////// + // Config default HDMI Mode + //////////////////////////////////////////////////// + {0x0F, 0x01, 0x01}, + {0x58, 0xFF, 0x00}, + {0x0F, 0x01, 0x00}, + {0xC0, 0x01, 0x00}, + {0xC1, 0x03, 0x02}, + {0xC6, 0x03, 0x00}, + {0,0,0} +}; + +_CODE RegSetEntry HDMITX_DefaultAVIInfo_Table[] = { + + //////////////////////////////////////////////////// + // Config default avi infoframe + //////////////////////////////////////////////////// + {0x0F, 0x01, 0x01}, + {0x58, 0xFF, 0x10}, + {0x59, 0xFF, 0x08}, + {0x5A, 0xFF, 0x00}, + {0x5B, 0xFF, 0x00}, + {0x5C, 0xFF, 0x00}, + {0x5D, 0xFF, 0x57}, + {0x5E, 0xFF, 0x00}, + {0x5F, 0xFF, 0x00}, + {0x60, 0xFF, 0x00}, + {0x61, 0xFF, 0x00}, + {0x62, 0xFF, 0x00}, + {0x63, 0xFF, 0x00}, + {0x64, 0xFF, 0x00}, + {0x65, 0xFF, 0x00}, + {0x0F, 0x01, 0x00}, + {0xCD, 0x03, 0x03}, + {0,0,0} +}; +_CODE RegSetEntry HDMITX_DeaultAudioInfo_Table[] = { + + //////////////////////////////////////////////////// + // Config default audio infoframe + //////////////////////////////////////////////////// + {0x0F, 0x01, 0x01}, + {0x68, 0xFF, 0x00}, + {0x69, 0xFF, 0x00}, + {0x6A, 0xFF, 0x00}, + {0x6B, 0xFF, 0x00}, + {0x6C, 0xFF, 0x00}, + {0x6D, 0xFF, 0x71}, + {0x0F, 0x01, 0x00}, + {0xCE, 0x03, 0x03}, + + {0,0,0} +}; + +_CODE RegSetEntry HDMITX_Aud_CHStatus_LPCM_20bit_48Khz[] = +{ + {0x0F, 0x01, 0x01}, + {0x33, 0xFF, 0x00}, + {0x34, 0xFF, 0x18}, + {0x35, 0xFF, 0x00}, + {0x91, 0xFF, 0x00}, + {0x92, 0xFF, 0x00}, + {0x93, 0xFF, 0x01}, + {0x94, 0xFF, 0x00}, + {0x98, 0xFF, 0x02}, + {0x99, 0xFF, 0xDA}, + {0x0F, 0x01, 0x00}, + {0,0,0}//end of table +} ; + +_CODE RegSetEntry HDMITX_AUD_SPDIF_2ch_24bit[] = +{ + {0x0F, 0x11, 0x00}, + {0x04, 0x14, 0x04}, + {0xE0, 0xFF, 0xD1}, + {0xE1, 0xFF, 0x01}, + {0xE2, 0xFF, 0xE4}, + {0xE3, 0xFF, 0x10}, + {0xE4, 0xFF, 0x00}, + {0xE5, 0xFF, 0x00}, + {0x04, 0x14, 0x00}, + {0,0,0}//end of table +} ; + +_CODE RegSetEntry HDMITX_AUD_I2S_2ch_24bit[] = +{ + {0x0F, 0x11, 0x00}, + {0x04, 0x14, 0x04}, + {0xE0, 0xFF, 0xC1}, + {0xE1, 0xFF, 0x01}, + {0xE2, 0xFF, 0xE4}, + {0xE3, 0xFF, 0x00}, + {0xE4, 0xFF, 0x00}, + {0xE5, 0xFF, 0x00}, + {0x04, 0x14, 0x00}, + {0,0,0}//end of table +} ; + +_CODE RegSetEntry HDMITX_DefaultAudio_Table[] = { + + //////////////////////////////////////////////////// + // Config default audio output format. + //////////////////////////////////////////////////// + {0x0F, 0x21, 0x00}, + {0x04, 0x14, 0x04}, + {0xE0, 0xFF, 0xC1}, + {0xE1, 0xFF, 0x01}, + {0xE2, 0xFF, 0xE4}, + {0xE3, 0xFF, 0x00}, + {0xE4, 0xFF, 0x00}, + {0xE5, 0xFF, 0x00}, + {0x0F, 0x01, 0x01}, + {0x33, 0xFF, 0x00}, + {0x34, 0xFF, 0x18}, + {0x35, 0xFF, 0x00}, + {0x91, 0xFF, 0x00}, + {0x92, 0xFF, 0x00}, + {0x93, 0xFF, 0x01}, + {0x94, 0xFF, 0x00}, + {0x98, 0xFF, 0x02}, + {0x99, 0xFF, 0xDB}, + {0x0F, 0x01, 0x00}, + {0x04, 0x14, 0x00}, + + {0x00, 0x00, 0x00} // End of Table. +} ; + +_CODE RegSetEntry HDMITX_PwrDown_Table[] = { + // Enable GRCLK + {0x0F, 0x40, 0x00}, + // PLL Reset + {0x61, 0x10, 0x10}, // DRV_RST + {0x62, 0x08, 0x00}, // XP_RESETB + {0x64, 0x04, 0x00}, // IP_RESETB + {0x01, 0x00, 0x00}, // idle(100); + + // PLL PwrDn + {0x61, 0x20, 0x20}, // PwrDn DRV + {0x62, 0x44, 0x44}, // PwrDn XPLL + {0x64, 0x40, 0x40}, // PwrDn IPLL + + // HDMITX PwrDn + {0x05, 0x01, 0x01}, // PwrDn PCLK + {0x0F, 0x78, 0x78}, // PwrDn GRCLK + {0x00, 0x00, 0x00} // End of Table. +}; + +_CODE RegSetEntry HDMITX_PwrOn_Table[] = { + {0x0F, 0x78, 0x38}, // PwrOn GRCLK + {0x05, 0x01, 0x00}, // PwrOn PCLK + + // PLL PwrOn + {0x61, 0x20, 0x00}, // PwrOn DRV + {0x62, 0x44, 0x00}, // PwrOn XPLL + {0x64, 0x40, 0x00}, // PwrOn IPLL + + // PLL Reset OFF + {0x61, 0x10, 0x00}, // DRV_RST + {0x62, 0x08, 0x08}, // XP_RESETB + {0x64, 0x04, 0x04}, // IP_RESETB + {0x0F, 0x78, 0x08}, // PwrOn IACLK + {0x00, 0x00, 0x00} // End of Table. +}; + +#ifdef DETECT_VSYNC_CHG_IN_SAV +BOOL EnSavVSync = FALSE ; +#endif + +////////////////////////////////////////////////////////////////////// +// Function Prototype +////////////////////////////////////////////////////////////////////// +void hdmitx_LoadRegSetting(RegSetEntry table[]); + +void HDMITX_InitTxDev(HDMITXDEV *pInstance) +{ + if(pInstance && 0 < HDMITX_MAX_DEV_COUNT) + { + hdmiTxDev[0] = *pInstance ; + } +} + +void InitHDMITX() +{ + hdmitx_LoadRegSetting(HDMITX_Init_Table); + HDMITX_WriteI2C_Byte(REG_TX_PLL_CTRL,0xff); + hdmiTxDev[0].bIntPOL = (hdmiTxDev[0].bIntType&B_TX_INTPOL_ACTH)?TRUE:FALSE ; + + // Avoid power loading in un play status. + ////////////////////////////////////////////////////////////////// + // Setup HDCP ROM + ////////////////////////////////////////////////////////////////// +#ifdef HDMITX_INPUT_INFO + hdmiTxDev[0].RCLK = CalcRCLK(); +#endif + hdmitx_LoadRegSetting(HDMITX_DefaultVideo_Table); + hdmitx_LoadRegSetting(HDMITX_SetHDMI_Table); + hdmitx_LoadRegSetting(HDMITX_DefaultAVIInfo_Table); + hdmitx_LoadRegSetting(HDMITX_DeaultAudioInfo_Table); + hdmitx_LoadRegSetting(HDMITX_Aud_CHStatus_LPCM_20bit_48Khz); + hdmitx_LoadRegSetting(HDMITX_AUD_SPDIF_2ch_24bit); + + HDMITX_DEBUG_PRINTF(( + "-----------------------------------------------------\n" + "Init HDMITX\n" + "-----------------------------------------------------\n")); + + DumpHDMITXReg(); +} + +BOOL getHDMITX_LinkStatus() +{ + if(B_TX_RXSENDETECT & HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS)) + { + if(0==HDMITX_ReadI2C_Byte(REG_TX_AFE_DRV_CTRL)) + { + //HDMITX_DEBUG_PRINTF(("getHDMITX_LinkStatus()!!\n") ); + return TRUE; + } + } + //HDMITX_DEBUG_PRINTF(("GetTMDS not Ready()!!\n") ); + + return FALSE; +} + +BYTE CheckHDMITX(BYTE *pHPD,BYTE *pHPDChange) +{ + BYTE intdata1,intdata2,intdata3,sysstat; + BYTE intclr3 = 0 ; + BYTE PrevHPD = hdmiTxDev[0].bHPD ; + BYTE HPD ; + sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); + // HDMITX_DEBUG_PRINTF(("REG_TX_SYS_STATUS = %X \n",sysstat)); + + if((sysstat & (B_TX_HPDETECT/*|B_TX_RXSENDETECT*/)) == (B_TX_HPDETECT/*|B_TX_RXSENDETECT*/)) + { + HPD = TRUE; + } + else + { + HPD = FALSE; + } + // CheckClockStable(sysstat); + // 2007/06/20 added by jj_tseng@chipadvanced.com + + if(pHPDChange) + { + *pHPDChange = (HPD!=PrevHPD)?TRUE:FALSE ; // default give pHPDChange value compared to previous HPD value. + + } + //~jj_tseng@chipadvanced.com 2007/06/20 + + if(HPD==FALSE) + { + hdmiTxDev[0].bAuthenticated = FALSE ; + } + if(sysstat & B_TX_INT_ACTIVE) + { + HDMITX_DEBUG_PRINTF(("REG_TX_SYS_STATUS = 0x%02X \n",(int)sysstat)); + + intdata1 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1); + HDMITX_DEBUG_PRINTF(("INT_Handler: reg%X = %X\n",(int)REG_TX_INT_STAT1,(int)intdata1)); + if(intdata1 & B_TX_INT_AUD_OVERFLOW) + { + HDMITX_DEBUG_PRINTF(("B_TX_INT_AUD_OVERFLOW.\n")); + HDMITX_OrReg_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST)); + HDMITX_AndReg_Byte(REG_TX_SW_RST,~(B_HDMITX_AUD_RST|B_TX_AREF_RST)); + //AudioDelayCnt=AudioOutDelayCnt; + //LastRefaudfreqnum=0; + } + if(intdata1 & B_TX_INT_DDCFIFO_ERR) + { + HDMITX_DEBUG_PRINTF(("DDC FIFO Error.\n")); + hdmitx_ClearDDCFIFO(); + hdmiTxDev[0].bAuthenticated= FALSE ; + } + if(intdata1 & B_TX_INT_DDC_BUS_HANG) + { + HDMITX_DEBUG_PRINTF(("DDC BUS HANG.\n")); + hdmitx_AbortDDC(); + + if(hdmiTxDev[0].bAuthenticated) + { + HDMITX_DEBUG_PRINTF(("when DDC hang,and aborted DDC,the HDCP authentication need to restart.\n")); + #ifdef SUPPORT_HDCP + hdmitx_hdcp_ResumeAuthentication(); + #endif + } + } + if(intdata1 & (B_TX_INT_HPD_PLUG/*|B_TX_INT_RX_SENSE*/)) + { + + if(pHPDChange) + { + *pHPDChange = TRUE ; + } + if(HPD == FALSE) + { + /* + HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_TX_AREF_RST|B_HDMITX_VID_RST|B_HDMITX_AUD_RST|B_TX_HDCP_RST_HDMITX); + delay1ms(1); + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); + */ + //HDMITX_DEBUG_PRINTF(("Unplug,%x %x\n",(int)HDMITX_ReadI2C_Byte(REG_TX_SW_RST),(int)HDMITX_ReadI2C_Byte(REG_TX_AFE_DRV_CTRL))); + } + } + if(intdata1 & (B_TX_INT_RX_SENSE)) + { + hdmiTxDev[0].bAuthenticated = FALSE; + } + intdata2 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); + HDMITX_DEBUG_PRINTF(("INT_Handler: reg%X = %X\n",(int)REG_TX_INT_STAT2,(int)intdata2)); + + #ifdef SUPPORT_HDCP + if(intdata2 & B_TX_INT_AUTH_DONE) + { + HDMITX_DEBUG_PRINTF(("interrupt Authenticate Done.\n")); + HDMITX_OrReg_Byte(REG_TX_INT_MASK2,(BYTE)B_TX_AUTH_DONE_MASK); + //hdmiTxDev[0].bAuthenticated = TRUE ; + //setHDMITX_AVMute(FALSE); + } + if(intdata2 & B_TX_INT_AUTH_FAIL) + { + hdmiTxDev[0].bAuthenticated = FALSE; + //HDMITX_DEBUG_PRINTF(("interrupt Authenticate Fail.\n")); + hdmitx_AbortDDC(); // @emily add + //hdmitx_hdcp_ResumeAuthentication(); + } + #endif // SUPPORT_HDCP + + /* + intdata3 = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT3); + if(intdata3 & B_TX_INT_VIDSTABLE) + { + sysstat = HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS); + if(sysstat & B_TXVIDSTABLE) + { + hdmitx_FireAFE(); + } + } + */ + intdata3= HDMITX_ReadI2C_Byte(0xEE); + if( intdata3 ) + { + HDMITX_WriteI2C_Byte(0xEE,intdata3); // clear ext interrupt ; + HDMITX_DEBUG_PRINTF(("%s%s%s%s%s%s%s\n", + (intdata3&0x40)?"video parameter change ":"", + (intdata3&0x20)?"HDCP Pj check done ":"", + (intdata3&0x10)?"HDCP Ri check done ":"", + (intdata3&0x8)? "DDC bus hang ":"", + (intdata3&0x4)? "Video input FIFO auto reset ":"", + (intdata3&0x2)? "No audio input interrupt ":"", + (intdata3&0x1)? "Audio decode error interrupt ":"")); + } + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,0xFF); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0xFF); + intclr3 = (HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS))|B_TX_CLR_AUD_CTS | B_TX_INTACTDONE ; + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // clear interrupt. + intclr3 &= ~(B_TX_INTACTDONE); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,intclr3); // INTACTDONE reset to zero. + } + // + // else + // { + // if(pHPDChange) + // { + // if(HPD != PrevHPD) + // { + // *pHPDChange = TRUE; + // } + // else + // { + // *pHPDChange = FALSE; + // } + // } + // } + if(pHPDChange) + { + if((*pHPDChange==TRUE) &&(HPD==FALSE)) + { + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); + } + } + if(pHPD) + { + *pHPD = HPD ; + } + hdmiTxDev[0].bHPD = HPD ; + return HPD ; +} + +void HDMITX_PowerOn() +{ + hdmitx_LoadRegSetting(HDMITX_PwrOn_Table); +} + +void HDMITX_PowerDown() +{ + hdmitx_LoadRegSetting(HDMITX_PwrDown_Table); +} + +void setHDMITX_AVMute(BYTE bEnable) +{ + Switch_HDMITX_Bank(0); + HDMITX_SetI2C_Byte(REG_TX_GCP,B_TX_SETAVMUTE, bEnable?B_TX_SETAVMUTE:0 ); + HDMITX_WriteI2C_Byte(REG_TX_PKT_GENERAL_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_LoadRegSetting() +// Input: RegSetEntry SettingTable[] ; +// Return: N/A +// Remark: if an entry {0, 0, 0} will be terminated. +////////////////////////////////////////////////////////////////////// + +void hdmitx_LoadRegSetting(RegSetEntry table[]) +{ + int i ; + + for( i = 0 ; ; i++ ) + { + if( table[i].offset == 0 && table[i].invAndMask == 0 && table[i].OrMask == 0 ) + { + return ; + } + else if( table[i].invAndMask == 0 && table[i].OrMask == 0 ) + { + HDMITX_DEBUG_PRINTF2(("delay(%d)\n",(int)table[i].offset)); + delay1ms(table[i].offset); + } + else if( table[i].invAndMask == 0xFF ) + { + HDMITX_DEBUG_PRINTF2(("HDMITX_WriteI2C_Byte(%02x,%02x)\n",(int)table[i].offset,(int)table[i].OrMask)); + HDMITX_WriteI2C_Byte(table[i].offset,table[i].OrMask); + } + else + { + HDMITX_DEBUG_PRINTF2(("HDMITX_SetI2C_Byte(%02x,%02x,%02x)\n",(int)table[i].offset,(int)table[i].invAndMask,(int)table[i].OrMask)); + HDMITX_SetI2C_Byte(table[i].offset,table[i].invAndMask,table[i].OrMask); + } + } +} + +///***************************************** +// @file +//******************************************/ + +BOOL getHDMITX_EDIDBlock(int EDIDBlockID,BYTE *pEDIDData) +{ + if(!pEDIDData) + { + return FALSE ; + } + if(getHDMITX_EDIDBytes(pEDIDData,EDIDBlockID/2,(EDIDBlockID%2)*128,128) == ER_FAIL) + { + return FALSE ; + } + return TRUE ; +} + +////////////////////////////////////////////////////////////////////// +// Function: getHDMITX_EDIDBytes +// Parameter: pData - the pointer of buffer to receive EDID ucdata. +// bSegment - the segment of EDID readback. +// offset - the offset of EDID ucdata in the segment. in byte. +// count - the read back bytes count,cannot exceed 32 +// Return: ER_SUCCESS if successfully getting EDID. ER_FAIL otherwise. +// Remark: function for read EDID ucdata from reciever. +// Side-Effect: DDC master will set to be HOST. DDC FIFO will be used and dirty. +////////////////////////////////////////////////////////////////////// + +SYS_STATUS getHDMITX_EDIDBytes(BYTE *pData,BYTE bSegment,BYTE offset,SHORT Count) +{ + SHORT RemainedCount,ReqCount ; + BYTE bCurrOffset ; + SHORT TimeOut ; + BYTE *pBuff = pData ; + BYTE ucdata ; + + // HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(%08lX,%d,%d,%d)\n",(ULONG)pData,(int)bSegment,(int)offset,(int)Count)); + if(!pData) + { +// HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): Invallid pData pointer %08lX\n",(ULONG)pData)); + return ER_FAIL ; + } + if(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG) + { + HDMITX_DEBUG_PRINTF(("Called hdmitx_AboutDDC()\n")); + hdmitx_AbortDDC(); + + } + // HDMITX_OrReg_Byte(REG_TX_INT_CTRL,(1<<1)); + + hdmitx_ClearDDCFIFO(); + + RemainedCount = Count ; + bCurrOffset = offset ; + + Switch_HDMITX_Bank(0); + + while(RemainedCount > 0) + { + + ReqCount = (RemainedCount > DDC_FIFO_MAXREQ)?DDC_FIFO_MAXREQ:RemainedCount ; + HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): ReqCount = %d,bCurrOffset = %d\n",(int)ReqCount,(int)bCurrOffset)); + + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_FIFO_CLR); + + for(TimeOut = 0 ; TimeOut < 200 ; TimeOut++) + { + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + + if(ucdata&B_TX_DDC_DONE) + { + break ; + } + if((ucdata & B_TX_DDC_ERROR)||(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG)) + { + HDMITX_DEBUG_PRINTF(("Called hdmitx_AboutDDC()\n")); + hdmitx_AbortDDC(); + return ER_FAIL ; + } + } + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_EDID_ADDRESS); // for EDID ucdata get + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,bCurrOffset); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,(BYTE)ReqCount); + HDMITX_WriteI2C_Byte(REG_TX_DDC_EDIDSEG,bSegment); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_EDID_READ); + + bCurrOffset += ReqCount ; + RemainedCount -= ReqCount ; + + for(TimeOut = 250 ; TimeOut > 0 ; TimeOut --) + { + delay1ms(1); + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + if(ucdata & B_TX_DDC_DONE) + { + break ; + } + if(ucdata & B_TX_DDC_ERROR) + { + HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): DDC_STATUS = %02X,fail.\n",(int)ucdata)); + // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); + return ER_FAIL ; + } + } + if(TimeOut == 0) + { + HDMITX_DEBUG_PRINTF(("getHDMITX_EDIDBytes(): DDC TimeOut. \n",(int)ucdata)); + // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); + return ER_FAIL ; + } + do + { + *(pBuff++) = HDMITX_ReadI2C_Byte(REG_TX_DDC_READFIFO); + ReqCount -- ; + }while(ReqCount > 0); + + } + // HDMITX_AndReg_Byte(REG_TX_INT_CTRL,~(1<<1)); + return ER_SUCCESS ; +} + +///////////////////////////// +// DDC Function. +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_ClearDDCFIFO +// Parameter: N/A +// Return: N/A +// Remark: clear the DDC FIFO. +// Side-Effect: DDC master will set to be HOST. +////////////////////////////////////////////////////////////////////// + +void hdmitx_ClearDDCFIFO() +{ + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_FIFO_CLR); +} + +void hdmitx_GenerateDDCSCLK() +{ + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_GEN_SCLCLK); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_AbortDDC +// Parameter: N/A +// Return: N/A +// Remark: Force abort DDC and reset DDC bus. +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +void hdmitx_AbortDDC() +{ + BYTE CPDesire,SWReset,DDCMaster ; + BYTE uc, timeout, i ; + // save the SW reset,DDC master,and CP Desire setting. + SWReset = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); + CPDesire = HDMITX_ReadI2C_Byte(REG_TX_HDCP_DESIRE); + DDCMaster = HDMITX_ReadI2C_Byte(REG_TX_DDC_MASTER_CTRL); + + HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,CPDesire&(~B_TX_CPDESIRE)); // @emily change order + HDMITX_WriteI2C_Byte(REG_TX_SW_RST,SWReset|B_TX_HDCP_RST_HDMITX); // @emily change order + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + + // 2009/01/15 modified by Jau-Chih.Tseng@ite.com.tw + // do abort DDC twice. + for( i = 0 ; i < 2 ; i++ ) + { + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_ABORT); + + for( timeout = 0 ; timeout < 200 ; timeout++ ) + { + uc = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + if (uc&B_TX_DDC_DONE) + { + break ; // success + } + if( uc & (B_TX_DDC_NOACK|B_TX_DDC_WAITBUS|B_TX_DDC_ARBILOSE) ) + { +// HDMITX_DEBUG_PRINTF(("hdmitx_AbortDDC Fail by reg16=%02X\n",(int)uc)); + break ; + } + delay1ms(1); // delay 1 ms to stable. + } + } + //~Jau-Chih.Tseng@ite.com.tw + +} + +///***************************************** +// @file +//******************************************/ + +extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; + +void WaitTxVidStable(); +void hdmitx_SetInputMode(BYTE InputMode,BYTE bInputSignalType); +void hdmitx_SetCSCScale(BYTE bInputMode,BYTE bOutputMode); +void hdmitx_SetupAFE(VIDEOPCLKLEVEL PCLKLevel); +void hdmitx_FireAFE(); + +////////////////////////////////////////////////////////////////////// +// utility function for main.. +////////////////////////////////////////////////////////////////////// + +#ifndef DISABLE_HDMITX_CSC + #if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB)) + extern _CODE BYTE bCSCMtx_RGB2YUV_ITU601_16_235[] ; + extern _CODE BYTE bCSCMtx_RGB2YUV_ITU601_0_255[] ; + extern _CODE BYTE bCSCMtx_RGB2YUV_ITU709_16_235[] ; + extern _CODE BYTE bCSCMtx_RGB2YUV_ITU709_0_255[] ; + #endif + + #if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV)) + extern _CODE BYTE bCSCMtx_YUV2RGB_ITU601_16_235[] ; + extern _CODE BYTE bCSCMtx_YUV2RGB_ITU601_0_255[] ; + extern _CODE BYTE bCSCMtx_YUV2RGB_ITU709_16_235[] ; + extern _CODE BYTE bCSCMtx_YUV2RGB_ITU709_0_255[] ; + + #endif +#endif// DISABLE_HDMITX_CSC + +////////////////////////////////////////////////////////////////////// +// Function Body. +////////////////////////////////////////////////////////////////////// + +void HDMITX_DisableVideoOutput() +{ + BYTE uc = HDMITX_ReadI2C_Byte(REG_TX_SW_RST) | B_HDMITX_VID_RST ; + HDMITX_WriteI2C_Byte(REG_TX_SW_RST,uc); + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD); + HDMITX_SetI2C_Byte(0x62, 0x90, 0x00); + HDMITX_SetI2C_Byte(0x64, 0x89, 0x00); +} + +BOOL HDMITX_EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) +{ + // bInputVideoMode,bOutputVideoMode,hdmiTxDev[0].bInputVideoSignalType,bAudioInputType,should be configured by upper F/W or loaded from EEPROM. + // should be configured by initsys.c + // VIDEOPCLKLEVEL level ; + + HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_HDMITX_VID_RST|B_HDMITX_AUD_RST|B_TX_AREF_RST|B_TX_HDCP_RST_HDMITX); + + hdmiTxDev[0].bHDMIMode = (BYTE)bHDMI ; + // 2009/12/09 added by jau-chih.tseng@ite.com.tw + Switch_HDMITX_Bank(1); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB1,0x00); + Switch_HDMITX_Bank(0); + //~jau-chih.tseng@ite.com.tw + + if(hdmiTxDev[0].bHDMIMode) + { + setHDMITX_AVMute(TRUE); + } + hdmitx_SetInputMode(inputColorMode,hdmiTxDev[0].bInputVideoSignalType); + + hdmitx_SetCSCScale(inputColorMode,outputColorMode); + + if(hdmiTxDev[0].bHDMIMode) + { + HDMITX_WriteI2C_Byte(REG_TX_HDMI_MODE,B_TX_HDMI_MODE); + } + else + { + HDMITX_WriteI2C_Byte(REG_TX_HDMI_MODE,B_TX_DVI_MODE); + } +#ifdef INVERT_VID_LATCHEDGE + uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); + uc |= B_TX_VDO_LATCH_EDGE ; + HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); +#endif + + hdmitx_SetupAFE(level); // pass if High Freq request + HDMITX_WriteI2C_Byte(REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST|B_TX_HDCP_RST_HDMITX); + + hdmitx_FireAFE(); + + return TRUE ; +} + +////////////////////////////////////////////////////////////////////// +// export this for dynamic change input signal +////////////////////////////////////////////////////////////////////// +BOOL setHDMITX_VideoSignalType(BYTE inputSignalType) +{ + hdmiTxDev[0].bInputVideoSignalType = inputSignalType ; + // hdmitx_SetInputMode(inputColorMode,hdmiTxDev[0].bInputVideoSignalType); + return TRUE ; +} + +void WaitTxVidStable() +{ +#if 0 + BYTE i ; + for( i = 0 ; i < 20 ; i++ ) + { + delay1ms(15); + if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) + { + continue ; + } + delay1ms(15); + if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) + { + continue ; + } + delay1ms(15); + if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) + { + continue ; + } + delay1ms(15); + if((HDMITX_ReadI2C_Byte(REG_TX_SYS_STATUS) & B_TXVIDSTABLE) == 0 ) + { + continue ; + } + break ; + } +#endif +} +// void CheckClockStable(BYTE SystemStat) +// { +// static BYTE Stablecnt=20; +// if(0==(SystemStat&B_TXVIDSTABLE)) +// { +// if(0==Stablecnt--) +// { +// HDMITX_ToggleBit(0x59,3); +// Stablecnt=20; +// } +// } +// else +// { +// Stablecnt=20; +// } +// } + +void setHDMITX_ColorDepthPhase(BYTE ColorDepth,BYTE bPhase) +{ +#ifdef IT6615 + BYTE uc ; + BYTE bColorDepth ; + + if(ColorDepth == 30) + { + bColorDepth = B_TX_CD_30 ; + HDMITX_DEBUG_PRINTF(("bColorDepth = B_TX_CD_30\n")); + } + else if (ColorDepth == 36) + { + bColorDepth = B_TX_CD_36 ; + HDMITX_DEBUG_PRINTF(("bColorDepth = B_TX_CD_36\n")); + } + /* + else if (ColorDepth == 24) + { + bColorDepth = B_TX_CD_24 ; + //bColorDepth = 0 ;//modify JJ by mail 20100423 1800 // not indicated + } + */ + else + { + bColorDepth = 0 ; // not indicated + } + Switch_HDMITX_Bank(0); + HDMITX_SetI2C_Byte(REG_TX_GCP,B_TX_COLOR_DEPTH_MASK ,bColorDepth); + HDMITX_DEBUG_PRINTF(("setHDMITX_ColorDepthPhase(%02X), regC1 = %02X\n",(int)bColorDepth,(int)HDMITX_ReadI2C_Byte(REG_TX_GCP))) ; +#endif +} + +#ifdef SUPPORT_SYNCEMBEDDED + +struct CRT_TimingSetting { + BYTE fmt; + WORD HActive; + WORD VActive; + WORD HTotal; + WORD VTotal; + WORD H_FBH; + WORD H_SyncW; + WORD H_BBH; + WORD V_FBH; + WORD V_SyncW; + WORD V_BBH; + BYTE Scan:1; + BYTE VPolarity:1; + BYTE HPolarity:1; +}; + +// VDEE_L, VDEE_H, VRS2S_L, VRS2S_H, VRS2E_L, VRS2E_H, HalfL_L, HalfL_H, VDE2S_L, VDE2S_H, HVP&Progress +_CODE struct CRT_TimingSetting TimingTable[] = +{ + // VIC H V HTotal VTotal HFT HSW HBP VF VSW VB + { 1, 640, 480, 800, 525, 16, 96, 48, 10, 2, 33, PROG, Vneg, Hneg},// 640x480@60Hz - CEA Mode [ 1] + { 2, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@60Hz - CEA Mode [ 2] + { 3, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@60Hz - CEA Mode [ 3] + { 4, 1280, 720, 1650, 750, 110, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@60Hz - CEA Mode [ 4] + { 5, 1920, 540, 2200, 562, 88, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@60Hz - CEA Mode [ 5] + { 6, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 6] + { 7, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 7] + // { 8, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 8] + // { 9, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [ 9] + // { 10, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [10] + // { 11, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [11] + // { 12, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [12] + // { 13, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, PROG, Vneg, Hneg},// 720x480(I)@60Hz - CEA Mode [13] + // { 14, 1440, 480, 1716, 525, 32, 124, 120, 9, 6, 30, PROG, Vneg, Hneg},// 1440x480@60Hz - CEA Mode [14] + // { 15, 1440, 480, 1716, 525, 32, 124, 120, 9, 6, 30, PROG, Vneg, Hneg},// 1440x480@60Hz - CEA Mode [15] + { 16, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@60Hz - CEA Mode [16] + { 17, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@50Hz - CEA Mode [17] + { 18, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@50Hz - CEA Mode [18] + { 19, 1280, 720, 1980, 750, 440, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@50Hz - CEA Mode [19] + { 20, 1920, 540, 2640, 562, 528, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@50Hz - CEA Mode [20] + { 21, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [21] + { 22, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [22] + // { 23, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [23] + // { 24, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [24] + // { 25, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [25] + // { 26, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@50Hz - CEA Mode [26] + // { 27, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [27] + // { 28, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, PROG, Vneg, Hneg},// 1440x288@50Hz - CEA Mode [28] + // { 29, 1440, 576, 1728, 625, 24, 128, 136, 5, 5, 39, PROG, Vpos, Hneg},// 1440x576@50Hz - CEA Mode [29] + // { 30, 1440, 576, 1728, 625, 24, 128, 136, 5, 5, 39, PROG, Vpos, Hneg},// 1440x576@50Hz - CEA Mode [30] + { 31, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@50Hz - CEA Mode [31] + { 32, 1920, 1080, 2750, 1125, 638, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@24Hz - CEA Mode [32] + { 33, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@25Hz - CEA Mode [33] + { 34, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@30Hz - CEA Mode [34] + // { 35, 2880, 480, 1716*2, 525, 32*2, 124*2, 120*2, 9, 6, 30, PROG, Vneg, Hneg},// 2880x480@60Hz - CEA Mode [35] + // { 36, 2880, 480, 1716*2, 525, 32*2, 124*2, 120*2, 9, 6, 30, PROG, Vneg, Hneg},// 2880x480@60Hz - CEA Mode [36] + // { 37, 2880, 576, 3456, 625, 24*2, 128*2, 136*2, 5, 5, 39, PROG, Vneg, Hneg},// 2880x576@50Hz - CEA Mode [37] + // { 38, 2880, 576, 3456, 625, 24*2, 128*2, 136*2, 5, 5, 39, PROG, Vneg, Hneg},// 2880x576@50Hz - CEA Mode [38] + // { 39, 1920, 540, 2304, 625, 32, 168, 184, 23, 5, 57, INTERLACE, Vneg, Hpos},// 1920x1080@50Hz - CEA Mode [39] + // { 40, 1920, 540, 2640, 562, 528, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@100Hz - CEA Mode [40] + // { 41, 1280, 720, 1980, 750, 440, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@100Hz - CEA Mode [41] + // { 42, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@100Hz - CEA Mode [42] + // { 43, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@100Hz - CEA Mode [43] + // { 44, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@100Hz - CEA Mode [44] + // { 45, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@100Hz - CEA Mode [45] + // { 46, 1920, 540, 2200, 562, 88, 44, 148, 2, 5, 15, INTERLACE, Vpos, Hpos},// 1920x1080(I)@120Hz - CEA Mode [46] + // { 47, 1280, 720, 1650, 750, 110, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@120Hz - CEA Mode [47] + // { 48, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [48] + // { 49, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [49] + // { 50, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [50] + // { 51, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [51] + // { 52, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@200Hz - CEA Mode [52] + // { 53, 720, 576, 864, 625, 12, 64, 68, 5, 5, 39, PROG, Vneg, Hneg},// 720x576@200Hz - CEA Mode [53] + // { 54, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@200Hz - CEA Mode [54] + // { 55, 720, 288, 864, 312, 12, 63, 69, 2, 3, 19, INTERLACE, Vneg, Hneg},// 1440x576(I)@200Hz - CEA Mode [55] + // { 56, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [56] + // { 57, 720, 480, 858, 525, 16, 62, 60, 9, 6, 30, PROG, Vneg, Hneg},// 720x480@120Hz - CEA Mode [57] + // { 58, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [58] + // { 59, 720, 240, 858, 262, 19, 62, 57, 4, 3, 15, INTERLACE, Vneg, Hneg},// 720x480(I)@120Hz - CEA Mode [59] + { 60, 1280, 720, 3300, 750, 1760, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@24Hz - CEA Mode [60] + { 61, 1280, 720, 3960, 750, 2420, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@25Hz - CEA Mode [61] + { 62, 1280, 720, 3300, 750, 1760, 40, 220, 5, 5, 20, PROG, Vpos, Hpos},// 1280x720@30Hz - CEA Mode [62] + // { 63, 1920, 1080, 2200, 1125, 88, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@120Hz - CEA Mode [63] + // { 64, 1920, 1080, 2640, 1125, 528, 44, 148, 4, 5, 36, PROG, Vpos, Hpos},// 1920x1080@100Hz - CEA Mode [64] +}; + +#define MaxIndex (sizeof(TimingTable)/sizeof(struct CRT_TimingSetting)) +BOOL setHDMITX_SyncEmbeddedByVIC(BYTE VIC,BYTE bInputType) +{ + int i ; + BYTE fmt_index=0; + + // if Embedded Video,need to generate timing with pattern register + Switch_HDMITX_Bank(0); + + HDMITX_DEBUG_PRINTF(("setHDMITX_SyncEmbeddedByVIC(%d,%x)\n",(int)VIC,(int)bInputType)); + if( VIC > 0 ) + { + for(i=0;i< MaxIndex;i ++) + { + if(TimingTable[i].fmt==VIC) + { + fmt_index=i; + HDMITX_DEBUG_PRINTF(("fmt_index=%02x)\n",(int)fmt_index)); + HDMITX_DEBUG_PRINTF(("***Fine Match Table ***\n")); + break; + } + } + } + else + { + HDMITX_DEBUG_PRINTF(("***No Match VIC == 0 ***\n")); + return FALSE ; + } + + if(i>=MaxIndex) + { + //return FALSE; + HDMITX_DEBUG_PRINTF(("***No Match VIC ***\n")); + return FALSE ; + } + //if( bInputSignalType & T_MODE_SYNCEMB ) + { + int HTotal, HDES, VTotal, VDES; + int HDEW, VDEW, HFP, HSW, VFP, VSW; + int HRS, HRE; + int VRS, VRE; + int H2ndVRRise; + int VRS2nd, VRE2nd; + BYTE Pol; + + HTotal =TimingTable[fmt_index].HTotal; + HDEW =TimingTable[fmt_index].HActive; + HFP =TimingTable[fmt_index].H_FBH; + HSW =TimingTable[fmt_index].H_SyncW; + HDES =HSW+TimingTable[fmt_index].H_BBH; + VTotal =TimingTable[fmt_index].VTotal; + VDEW =TimingTable[fmt_index].VActive; + VFP =TimingTable[fmt_index].V_FBH; + VSW =TimingTable[fmt_index].V_SyncW; + VDES =VSW+TimingTable[fmt_index].V_BBH; + + Pol = (TimingTable[fmt_index].HPolarity==Hpos)?(1<<1):0 ; + Pol |= (TimingTable[fmt_index].VPolarity==Vpos)?(1<<2):0 ; + + // SyncEmb case===== + if( bInputType & T_MODE_CCIR656) + { + HRS = HFP - 1; + } + else + { + HRS = HFP - 2; + /* + if(VIC==HDMI_1080p60 || + VIC==HDMI_1080p50 ) + { + HDMITX_OrReg_Byte(0x59, (1<<3)); + } + else + { + HDMITX_AndReg_Byte(0x59, ~(1<<3)); + } + */ + } + HRE = HRS + HSW; + H2ndVRRise = HRS+ HTotal/2; + + VRS = VFP; + VRE = VRS + VSW; + + // VTotal>>=1; + + if(PROG == TimingTable[fmt_index].Scan) + { // progressive mode + VRS2nd = 0xFFF; + VRE2nd = 0x3F; + } + else + { // interlaced mode + if(39 == TimingTable[fmt_index].fmt) + { + VRS2nd = VRS + VTotal - 1; + VRE2nd = VRS2nd + VSW; + } + else + { + VRS2nd = VRS + VTotal; + VRE2nd = VRS2nd + VSW; + } + } + #ifdef DETECT_VSYNC_CHG_IN_SAV + if( EnSavVSync ) + { + VRS -= 1; + VRE -= 1; + if( !pSetVTiming->ScanMode ) // interlaced mode + { + VRS2nd -= 1; + VRE2nd -= 1; + } + } + #endif // DETECT_VSYNC_CHG_IN_SAV + HDMITX_SetI2C_Byte(0x90, 0x06, Pol); + // write H2ndVRRise + HDMITX_SetI2C_Byte(0x90, 0xF0, (H2ndVRRise&0x0F)<<4); + HDMITX_WriteI2C_Byte(0x91, (H2ndVRRise&0x0FF0)>>4); + // write HRS/HRE + HDMITX_WriteI2C_Byte(0x95, HRS&0xFF); + HDMITX_WriteI2C_Byte(0x96, HRE&0xFF); + HDMITX_WriteI2C_Byte(0x97, ((HRE&0x0F00)>>4)+((HRS&0x0F00)>>8)); + // write VRS/VRE + HDMITX_WriteI2C_Byte(0xa0, VRS&0xFF); + HDMITX_WriteI2C_Byte(0xa1, ((VRE&0x0F)<<4)+((VRS&0x0F00)>>8)); + HDMITX_WriteI2C_Byte(0xa2, VRS2nd&0xFF); + HDMITX_WriteI2C_Byte(0xa6, (VRE2nd&0xF0)+((VRE&0xF0)>>4)); + HDMITX_WriteI2C_Byte(0xa3, ((VRE2nd&0x0F)<<4)+((VRS2nd&0xF00)>>8)); + HDMITX_WriteI2C_Byte(0xa4, H2ndVRRise&0xFF); + HDMITX_WriteI2C_Byte(0xa5, (/*EnDEOnly*/0<<5)+((TimingTable[fmt_index].Scan==INTERLACE)?(1<<4):0)+((H2ndVRRise&0xF00)>>8)); + HDMITX_SetI2C_Byte(0xb1, 0x51, ((HRE&0x1000)>>6)+((HRS&0x1000)>>8)+((HDES&0x1000)>>12)); + HDMITX_SetI2C_Byte(0xb2, 0x05, ((H2ndVRRise&0x1000)>>10)+((H2ndVRRise&0x1000)>>12)); + } + return TRUE ; +} + +#endif // SUPPORT_SYNCEMBEDDED + +//~jj_tseng@chipadvanced.com 2007/01/02 + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetInputMode +// Parameter: InputMode,bInputSignalType +// InputMode - use [1:0] to identify the color space for reg70[7:6], +// definition: +// #define F_MODE_RGB444 0 +// #define F_MODE_YUV422 1 +// #define F_MODE_YUV444 2 +// #define F_MODE_CLRMOD_MASK 3 +// bInputSignalType - defined the CCIR656 D[0],SYNC Embedded D[1],and +// DDR input in D[2]. +// Return: N/A +// Remark: program Reg70 with the input value. +// Side-Effect: Reg70. +////////////////////////////////////////////////////////////////////// + +void hdmitx_SetInputMode(BYTE InputColorMode,BYTE bInputSignalType) +{ + BYTE ucData ; + + ucData = HDMITX_ReadI2C_Byte(REG_TX_INPUT_MODE); + ucData &= ~(M_TX_INCOLMOD|B_TX_2X656CLK|B_TX_SYNCEMB|B_TX_INDDR|B_TX_PCLKDIV2); + ucData |= 0x01;//input clock delay 1 for 1080P DDR + + switch(InputColorMode & F_MODE_CLRMOD_MASK) + { + case F_MODE_YUV422: + ucData |= B_TX_IN_YUV422 ; + break ; + case F_MODE_YUV444: + ucData |= B_TX_IN_YUV444 ; + break ; + case F_MODE_RGB444: + default: + ucData |= B_TX_IN_RGB ; + break ; + } + if(bInputSignalType & T_MODE_PCLKDIV2) + { + ucData |= B_TX_PCLKDIV2 ; HDMITX_DEBUG_PRINTF(("PCLK Divided by 2 mode\n")); + } + if(bInputSignalType & T_MODE_CCIR656) + { + ucData |= B_TX_2X656CLK ; HDMITX_DEBUG_PRINTF(("CCIR656 mode\n")); + } + if(bInputSignalType & T_MODE_SYNCEMB) + { + ucData |= B_TX_SYNCEMB ; HDMITX_DEBUG_PRINTF(("Sync Embedded mode\n")); + } + if(bInputSignalType & T_MODE_INDDR) + { + ucData |= B_TX_INDDR ; HDMITX_DEBUG_PRINTF(("Input DDR mode\n")); + } + HDMITX_WriteI2C_Byte(REG_TX_INPUT_MODE,ucData); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetCSCScale +// Parameter: bInputMode - +// D[1:0] - Color Mode +// D[4] - Colorimetry 0: ITU_BT601 1: ITU_BT709 +// D[5] - Quantization 0: 0_255 1: 16_235 +// D[6] - Up/Dn Filter 'Required' +// 0: no up/down filter +// 1: enable up/down filter when csc need. +// D[7] - Dither Filter 'Required' +// 0: no dither enabled. +// 1: enable dither and dither free go "when required". +// bOutputMode - +// D[1:0] - Color mode. +// Return: N/A +// Remark: reg72~reg8D will be programmed depended the input with table. +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +void hdmitx_SetCSCScale(BYTE bInputMode,BYTE bOutputMode) +{ + BYTE ucData,csc ; + BYTE i ; + BYTE filter = 0 ; // filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT + + // (1) YUV422 in,RGB/YUV444 output (Output is 8-bit,input is 12-bit) + // (2) YUV444/422 in,RGB output (CSC enable,and output is not YUV422) + // (3) RGB in,YUV444 output (CSC enable,and output is not YUV422) + // + // YUV444/RGB24 <-> YUV422 need set up/down filter. + HDMITX_DEBUG_PRINTF(("hdmitx_SetCSCScale(BYTE bInputMode = %x,BYTE bOutputMode = %x)\n", (int)bInputMode, (int)bOutputMode)) ; + switch(bInputMode&F_MODE_CLRMOD_MASK) + { + #ifdef SUPPORT_INPUTYUV444 + case F_MODE_YUV444: + HDMITX_DEBUG_PRINTF(("Input mode is YUV444 ")); + switch(bOutputMode&F_MODE_CLRMOD_MASK) + { + case F_MODE_YUV444: + HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); + csc = B_HDMITX_CSC_BYPASS ; + break ; + + case F_MODE_YUV422: + HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); + if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV444 to YUV422 need up/down filter for processing. + { + filter |= B_TX_EN_UDFILTER ; + } + csc = B_HDMITX_CSC_BYPASS ; + break ; + case F_MODE_RGB444: + HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); + csc = B_HDMITX_CSC_YUV2RGB ; + if(bInputMode & F_VIDMODE_EN_DITHER) // YUV444 to RGB24 need dither + { + filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; + } + break ; + } + break ; + #endif + + #ifdef SUPPORT_INPUTYUV422 + case F_MODE_YUV422: + HDMITX_DEBUG_PRINTF(("Input mode is YUV422\n")); + switch(bOutputMode&F_MODE_CLRMOD_MASK) + { + case F_MODE_YUV444: + HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); + csc = B_HDMITX_CSC_BYPASS ; + if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV422 to YUV444 need up filter + { + filter |= B_TX_EN_UDFILTER ; + } + if(bInputMode & F_VIDMODE_EN_DITHER) // YUV422 to YUV444 need dither + { + filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; + } + break ; + case F_MODE_YUV422: + HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); + csc = B_HDMITX_CSC_BYPASS ; + + break ; + + case F_MODE_RGB444: + HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); + csc = B_HDMITX_CSC_YUV2RGB ; + if(bInputMode & F_VIDMODE_EN_UDFILT) // YUV422 to RGB24 need up/dn filter. + { + filter |= B_TX_EN_UDFILTER ; + } + if(bInputMode & F_VIDMODE_EN_DITHER) // YUV422 to RGB24 need dither + { + filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; + } + break ; + } + break ; + #endif + + #ifdef SUPPORT_INPUTRGB + case F_MODE_RGB444: + HDMITX_DEBUG_PRINTF(("Input mode is RGB24\n")); + switch(bOutputMode&F_MODE_CLRMOD_MASK) + { + case F_MODE_YUV444: + HDMITX_DEBUG_PRINTF(("Output mode is YUV444\n")); + csc = B_HDMITX_CSC_RGB2YUV ; + + if(bInputMode & F_VIDMODE_EN_DITHER) // RGB24 to YUV444 need dither + { + filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; + } + break ; + + case F_MODE_YUV422: + HDMITX_DEBUG_PRINTF(("Output mode is YUV422\n")); + if(bInputMode & F_VIDMODE_EN_UDFILT) // RGB24 to YUV422 need down filter. + { + filter |= B_TX_EN_UDFILTER ; + } + if(bInputMode & F_VIDMODE_EN_DITHER) // RGB24 to YUV422 need dither + { + filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ; + } + csc = B_HDMITX_CSC_RGB2YUV ; + break ; + + case F_MODE_RGB444: + HDMITX_DEBUG_PRINTF(("Output mode is RGB24\n")); + csc = B_HDMITX_CSC_BYPASS ; + break ; + } + break ; + #endif + } +#ifndef DISABLE_HDMITX_CSC + + #ifdef SUPPORT_INPUTRGB + // set the CSC metrix registers by colorimetry and quantization + if(csc == B_HDMITX_CSC_RGB2YUV) + { + HDMITX_DEBUG_PRINTF(("CSC = RGB2YUV %x ",csc)); + switch(bInputMode&(F_VIDMODE_ITU709|F_VIDMODE_16_235)) + { + case F_VIDMODE_ITU709|F_VIDMODE_16_235: + HDMITX_DEBUG_PRINTF(("ITU709 16-235 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_16_235[i]));} + break ; + case F_VIDMODE_ITU709|F_VIDMODE_0_255: + HDMITX_DEBUG_PRINTF(("ITU709 0-255 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_0_255[i]));} + break ; + case F_VIDMODE_ITU601|F_VIDMODE_16_235: + HDMITX_DEBUG_PRINTF(("ITU601 16-235 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_16_235[i]));} + break ; + case F_VIDMODE_ITU601|F_VIDMODE_0_255: + default: + HDMITX_DEBUG_PRINTF(("ITU601 0-255 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_0_255[i]));} + break ; + } + } + #endif + + #ifdef SUPPORT_INPUTYUV + if (csc == B_HDMITX_CSC_YUV2RGB) + { + HDMITX_DEBUG_PRINTF(("CSC = YUV2RGB %x ",csc)); + + switch(bInputMode&(F_VIDMODE_ITU709|F_VIDMODE_16_235)) + { + case F_VIDMODE_ITU709|F_VIDMODE_16_235: + HDMITX_DEBUG_PRINTF(("ITU709 16-235 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_16_235[i]));} + break ; + case F_VIDMODE_ITU709|F_VIDMODE_0_255: + HDMITX_DEBUG_PRINTF(("ITU709 0-255 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_0_255[i]));} + break ; + case F_VIDMODE_ITU601|F_VIDMODE_16_235: + HDMITX_DEBUG_PRINTF(("ITU601 16-235 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_16_235[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_16_235[i]));} + break ; + case F_VIDMODE_ITU601|F_VIDMODE_0_255: + default: + HDMITX_DEBUG_PRINTF(("ITU601 0-255 ")); + for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ HDMITX_WriteI2C_Byte(REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_0_255[i]) ; HDMITX_DEBUG_PRINTF(("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_0_255[i]));} + break ; + } + } + #endif +#else// DISABLE_HDMITX_CSC + csc = B_HDMITX_CSC_BYPASS ; +#endif// DISABLE_HDMITX_CSC + + if( csc == B_HDMITX_CSC_BYPASS ) + { + HDMITX_SetI2C_Byte(0xF, 0x10, 0x10); + } + else + { + HDMITX_SetI2C_Byte(0xF, 0x10, 0x00); + } + ucData = HDMITX_ReadI2C_Byte(REG_TX_CSC_CTRL) & ~(M_TX_CSC_SEL|B_TX_DNFREE_GO|B_TX_EN_DITHER|B_TX_EN_UDFILTER); + ucData |= filter|csc ; + + HDMITX_WriteI2C_Byte(REG_TX_CSC_CTRL,ucData); + + // set output Up/Down Filter,Dither control + +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetupAFE +// Parameter: VIDEOPCLKLEVEL level +// PCLK_LOW - for 13.5MHz (for mode less than 1080p) +// PCLK MEDIUM - for 25MHz~74MHz +// PCLK HIGH - PCLK > 80Hz (for 1080p mode or above) +// Return: N/A +// Remark: set reg62~reg65 depended on HighFreqMode +// reg61 have to be programmed at last and after video stable input. +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +void hdmitx_SetupAFE(VIDEOPCLKLEVEL level) +{ + + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST);/* 0x10 */ + switch(level) + { + case PCLK_HIGH: + HDMITX_SetI2C_Byte(0x62, 0x90, 0x80); + HDMITX_SetI2C_Byte(0x64, 0x89, 0x80); + HDMITX_SetI2C_Byte(0x68, 0x10, 0x80); + HDMITX_DEBUG_PRINTF(("hdmitx_SetupAFE()===================HIGHT\n")); + break ; + default: + HDMITX_SetI2C_Byte(0x62, 0x90, 0x10); + HDMITX_SetI2C_Byte(0x64, 0x89, 0x09); + HDMITX_SetI2C_Byte(0x68, 0x10, 0x10); + HDMITX_DEBUG_PRINTF(("hdmitx_SetupAFE()===================LOW\n")); + break ; + } + HDMITX_SetI2C_Byte(REG_TX_SW_RST,B_TX_REF_RST_HDMITX|B_HDMITX_VID_RST,0); + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,0); + delay1ms(1); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_FireAFE +// Parameter: N/A +// Return: N/A +// Remark: write reg61 with 0x04 +// When program reg61 with 0x04,then audio and video circuit work. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +void hdmitx_FireAFE() +{ + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(REG_TX_AFE_DRV_CTRL,0); +} + +///***************************************** +// @file +//******************************************/ + +BYTE AudioDelayCnt=0; +BYTE LastRefaudfreqnum=0; +BOOL bForceCTS = FALSE; + +////////////////////////////////////////////////////////////////////// +// Audio Output +////////////////////////////////////////////////////////////////////// + +void setHDMITX_ChStat(BYTE ucIEC60958ChStat[]) +{ + BYTE uc ; + + Switch_HDMITX_Bank(1); + uc = (ucIEC60958ChStat[0] <<1)& 0x7C ; + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_MODE,uc); + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CAT,ucIEC60958ChStat[1]); // 192, audio CATEGORY + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_SRCNUM,ucIEC60958ChStat[2]&0xF); + HDMITX_WriteI2C_Byte(REG_TX_AUD0CHST_CHTNUM,(ucIEC60958ChStat[2]>>4)&0xF); + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,ucIEC60958ChStat[3]); // choose clock + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,ucIEC60958ChStat[4]); + Switch_HDMITX_Bank(0); +} + +void setHDMITX_UpdateChStatFs(ULONG Fs) +{ + BYTE uc ; + + ///////////////////////////////////// + // Fs should be the following value. + // #define AUDFS_22p05KHz 4 + // #define AUDFS_44p1KHz 0 + // #define AUDFS_88p2KHz 8 + // #define AUDFS_176p4KHz 12 + // + // #define AUDFS_24KHz 6 + // #define AUDFS_48KHz 2 + // #define AUDFS_96KHz 10 + // #define AUDFS_192KHz 14 + // + // #define AUDFS_768KHz 9 + // + // #define AUDFS_32KHz 3 + // #define AUDFS_OTHER 1 + ///////////////////////////////////// + + Switch_HDMITX_Bank(1); + uc = HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_CA_FS); // choose clock + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,uc); // choose clock + uc &= 0xF0 ; + uc |= (Fs&0xF); + + uc = HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_OFS_WL); + uc &= 0xF ; + uc |= ((~Fs) << 4)&0xF0 ; + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,uc); + + Switch_HDMITX_Bank(0); +} + +void setHDMITX_LPCMAudio(BYTE AudioSrcNum, BYTE AudSWL, BOOL bSPDIF) +{ + + BYTE AudioEnable, AudioFormat ; + + AudioEnable = 0 ; + AudioFormat = hdmiTxDev[0].bOutputAudioMode ; + + switch(AudSWL) + { + case 16: + AudioEnable |= M_TX_AUD_16BIT ; + break ; + case 18: + AudioEnable |= M_TX_AUD_18BIT ; + break ; + case 20: + AudioEnable |= M_TX_AUD_20BIT ; + break ; + case 24: + default: + AudioEnable |= M_TX_AUD_24BIT ; + break ; + } + if( bSPDIF ) + { + AudioFormat &= ~0x40 ; + AudioEnable |= B_TX_AUD_SPDIF|B_TX_AUD_EN_I2S0 ; + } + else + { + AudioFormat |= 0x40 ; + switch(AudioSrcNum) + { + case 4: + AudioEnable |= B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; + break ; + + case 3: + AudioEnable |= B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; + break ; + + case 2: + AudioEnable |= B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ; + break ; + + case 1: + default: + AudioFormat &= ~0x40 ; + AudioEnable |= B_TX_AUD_EN_I2S0 ; + break ; + + } + } + AudioFormat|=0x01;//mingchih add + hdmiTxDev[0].bAudioChannelEnable=AudioEnable; + + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0,AudioEnable&0xF0); + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,AudioFormat); // regE1 bOutputAudioMode should be loaded from ROM image. + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. +#ifdef USE_SPDIF_CHSTAT + if( bSPDIF ) + { + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); + } + else + { + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); + } +#else // not USE_SPDIF_CHSTAT + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); +#endif // USE_SPDIF_CHSTAT + + HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); + HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ; + + if( bSPDIF ) + { + BYTE i ; + HDMITX_OrReg_Byte(0x5c,(1<<6)); + for( i = 0 ; i < 100 ; i++ ) + { + if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) + { + break ; // stable clock. + } + } + } +} + +void setHDMITX_NLPCMAudio(BOOL bSPDIF) // no Source Num, no I2S. +{ + BYTE AudioEnable, AudioFormat ; + BYTE i ; + + AudioFormat = 0x01 ; // NLPCM must use standard I2S mode. + if( bSPDIF ) + { + AudioEnable = M_TX_AUD_24BIT|B_TX_AUD_SPDIF; + } + else + { + AudioEnable = M_TX_AUD_24BIT; + } + + Switch_HDMITX_Bank(0); + // HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, AudioEnable); + //HDMITX_AndREG_Byte(REG_TX_SW_RST,~(B_HDMITX_AUD_RST|B_TX_AREF_RST)); + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x01); // regE1 bOutputAudioMode should be loaded from ROM image. + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. + +#ifdef USE_SPDIF_CHSTAT + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); +#else // not USE_SPDIF_CHSTAT + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); +#endif // USE_SPDIF_CHSTAT + + HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); + HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ; + + if( bSPDIF ) + { + for( i = 0 ; i < 100 ; i++ ) + { + if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) + { + break ; // stable clock. + } + } + } + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, AudioEnable|B_TX_AUD_EN_I2S0); +} + +void setHDMITX_HBRAudio(BOOL bSPDIF) +{ + // BYTE rst; + Switch_HDMITX_Bank(0); + + // rst = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); + // rst &= ~(B_HDMITX_AUD_RST|B_TX_AREF_RST); + + // HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst | B_HDMITX_AUD_RST ); + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x47); // regE1 bOutputAudioMode should be loaded from ROM image. + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. + + if( bSPDIF ) + { + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL); + } + else + { + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); + } + HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x08); + HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,B_TX_HBR); // regE5 = 0 ; + + //uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); + //uc &= ~M_TX_AUD_DIV ; + //HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); + + if( bSPDIF ) + { + BYTE i ; + for( i = 0 ; i < 100 ; i++ ) + { + if(HDMITX_ReadI2C_Byte(REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK) + { + break ; // stable clock. + } + } + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF|B_TX_AUD_EN_SPDIF); + } + else + { + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0); + } + HDMITX_AndReg_Byte(0x5c,~(1<<6)); + hdmiTxDev[0].bAudioChannelEnable=HDMITX_ReadI2C_Byte(REG_TX_AUDIO_CTRL0); + // HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst ); +} + +void setHDMITX_DSDAudio() +{ + // to be continue + // BYTE rst; + // rst = HDMITX_ReadI2C_Byte(REG_TX_SW_RST); + + //HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst | (B_HDMITX_AUD_RST|B_TX_AREF_RST) ); + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,0x41); // regE1 bOutputAudioMode should be loaded from ROM image. + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping. + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,0); + + HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,0x00); + HDMITX_WriteI2C_Byte(REG_TX_AUD_HDAUDIO,B_TX_DSD); // regE5 = 0 ; + //HDMITX_WriteI2C_Byte(REG_TX_SW_RST, rst & ~(B_HDMITX_AUD_RST|B_TX_AREF_RST) ); + + //uc = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1); + //uc &= ~M_TX_AUD_DIV ; + //HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, uc); + + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0); +} + +void HDMITX_DisableAudioOutput() +{ + //BYTE uc = (HDMITX_ReadI2C_Byte(REG_TX_SW_RST) | (B_HDMITX_AUD_RST | B_TX_AREF_RST)); + //HDMITX_WriteI2C_Byte(REG_TX_SW_RST,uc); + AudioDelayCnt=AudioOutDelayCnt; + LastRefaudfreqnum=0; + HDMITX_SetI2C_Byte(REG_TX_SW_RST, (B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST) ); + HDMITX_SetI2C_Byte(0x0F, 0x10, 0x10 ); +} + +void HDMITX_EnableAudioOutput(BYTE AudioType, BOOL bSPDIF, ULONG SampleFreq, BYTE ChNum, BYTE *pIEC60958ChStat, ULONG TMDSClock) +{ + static _IDATA BYTE ucIEC60958ChStat[5] ; + + BYTE Fs ; + AudioDelayCnt=36; + LastRefaudfreqnum=0; + hdmiTxDev[0].TMDSClock=TMDSClock; + hdmiTxDev[0].bAudioChannelEnable=0; + hdmiTxDev[0].bSPDIF_OUT=bSPDIF; + + HDMITX_DEBUG_PRINTF1(("HDMITX_EnableAudioOutput(%02X, %s, %ld, %d, %p, %ld);\n", + AudioType, bSPDIF?"SPDIF":"I2S",SampleFreq, ChNum, pIEC60958ChStat, TMDSClock + )); + + HDMITX_OrReg_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST | B_TX_AREF_RST)); + HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL0,B_TX_AUTO_OVER_SAMPLING_CLOCK|B_TX_EXT_256FS|0x01); + + HDMITX_SetI2C_Byte(0x0F, 0x10, 0x00 ); // power on the ACLK + + if(bSPDIF) + { + if(AudioType==T_AUDIO_HBR) + { + HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL0,0x81); + } + HDMITX_OrReg_Byte(REG_TX_AUDIO_CTRL0,B_TX_AUD_SPDIF); + } + else + { + HDMITX_AndReg_Byte(REG_TX_AUDIO_CTRL0,(~B_TX_AUD_SPDIF)); + } + if( AudioType != T_AUDIO_DSD) + { + // one bit audio have no channel status. + switch(SampleFreq) + { + case 44100L: Fs = AUDFS_44p1KHz ; break ; + case 88200L: Fs = AUDFS_88p2KHz ; break ; + case 176400L: Fs = AUDFS_176p4KHz ; break ; + case 32000L: Fs = AUDFS_32KHz ; break ; + case 48000L: Fs = AUDFS_48KHz ; break ; + case 96000L: Fs = AUDFS_96KHz ; break ; + case 192000L: Fs = AUDFS_192KHz ; break ; + case 768000L: Fs = AUDFS_768KHz ; break ; + default: + SampleFreq = 48000L ; + Fs = AUDFS_48KHz ; + break ; // default, set Fs = 48KHz. + } + #ifdef SUPPORT_AUDIO_MONITOR + hdmiTxDev[0].bAudFs=AUDFS_OTHER; + #else + hdmiTxDev[0].bAudFs=Fs; + #endif + setHDMITX_NCTS(hdmiTxDev[0].bAudFs); + if( pIEC60958ChStat == NULL ) + { + ucIEC60958ChStat[0] = 0 ; + ucIEC60958ChStat[1] = 0 ; + ucIEC60958ChStat[2] = (ChNum+1)/2 ; + + if(ucIEC60958ChStat[2]<1) + { + ucIEC60958ChStat[2] = 1 ; + } + else if( ucIEC60958ChStat[2] >4 ) + { + ucIEC60958ChStat[2] = 4 ; + } + ucIEC60958ChStat[3] = Fs ; + ucIEC60958ChStat[4] = ((~Fs)<<4) & 0xF0 | CHTSTS_SWCODE ; // Fs | 24bit word length + pIEC60958ChStat = ucIEC60958ChStat ; + } + } + HDMITX_SetI2C_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),B_TX_AREF_RST); + + switch(AudioType) + { + case T_AUDIO_HBR: + HDMITX_DEBUG_PRINTF(("T_AUDIO_HBR\n")); + pIEC60958ChStat[0] |= 1<<1 ; + pIEC60958ChStat[2] = 0; + pIEC60958ChStat[3] &= 0xF0 ; + pIEC60958ChStat[3] |= AUDFS_768KHz ; + pIEC60958ChStat[4] |= (((~AUDFS_768KHz)<<4) & 0xF0)| 0xB ; + setHDMITX_ChStat(pIEC60958ChStat); + setHDMITX_HBRAudio(bSPDIF); + + break ; + case T_AUDIO_DSD: + HDMITX_DEBUG_PRINTF(("T_AUDIO_DSD\n")); + setHDMITX_DSDAudio(); + break ; + case T_AUDIO_NLPCM: + HDMITX_DEBUG_PRINTF(("T_AUDIO_NLPCM\n")); + pIEC60958ChStat[0] |= 1<<1 ; + setHDMITX_ChStat(pIEC60958ChStat); + setHDMITX_NLPCMAudio(bSPDIF); + break ; + case T_AUDIO_LPCM: + HDMITX_DEBUG_PRINTF(("T_AUDIO_LPCM\n")); + pIEC60958ChStat[0] &= ~(1<<1); + + setHDMITX_ChStat(pIEC60958ChStat); + setHDMITX_LPCMAudio((ChNum+1)/2, SUPPORT_AUDI_AudSWL, bSPDIF); + // can add auto adjust + break ; + } + HDMITX_AndReg_Byte(REG_TX_INT_MASK1,(~B_TX_AUDIO_OVFLW_MASK)); + HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable); + + HDMITX_SetI2C_Byte(REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),0); +} + +void hdmitx_AutoAdjustAudio() +{ + unsigned long SampleFreq,cTMDSClock ; + unsigned long N ; + ULONG aCTS=0; + BYTE fs, uc,LoopCnt=10; + if(bForceCTS) + { + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(0xF8, 0xC3); + HDMITX_WriteI2C_Byte(0xF8, 0xA5); + HDMITX_AndReg_Byte(REG_TX_PKT_SINGLE_CTRL,~B_TX_SW_CTS); // D[1] = 0, HW auto count CTS + HDMITX_WriteI2C_Byte(0xF8, 0xFF); + } + //delay1ms(50); + Switch_HDMITX_Bank(1); + N = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN2)&0xF) << 16 ; + N |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN1)) <<8 ; + N |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudN0)); + + while(LoopCnt--) + { ULONG TempCTS=0; + aCTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; + aCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; + aCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; + if(aCTS==TempCTS) + {break;} + TempCTS=aCTS; + } + Switch_HDMITX_Bank(0); + if( aCTS == 0) + { + HDMITX_DEBUG_PRINTF(("aCTS== 0")); + return; + } + uc = HDMITX_ReadI2C_Byte(REG_TX_GCP); + + cTMDSClock = hdmiTxDev[0].TMDSClock ; + //TMDSClock=GetInputPclk(); + HDMITX_DEBUG_PRINTF(("PCLK = %u0,000\n",(WORD)(cTMDSClock/10000))); + switch(uc & 0x70) + { + case 0x50: + cTMDSClock *= 5 ; + cTMDSClock /= 4 ; + break ; + case 0x60: + cTMDSClock *= 3 ; + cTMDSClock /= 2 ; + } + SampleFreq = cTMDSClock/aCTS ; + SampleFreq *= N ; + SampleFreq /= 128 ; + //SampleFreq=48000; + + HDMITX_DEBUG_PRINTF(("SampleFreq = %u0\n",(WORD)(SampleFreq/10))); + if( SampleFreq>31000L && SampleFreq<=38050L ){fs = AUDFS_32KHz ;} + else if (SampleFreq < 46550L ) {fs = AUDFS_44p1KHz ;}//46050 + else if (SampleFreq < 68100L ) {fs = AUDFS_48KHz ;} + else if (SampleFreq < 92100L ) {fs = AUDFS_88p2KHz ;} + else if (SampleFreq < 136200L ) {fs = AUDFS_96KHz ;} + else if (SampleFreq < 184200L ) {fs = AUDFS_176p4KHz ;} + else if (SampleFreq < 240200L ) {fs = AUDFS_192KHz ;} + else if (SampleFreq < 800000L ) {fs = AUDFS_768KHz ;} + else + { + fs = AUDFS_OTHER; + HDMITX_DEBUG_PRINTF(("fs = AUDFS_OTHER\n")); + } + if(hdmiTxDev[0].bAudFs != fs) + { + hdmiTxDev[0].bAudFs=fs; + setHDMITX_NCTS(hdmiTxDev[0].bAudFs); // set N, CTS by new generated clock. + //CurrCTS=0; + return; + } + return; +} + +BOOL hdmitx_IsAudioChang() +{ + //ULONG pCTS=0; + BYTE FreDiff=0,Refaudfreqnum; + + //Switch_HDMITX_Bank(1); + //pCTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; + //pCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; + //pCTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; + //Switch_HDMITX_Bank(0); + Switch_HDMITX_Bank(0); + Refaudfreqnum=HDMITX_ReadI2C_Byte(0x60); + //HDMITX_DEBUG_PRINTF(("Refaudfreqnum=%X pCTS= %u",(WORD)Refaudfreqnum,(WORD)(pCTS/10000))); + //if((pCTS%10000)<1000)HDMITX_DEBUG_PRINTF(("0")); + //if((pCTS%10000)<100)HDMITX_DEBUG_PRINTF(("0")); + //if((pCTS%10000)<10)HDMITX_DEBUG_PRINTF(("0")); + //HDMITX_DEBUG_PRINTF(("%u\n",(WORD)(pCTS%10000))); + if((1<<4)&HDMITX_ReadI2C_Byte(0x5f)) + { + //printf("=======XXXXXXXXXXX=========\n"); + return FALSE; + } + if(LastRefaudfreqnum>Refaudfreqnum) + {FreDiff=LastRefaudfreqnum-Refaudfreqnum;} + else + {FreDiff=Refaudfreqnum-LastRefaudfreqnum;} + LastRefaudfreqnum=Refaudfreqnum; + if(3>8)&0xFF)); + HDMITX_WriteI2C_Byte(REGPktAudN2,(BYTE)((n>>16)&0xF)); + + if(bForceCTS) + { + ULONG SumCTS=0; + while(LoopCnt--) + { + delay1ms(30); + CTS = ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt2)) << 12 ; + CTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt1)) <<4 ; + CTS |= ((unsigned long)HDMITX_ReadI2C_Byte(REGPktAudCTSCnt0)&0xf0)>>4 ; + if( CTS == 0) + { + continue; + } + else + { + if(LastCTS>CTS ) + {diff=LastCTS-CTS;} + else + {diff=CTS-LastCTS;} + //HDMITX_DEBUG_PRINTF(("LastCTS= %u%u",(WORD)(LastCTS/10000),(WORD)(LastCTS%10000))); + //HDMITX_DEBUG_PRINTF((" CTS= %u%u\n",(WORD)(CTS/10000),(WORD)(CTS%10000))); + LastCTS=CTS; + if(5>diff) + { + CTSStableCnt++; + SumCTS+=CTS; + } + else + { + CTSStableCnt=0; + SumCTS=0; + continue; + } + if(CTSStableCnt>=32) + { + LastCTS=(SumCTS>>5); + break; + } + } + } + } + HDMITX_WriteI2C_Byte(REGPktAudCTS0,(BYTE)((LastCTS)&0xFF)); + HDMITX_WriteI2C_Byte(REGPktAudCTS1,(BYTE)((LastCTS>>8)&0xFF)); + HDMITX_WriteI2C_Byte(REGPktAudCTS2,(BYTE)((LastCTS>>16)&0xF)); + Switch_HDMITX_Bank(0); +#ifdef Force_CTS + bForceCTS = TRUE; +#endif + HDMITX_WriteI2C_Byte(0xF8, 0xC3); + HDMITX_WriteI2C_Byte(0xF8, 0xA5); + if(bForceCTS) + { + HDMITX_OrReg_Byte(REG_TX_PKT_SINGLE_CTRL,B_TX_SW_CTS); // D[1] = 0, HW auto count CTS + } + else + { + HDMITX_AndReg_Byte(REG_TX_PKT_SINGLE_CTRL,~B_TX_SW_CTS); // D[1] = 0, HW auto count CTS + } + HDMITX_WriteI2C_Byte(0xF8, 0xFF); + + if(FALSE==HBR_mode) //LPCM + { + BYTE uData; + Switch_HDMITX_Bank(1); + Fs = AUDFS_768KHz ; + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,0x00|Fs); + Fs = ~Fs ; // OFS is the one's complement of FS + uData = (0x0f&HDMITX_ReadI2C_Byte(REG_TX_AUDCHST_OFS_WL)); + HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,(Fs<<4)|uData); + Switch_HDMITX_Bank(0); + } +} + +///***************************************** +// @file +//******************************************/ + +BOOL HDMITX_EnableVSInfoFrame(BYTE bEnable,BYTE *pVSInfoFrame) +{ + if(!bEnable) + { + hdmitx_DISABLE_VSDB_PKT(); + return TRUE ; + } + if(hdmitx_SetVSIInfoFrame((VendorSpecific_InfoFrame *)pVSInfoFrame) == ER_SUCCESS) + { + return TRUE ; + } + return FALSE ; +} + +BOOL HDMITX_EnableAVIInfoFrame(BYTE bEnable,BYTE *pAVIInfoFrame) +{ + if(!bEnable) + { + hdmitx_DISABLE_AVI_INFOFRM_PKT(); + return TRUE ; + } + if(hdmitx_SetAVIInfoFrame((AVI_InfoFrame *)pAVIInfoFrame) == ER_SUCCESS) + { + return TRUE ; + } + return FALSE ; +} + +BOOL HDMITX_EnableAudioInfoFrame(BYTE bEnable,BYTE *pAudioInfoFrame) +{ + if(!bEnable) + { + hdmitx_DISABLE_AVI_INFOFRM_PKT(); + return TRUE ; + } + if(hdmitx_SetAudioInfoFrame((Audio_InfoFrame *)pAudioInfoFrame) == ER_SUCCESS) + { + return TRUE ; + } + return FALSE ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetAVIInfoFrame() +// Parameter: pAVIInfoFrame - the pointer to HDMI AVI Infoframe ucData +// Return: N/A +// Remark: Fill the AVI InfoFrame ucData,and count checksum,then fill into +// AVI InfoFrame registers. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_SetAVIInfoFrame(AVI_InfoFrame *pAVIInfoFrame) +{ + int i ; + byte checksum ; + + if(!pAVIInfoFrame) + { + return ER_FAIL ; + } + Switch_HDMITX_Bank(1); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB1,pAVIInfoFrame->pktbyte.AVI_DB[0]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB2,pAVIInfoFrame->pktbyte.AVI_DB[1]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB3,pAVIInfoFrame->pktbyte.AVI_DB[2]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB4,pAVIInfoFrame->pktbyte.AVI_DB[3]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB5,pAVIInfoFrame->pktbyte.AVI_DB[4]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB6,pAVIInfoFrame->pktbyte.AVI_DB[5]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB7,pAVIInfoFrame->pktbyte.AVI_DB[6]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB8,pAVIInfoFrame->pktbyte.AVI_DB[7]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB9,pAVIInfoFrame->pktbyte.AVI_DB[8]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB10,pAVIInfoFrame->pktbyte.AVI_DB[9]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB11,pAVIInfoFrame->pktbyte.AVI_DB[10]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB12,pAVIInfoFrame->pktbyte.AVI_DB[11]); + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_DB13,pAVIInfoFrame->pktbyte.AVI_DB[12]); + for(i = 0,checksum = 0; i < 13 ; i++) + { + checksum -= pAVIInfoFrame->pktbyte.AVI_DB[i] ; + } + /* + HDMITX_DEBUG_PRINTF(("SetAVIInfo(): ")); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB1))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB2))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB3))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB4))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB5))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB6))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB7))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB8))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB9))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB10))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB11))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB12))); + HDMITX_DEBUG_PRINTF(("%02X ",(int)HDMITX_ReadI2C_Byte(REG_TX_AVIINFO_DB13))); + HDMITX_DEBUG_PRINTF(("\n")); + */ + checksum -= AVI_INFOFRAME_VER+AVI_INFOFRAME_TYPE+AVI_INFOFRAME_LEN ; + HDMITX_WriteI2C_Byte(REG_TX_AVIINFO_SUM,checksum); + + Switch_HDMITX_Bank(0); + hdmitx_ENABLE_AVI_INFOFRM_PKT(); + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetAudioInfoFrame() +// Parameter: pAudioInfoFrame - the pointer to HDMI Audio Infoframe ucData +// Return: N/A +// Remark: Fill the Audio InfoFrame ucData,and count checksum,then fill into +// Audio InfoFrame registers. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_SetAudioInfoFrame(Audio_InfoFrame *pAudioInfoFrame) +{ + BYTE checksum ; + + if(!pAudioInfoFrame) + { + return ER_FAIL ; + } + Switch_HDMITX_Bank(1); + checksum = 0x100-(AUDIO_INFOFRAME_VER+AUDIO_INFOFRAME_TYPE+AUDIO_INFOFRAME_LEN ); + HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_CC,pAudioInfoFrame->pktbyte.AUD_DB[0]); + checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_CC); checksum &= 0xFF ; + HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_SF,pAudioInfoFrame->pktbyte.AUD_DB[1]); + checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_SF); checksum &= 0xFF ; + HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_CA,pAudioInfoFrame->pktbyte.AUD_DB[3]); + checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_CA); checksum &= 0xFF ; + HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_DM_LSV,pAudioInfoFrame->pktbyte.AUD_DB[4]); + checksum -= HDMITX_ReadI2C_Byte(REG_TX_PKT_AUDINFO_DM_LSV); checksum &= 0xFF ; + + HDMITX_WriteI2C_Byte(REG_TX_PKT_AUDINFO_SUM,checksum); + + Switch_HDMITX_Bank(0); + hdmitx_ENABLE_AUD_INFOFRM_PKT(); + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetSPDInfoFrame() +// Parameter: pSPDInfoFrame - the pointer to HDMI SPD Infoframe ucData +// Return: N/A +// Remark: Fill the SPD InfoFrame ucData,and count checksum,then fill into +// SPD InfoFrame registers. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_SetSPDInfoFrame(SPD_InfoFrame *pSPDInfoFrame) +{ + int i ; + BYTE ucData ; + + if(!pSPDInfoFrame) + { + return ER_FAIL ; + } + Switch_HDMITX_Bank(1); + for(i = 0,ucData = 0 ; i < 25 ; i++) + { + ucData -= pSPDInfoFrame->pktbyte.SPD_DB[i] ; + HDMITX_WriteI2C_Byte(REG_TX_PKT_SPDINFO_PB1+i,pSPDInfoFrame->pktbyte.SPD_DB[i]); + } + ucData -= SPD_INFOFRAME_VER+SPD_INFOFRAME_TYPE+SPD_INFOFRAME_LEN ; + HDMITX_WriteI2C_Byte(REG_TX_PKT_SPDINFO_SUM,ucData); // checksum + Switch_HDMITX_Bank(0); + hdmitx_ENABLE_SPD_INFOFRM_PKT(); + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_SetMPEGInfoFrame() +// Parameter: pMPEGInfoFrame - the pointer to HDMI MPEG Infoframe ucData +// Return: N/A +// Remark: Fill the MPEG InfoFrame ucData,and count checksum,then fill into +// MPEG InfoFrame registers. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_SetMPEGInfoFrame(MPEG_InfoFrame *pMPGInfoFrame) +{ + int i ; + BYTE ucData ; + + if(!pMPGInfoFrame) + { + return ER_FAIL ; + } + Switch_HDMITX_Bank(1); + + HDMITX_WriteI2C_Byte(REG_TX_PKT_MPGINFO_FMT,pMPGInfoFrame->info.FieldRepeat|(pMPGInfoFrame->info.MpegFrame<<1)); + HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB0,pMPGInfoFrame->pktbyte.MPG_DB[0]); + HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB1,pMPGInfoFrame->pktbyte.MPG_DB[1]); + HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB2,pMPGInfoFrame->pktbyte.MPG_DB[2]); + HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_DB3,pMPGInfoFrame->pktbyte.MPG_DB[3]); + + for(ucData = 0,i = 0 ; i < 5 ; i++) + { + ucData -= pMPGInfoFrame->pktbyte.MPG_DB[i] ; + } + ucData -= MPEG_INFOFRAME_VER+MPEG_INFOFRAME_TYPE+MPEG_INFOFRAME_LEN ; + + HDMITX_WriteI2C_Byte(REG_TX_PKG_MPGINFO_SUM,ucData); + + Switch_HDMITX_Bank(0); + hdmitx_ENABLE_SPD_INFOFRM_PKT(); + + return ER_SUCCESS ; +} + +// 2009/12/04 added by Ming-chih.lung@ite.com.tw + +SYS_STATUS hdmitx_SetVSIInfoFrame(VendorSpecific_InfoFrame *pVSIInfoFrame) +{ + BYTE ucData=0 ; + + if(!pVSIInfoFrame) + { + return ER_FAIL ; + } + + Switch_HDMITX_Bank(1); + HDMITX_WriteI2C_Byte(0x80,pVSIInfoFrame->pktbyte.VS_DB[3]); + HDMITX_WriteI2C_Byte(0x81,pVSIInfoFrame->pktbyte.VS_DB[4]); + + ucData -= pVSIInfoFrame->pktbyte.VS_DB[3] ; + ucData -= pVSIInfoFrame->pktbyte.VS_DB[4] ; + + if( pVSIInfoFrame->pktbyte.VS_DB[4] & (1<<7 )) + { + ucData -= pVSIInfoFrame->pktbyte.VS_DB[5] ; + HDMITX_WriteI2C_Byte(0x82,pVSIInfoFrame->pktbyte.VS_DB[5]); + ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 6 + 0x0C + 0x03 ; + } + else + { + ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 5 + 0x0C + 0x03 ; + } + + pVSIInfoFrame->pktbyte.CheckSum=ucData; + + HDMITX_WriteI2C_Byte(0x83,pVSIInfoFrame->pktbyte.CheckSum); + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(REG_TX_3D_INFO_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT); + return ER_SUCCESS ; +} + +SYS_STATUS hdmitx_Set_GeneralPurpose_PKT(BYTE *pData) +{ + int i ; + + if( pData == NULL ) + { + return ER_FAIL ; + + } + Switch_HDMITX_Bank(1); + for( i = 0x38 ; i <= 0x56 ; i++) + { + HDMITX_WriteI2C_Byte(i, pData[i-0x38] ); + } + Switch_HDMITX_Bank(0); + hdmitx_ENABLE_GeneralPurpose_PKT(); + //hdmitx_ENABLE_NULL_PKT(); + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function: DumpHDMITXReg() +// Parameter: N/A +// Return: N/A +// Remark: Debug function,dumps the registers of CAT6611. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +#if Debug_message +void DumpHDMITXReg() +{ + int i,j ; + BYTE ucData ; + + HDMITX_DEBUG_PRINTF((" ")); + for(j = 0 ; j < 16 ; j++) + { + HDMITX_DEBUG_PRINTF((" %02X",(int)j)); + if((j == 3)||(j==7)||(j==11)) + { + HDMITX_DEBUG_PRINTF((" ")); + } + } + HDMITX_DEBUG_PRINTF(("\n -----------------------------------------------------\n")); + + Switch_HDMITX_Bank(0); + + for(i = 0 ; i < 0x100 ; i+=16) + { + HDMITX_DEBUG_PRINTF(("[%3X] ",i)); + for(j = 0 ; j < 16 ; j++) + { + if( (i+j)!= 0x17) + { + ucData = HDMITX_ReadI2C_Byte((BYTE)((i+j)&0xFF)); + HDMITX_DEBUG_PRINTF((" %02X",(int)ucData)); + } + else + { + HDMITX_DEBUG_PRINTF((" XX",(int)ucData)); // for DDC FIFO + } + if((j == 3)||(j==7)||(j==11)) + { + HDMITX_DEBUG_PRINTF((" -")); + } + } + HDMITX_DEBUG_PRINTF(("\n")); + if((i % 0x40) == 0x30) + { + HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); + } + } + Switch_HDMITX_Bank(1); + for(i = 0x130; i < 0x200 ; i+=16) + { + HDMITX_DEBUG_PRINTF(("[%3X] ",i)); + for(j = 0 ; j < 16 ; j++) + { + ucData = HDMITX_ReadI2C_Byte((BYTE)((i+j)&0xFF)); + HDMITX_DEBUG_PRINTF((" %02X",(int)ucData)); + if((j == 3)||(j==7)||(j==11)) + { + HDMITX_DEBUG_PRINTF((" -")); + } + } + HDMITX_DEBUG_PRINTF(("\n")); + if((i % 0x40) == 0x20) + { + HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); + } + } + HDMITX_DEBUG_PRINTF((" -----------------------------------------------------\n")); + Switch_HDMITX_Bank(0); +} + +#endif + diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h new file mode 100755 index 000000000000..e3570210f078 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_drv.h @@ -0,0 +1,746 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +#ifndef _HDMITX_DRV_H_ +#define _HDMITX_DRV_H_ + +//#define EXTERN_HDCPROM +///////////////////////////////////////// +// DDC Address +///////////////////////////////////////// +#define DDC_HDCP_ADDRESS 0x74 +#define DDC_EDID_ADDRESS 0xA0 +#define DDC_FIFO_MAXREQ 0x20 + +// I2C address + +#define _80MHz 80000000 +#define HDMI_TX_I2C_SLAVE_ADDR 0x98 +#define CEC_I2C_SLAVE_ADDR 0x9C + +#define DISABLE_HDMITX_CSC +/////////////////////////////////////////////////////////////////////// +// Register offset +/////////////////////////////////////////////////////////////////////// + +#define REG_TX_VENDOR_ID0 0x00 +#define REG_TX_VENDOR_ID1 0x01 +#define REG_TX_DEVICE_ID0 0x02 +#define REG_TX_DEVICE_ID1 0x03 + + #define O_TX_DEVID 0 + #define M_TX_DEVID 0xF + #define O_TX_REVID 4 + #define M_TX_REVID 0xF + +#define REG_TX_SW_RST 0x04 + #define B_TX_ENTEST (1<<7) + #define B_TX_REF_RST_HDMITX (1<<5) + #define B_TX_AREF_RST (1<<4) + #define B_HDMITX_VID_RST (1<<3) + #define B_HDMITX_AUD_RST (1<<2) + #define B_TX_HDMI_RST (1<<1) + #define B_TX_HDCP_RST_HDMITX (1<<0) + +#define REG_TX_INT_CTRL 0x05 + #define B_TX_INTPOL_ACTL 0 + #define B_TX_INTPOL_ACTH (1<<7) + #define B_TX_INT_PUSHPULL 0 + #define B_TX_INT_OPENDRAIN (1<<6) + +#define REG_TX_INT_STAT1 0x06 + #define B_TX_INT_AUD_OVERFLOW (1<<7) + #define B_TX_INT_ROMACQ_NOACK (1<<6) + #define B_TX_INT_RDDC_NOACK (1<<5) + #define B_TX_INT_DDCFIFO_ERR (1<<4) + #define B_TX_INT_ROMACQ_BUS_HANG (1<<3) + #define B_TX_INT_DDC_BUS_HANG (1<<2) + #define B_TX_INT_RX_SENSE (1<<1) + #define B_TX_INT_HPD_PLUG (1<<0) + +#define REG_TX_INT_STAT2 0x07 + #define B_TX_INT_HDCP_SYNC_DET_FAIL (1<<7) + #define B_TX_INT_VID_UNSTABLE (1<<6) + #define B_TX_INT_PKTACP (1<<5) + #define B_TX_INT_PKTNULL (1<<4) + #define B_TX_INT_PKTGENERAL (1<<3) + #define B_TX_INT_KSVLIST_CHK (1<<2) + #define B_TX_INT_AUTH_DONE (1<<1) + #define B_TX_INT_AUTH_FAIL (1<<0) + +#define REG_TX_INT_STAT3 0x08 + #define B_TX_INT_AUD_CTS (1<<6) + #define B_TX_INT_VSYNC (1<<5) + #define B_TX_INT_VIDSTABLE (1<<4) + #define B_TX_INT_PKTMPG (1<<3) + #define B_TX_INT_PKTSPD (1<<2) + #define B_TX_INT_PKTAUD (1<<1) + #define B_TX_INT_PKTAVI (1<<0) + +#define REG_TX_INT_MASK1 0x09 + #define B_TX_AUDIO_OVFLW_MASK (1<<7) + #define B_TX_DDC_NOACK_MASK (1<<5) + #define B_TX_DDC_FIFO_ERR_MASK (1<<4) + #define B_TX_DDC_BUS_HANG_MASK (1<<2) + #define B_TX_RXSEN_MASK (1<<1) + #define B_TX_HPD_MASK (1<<0) + +#define REG_TX_INT_MASK2 0x0A + #define B_TX_PKT_AVI_MASK (1<<7) + #define B_TX_PKT_VID_UNSTABLE_MASK (1<<6) + #define B_TX_PKT_ACP_MASK (1<<5) + #define B_TX_PKT_NULL_MASK (1<<4) + #define B_TX_PKT_GEN_MASK (1<<3) + #define B_TX_KSVLISTCHK_MASK (1<<2) + #define B_TX_AUTH_DONE_MASK (1<<1) + #define B_TX_AUTH_FAIL_MASK (1<<0) + +#define REG_TX_INT_MASK3 0x0B + #define B_TX_HDCP_SYNC_DET_FAIL_MASK (1<<6) + #define B_TX_AUDCTS_MASK (1<<5) + #define B_TX_VSYNC_MASK (1<<4) + #define B_TX_VIDSTABLE_MASK (1<<3) + #define B_TX_PKT_MPG_MASK (1<<2) + #define B_TX_PKT_SPD_MASK (1<<1) + #define B_TX_PKT_AUD_MASK (1<<0) + +#define REG_TX_INT_CLR0 0x0C + #define B_TX_CLR_PKTACP (1<<7) + #define B_TX_CLR_PKTNULL (1<<6) + #define B_TX_CLR_PKTGENERAL (1<<5) + #define B_TX_CLR_KSVLISTCHK (1<<4) + #define B_TX_CLR_AUTH_DONE (1<<3) + #define B_TX_CLR_AUTH_FAIL (1<<2) + #define B_TX_CLR_RXSENSE (1<<1) + #define B_TX_CLR_HPD (1<<0) + +#define REG_TX_INT_CLR1 0x0D + #define B_TX_CLR_VSYNC (1<<7) + #define B_TX_CLR_VIDSTABLE (1<<6) + #define B_TX_CLR_PKTMPG (1<<5) + #define B_TX_CLR_PKTSPD (1<<4) + #define B_TX_CLR_PKTAUD (1<<3) + #define B_TX_CLR_PKTAVI (1<<2) + #define B_TX_CLR_HDCP_SYNC_DET_FAIL (1<<1) + #define B_TX_CLR_VID_UNSTABLE (1<<0) + +#define REG_TX_SYS_STATUS 0x0E + // readonly + #define B_TX_INT_ACTIVE (1<<7) + #define B_TX_HPDETECT (1<<6) + #define B_TX_RXSENDETECT (1<<5) + #define B_TXVIDSTABLE (1<<4) + // read/write + #define O_TX_CTSINTSTEP 2 + #define M_TX_CTSINTSTEP (3<<2) + #define B_TX_CLR_AUD_CTS (1<<1) + #define B_TX_INTACTDONE (1<<0) + +#define REG_TX_BANK_CTRL 0x0F + #define B_TX_BANK0 0 + #define B_TX_BANK1 1 + +// DDC + +#define REG_TX_DDC_MASTER_CTRL 0x10 + #define B_TX_MASTERROM (1<<1) + #define B_TX_MASTERDDC (0<<1) + #define B_TX_MASTERHOST (1<<0) + #define B_TX_MASTERHDCP (0<<0) + +#define REG_TX_DDC_HEADER 0x11 +#define REG_TX_DDC_REQOFF 0x12 +#define REG_TX_DDC_REQCOUNT 0x13 +#define REG_TX_DDC_EDIDSEG 0x14 +#define REG_TX_DDC_CMD 0x15 + #define CMD_DDC_SEQ_BURSTREAD 0 + #define CMD_LINK_CHKREAD 2 + #define CMD_EDID_READ 3 + #define CMD_FIFO_CLR 9 + #define CMD_GEN_SCLCLK 0xA + #define CMD_DDC_ABORT 0xF + +#define REG_TX_DDC_STATUS 0x16 + #define B_TX_DDC_DONE (1<<7) + #define B_TX_DDC_ACT (1<<6) + #define B_TX_DDC_NOACK (1<<5) + #define B_TX_DDC_WAITBUS (1<<4) + #define B_TX_DDC_ARBILOSE (1<<3) + #define B_TX_DDC_ERROR (B_TX_DDC_NOACK|B_TX_DDC_WAITBUS|B_TX_DDC_ARBILOSE) + #define B_TX_DDC_FIFOFULL (1<<2) + #define B_TX_DDC_FIFOEMPTY (1<<1) + +#define REG_TX_DDC_READFIFO 0x17 +#define REG_TX_ROM_STARTADDR 0x18 +#define REG_TX_HDCP_HEADER 0x19 +#define REG_TX_ROM_HEADER 0x1A +#define REG_TX_BUSHOLD_T 0x1B +#define REG_TX_ROM_STAT 0x1C + #define B_TX_ROM_DONE (1<<7) + #define B_TX_ROM_ACTIVE (1<<6) + #define B_TX_ROM_NOACK (1<<5) + #define B_TX_ROM_WAITBUS (1<<4) + #define B_TX_ROM_ARBILOSE (1<<3) + #define B_TX_ROM_BUSHANG (1<<2) + +// HDCP +#define REG_TX_AN_GENERATE 0x1F + #define B_TX_START_CIPHER_GEN 1 + #define B_TX_STOP_CIPHER_GEN 0 + +#define REG_TX_CLK_CTRL0 0x58 + #define O_TX_OSCLK_SEL 5 + #define M_TX_OSCLK_SEL 3 + #define B_TX_AUTO_OVER_SAMPLING_CLOCK (1<<4) + #define O_TX_EXT_MCLK_SEL 2 + #define M_TX_EXT_MCLK_SEL (3< +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#include "hdmitx.h" +#include "hdmitx_drv.h" + +static BYTE countbit(BYTE b); + +extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; + +#ifdef SUPPORT_SHA +_XDATA BYTE SHABuff[64] ; +_XDATA BYTE V[20] ; +_XDATA BYTE KSVList[32] ; +_XDATA BYTE Vr[20] ; +_XDATA BYTE M0[8] ; +#endif + +BOOL HDMITX_EnableHDCP(BYTE bEnable) +{ +#ifdef SUPPORT_HDCP + if(bEnable) + { + if(ER_FAIL == hdmitx_hdcp_Authenticate()) + { + //printf("ER_FAIL == hdmitx_hdcp_Authenticate\n"); + hdmitx_hdcp_ResetAuth(); + return FALSE ; + } + } + else + { + hdmiTxDev[0].bAuthenticated=FALSE; + hdmitx_hdcp_ResetAuth(); + } +#endif + return TRUE ; +} + +#ifdef SUPPORT_HDCP + +BOOL getHDMITX_AuthenticationDone() +{ + //HDCP_DEBUG_PRINTF((" getHDMITX_AuthenticationDone() = %s\n",hdmiTxDev[0].bAuthenticated?"TRUE":"FALSE" )); + return hdmiTxDev[0].bAuthenticated; +} + +////////////////////////////////////////////////////////////////////// +// Authentication +////////////////////////////////////////////////////////////////////// +void hdmitx_hdcp_ClearAuthInterrupt() +{ + // BYTE uc ; + // uc = HDMITX_ReadI2C_Byte(REG_TX_INT_MASK2) & (~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)); + HDMITX_SetI2C_Byte(REG_TX_INT_MASK2, B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK, 0); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL|B_TX_CLR_AUTH_DONE|B_TX_CLR_KSVLISTCHK); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); +} + +void hdmitx_hdcp_ResetAuth() +{ + HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,0); + HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,0); + HDMITX_OrReg_Byte(REG_TX_SW_RST,B_TX_HDCP_RST_HDMITX); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + hdmitx_hdcp_ClearAuthInterrupt(); + hdmitx_AbortDDC(); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_Auth_Fire() +// Parameter: N/A +// Return: N/A +// Remark: write anything to reg21 to enable HDCP authentication by HW +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_Auth_Fire() +{ + // HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Auth_Fire():\n")); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHDCP); // MASTERHDCP,no need command but fire. + HDMITX_WriteI2C_Byte(REG_TX_AUTHFIRE,1); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_StartAnCipher +// Parameter: N/A +// Return: N/A +// Remark: Start the Cipher to free run for random number. When stop,An is +// ready in Reg30. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_StartAnCipher() +{ + HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_START_CIPHER_GEN); + delay1ms(1); // delay 1 ms +} +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_StopAnCipher +// Parameter: N/A +// Return: N/A +// Remark: Stop the Cipher,and An is ready in Reg30. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_StopAnCipher() +{ + HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_STOP_CIPHER_GEN); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_GenerateAn +// Parameter: N/A +// Return: N/A +// Remark: start An ciper random run at first,then stop it. Software can get +// an in reg30~reg38,the write to reg28~2F +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_GenerateAn() +{ + BYTE Data[8]; + BYTE i=0; +#if 1 + hdmitx_hdcp_StartAnCipher(); + // HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_START_CIPHER_GEN); + // delay1ms(1); // delay 1 ms + // HDMITX_WriteI2C_Byte(REG_TX_AN_GENERATE,B_TX_STOP_CIPHER_GEN); + + hdmitx_hdcp_StopAnCipher(); + + Switch_HDMITX_Bank(0); + // new An is ready in reg30 + HDMITX_ReadI2C_ByteN(REG_TX_AN_GEN,Data,8); +#else + Data[0] = 0 ;Data[1] = 0 ;Data[2] = 0 ;Data[3] = 0 ; + Data[4] = 0 ;Data[5] = 0 ;Data[6] = 0 ;Data[7] = 0 ; +#endif + for(i=0;i<8;i++) + { + HDMITX_WriteI2C_Byte(REG_TX_AN+i,Data[i]); + } + //HDMITX_WriteI2C_ByteN(REG_TX_AN,Data,8); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_GetBCaps +// Parameter: pBCaps - pointer of byte to get BCaps. +// pBStatus - pointer of two bytes to get BStatus +// Return: ER_SUCCESS if successfully got BCaps and BStatus. +// Remark: get B status and capability from HDCP reciever via DDC bus. +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_hdcp_GetBCaps(PBYTE pBCaps ,PUSHORT pBStatus) +{ + BYTE ucdata ; + BYTE TimeOut ; + + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x40); // BCaps offset + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,3); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); + + for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) + { + delay1ms(1); + + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + + if(ucdata & B_TX_DDC_DONE) + { + //HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC Done.\n")); + break ; + } + if(ucdata & B_TX_DDC_ERROR) + { +// HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC fail by reg16=%02X.\n",ucdata)); + return ER_FAIL ; + } + } + if(TimeOut == 0) + { + return ER_FAIL ; + } +#if 1 + ucdata = HDMITX_ReadI2C_Byte(REG_TX_BSTAT+1); + + *pBStatus = (USHORT)ucdata ; + *pBStatus <<= 8 ; + ucdata = HDMITX_ReadI2C_Byte(REG_TX_BSTAT); + *pBStatus |= ((USHORT)ucdata&0xFF); + *pBCaps = HDMITX_ReadI2C_Byte(REG_TX_BCAP); +#else + *pBCaps = HDMITX_ReadI2C_Byte(0x17); + *pBStatus = HDMITX_ReadI2C_Byte(0x17) & 0xFF ; + *pBStatus |= (int)(HDMITX_ReadI2C_Byte(0x17)&0xFF)<<8; + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): ucdata = %02X\n",(int)HDMITX_ReadI2C_Byte(0x16))); +#endif + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_GetBKSV +// Parameter: pBKSV - pointer of 5 bytes buffer for getting BKSV +// Return: ER_SUCCESS if successfuly got BKSV from Rx. +// Remark: Get BKSV from HDCP reciever. +// Side-Effect: N/A +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_hdcp_GetBKSV(BYTE *pBKSV) +{ + BYTE ucdata ; + BYTE TimeOut ; + + Switch_HDMITX_Bank(0); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x00); // BKSV offset + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,5); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); + + for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) + { + delay1ms(1); + + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + if(ucdata & B_TX_DDC_DONE) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC Done.\n")); + break ; + } + if(ucdata & B_TX_DDC_ERROR) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetBCaps(): DDC No ack or arbilose,%x,maybe cable did not connected. Fail.\n",ucdata)); + return ER_FAIL ; + } + } + if(TimeOut == 0) + { + return ER_FAIL ; + } + HDMITX_ReadI2C_ByteN(REG_TX_BKSV,(PBYTE)pBKSV,5); + + return ER_SUCCESS ; +} + +////////////////////////////////////////////////////////////////////// +// Function:hdmitx_hdcp_Authenticate +// Parameter: N/A +// Return: ER_SUCCESS if Authenticated without error. +// Remark: do Authentication with Rx +// Side-Effect: +// 1. hdmiTxDev[0].bAuthenticated global variable will be TRUE when authenticated. +// 2. Auth_done interrupt and AUTH_FAIL interrupt will be enabled. +////////////////////////////////////////////////////////////////////// +static BYTE countbit(BYTE b) +{ + BYTE i,count ; + for( i = 0, count = 0 ; i < 8 ; i++ ) + { + if( b & (1< 6) + { + HDCP_DEBUG_PRINTF(("Down Stream Count %d is over maximum supported number 6,fail.\n",(int)(BStatus & M_TX_DOWNSTREAM_COUNT))); + return ER_FAIL ; + } + */ + HDCP_DEBUG_PRINTF(("BCAPS = %02X BSTATUS = %04X\n", (int)BCaps, BStatus)); + hdmitx_hdcp_GetBKSV(BKSV); + HDCP_DEBUG_PRINTF(("BKSV %02X %02X %02X %02X %02X\n",(int)BKSV[0],(int)BKSV[1],(int)BKSV[2],(int)BKSV[3],(int)BKSV[4])); + + for(TimeOut = 0, ucdata = 0 ; TimeOut < 5 ; TimeOut ++) + { + ucdata += countbit(BKSV[TimeOut]); + } + if( ucdata != 20 ) + { + HDCP_DEBUG_PRINTF(("countbit error\n")); + return ER_FAIL ; + + } + Switch_HDMITX_Bank(0); // switch bank action should start on direct register writting of each function. + + HDMITX_AndReg_Byte(REG_TX_SW_RST,~(B_TX_HDCP_RST_HDMITX)); + + HDMITX_WriteI2C_Byte(REG_TX_HDCP_DESIRE,B_TX_CPDESIRE); + hdmitx_hdcp_ClearAuthInterrupt(); + + hdmitx_hdcp_GenerateAn(); + HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,0); + hdmiTxDev[0].bAuthenticated = FALSE ; + + hdmitx_ClearDDCFIFO(); + + if((BCaps & B_TX_CAP_HDMI_REPEATER) == 0) + { + hdmitx_hdcp_Auth_Fire(); + // wait for status ; + + for(TimeOut = 250 ; TimeOut > 0 ; TimeOut --) + { + delay1ms(5); // delay 1ms + ucdata = HDMITX_ReadI2C_Byte(REG_TX_AUTH_STAT); + // HDCP_DEBUG_PRINTF(("reg46 = %02x reg16 = %02x\n",(int)ucdata,(int)HDMITX_ReadI2C_Byte(0x16))); + + if(ucdata & B_TX_AUTH_DONE) + { + hdmiTxDev[0].bAuthenticated = TRUE ; + break ; + } + ucdata = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); + if(ucdata & B_TX_INT_AUTH_FAIL) + { + + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); + + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Authenticate fail\n")); + hdmiTxDev[0].bAuthenticated = FALSE ; + return ER_FAIL ; + } + } + if(TimeOut == 0) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate()-receiver: Time out. return fail\n")); + hdmiTxDev[0].bAuthenticated = FALSE ; + return ER_FAIL ; + } + return ER_SUCCESS ; + } + return hdmitx_hdcp_Authenticate_Repeater(); +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_VerifyIntegration +// Parameter: N/A +// Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail. +// Remark: no used now. +// Side-Effect: +////////////////////////////////////////////////////////////////////// + +SYS_STATUS hdmitx_hdcp_VerifyIntegration() +{ + // if any interrupt issued a Auth fail,returned the Verify Integration fail. + + if(HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1) & B_TX_INT_AUTH_FAIL) + { + hdmitx_hdcp_ClearAuthInterrupt(); + hdmiTxDev[0].bAuthenticated = FALSE ; + return ER_FAIL ; + } + if(hdmiTxDev[0].bAuthenticated == TRUE) + { + return ER_SUCCESS ; + } + return ER_FAIL ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_Authenticate_Repeater +// Parameter: BCaps and BStatus +// Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail. +// Remark: +// Side-Effect: as Authentication +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_CancelRepeaterAuthenticate() +{ + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_CancelRepeaterAuthenticate")); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST); + hdmitx_AbortDDC(); + HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,B_TX_LISTFAIL|B_TX_LISTDONE); + hdmitx_hdcp_ClearAuthInterrupt(); +} + +void hdmitx_hdcp_ResumeRepeaterAuthenticate() +{ + HDMITX_WriteI2C_Byte(REG_TX_LISTCTRL,B_TX_LISTDONE); + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHDCP); +} + +#if 0 // def SUPPORT_SHA +// #define SHA_BUFF_COUNT 17 +// _XDATA ULONG w[SHA_BUFF_COUNT]; +// +// _XDATA ULONG sha[5] ; +// +// #define rol(x,y) (((x) << (y)) | (((ULONG)x) >> (32-y))) +// +// void SHATransform(ULONG * h) +// { +// int t,i; +// ULONG tmp ; +// +// h[0] = 0x67452301 ; +// h[1] = 0xefcdab89; +// h[2] = 0x98badcfe; +// h[3] = 0x10325476; +// h[4] = 0xc3d2e1f0; +// for( t = 0 ; t < 80 ; t++ ) +// { +// if((t>=16)&&(t<80)) { +// i=(t+SHA_BUFF_COUNT-3)%SHA_BUFF_COUNT; +// tmp = w[i]; +// i=(t+SHA_BUFF_COUNT-8)%SHA_BUFF_COUNT; +// tmp ^= w[i]; +// i=(t+SHA_BUFF_COUNT-14)%SHA_BUFF_COUNT; +// tmp ^= w[i]; +// i=(t+SHA_BUFF_COUNT-16)%SHA_BUFF_COUNT; +// tmp ^= w[i]; +// w[t%SHA_BUFF_COUNT] = rol(tmp,1); +// //HDCP_DEBUG_PRINTF(("w[%2d] = %08lX\n",t,w[t%SHA_BUFF_COUNT])); +// } +// +// if((t>=0)&&(t<20)) { +// tmp = rol(h[0],5) + ((h[1] & h[2]) | (h[3] & ~h[1])) + h[4] + w[t%SHA_BUFF_COUNT] + 0x5a827999; +// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// +// h[4] = h[3]; +// h[3] = h[2]; +// h[2] = rol(h[1],30); +// h[1] = h[0]; +// h[0] = tmp; +// +// } +// if((t>=20)&&(t<40)) { +// tmp = rol(h[0],5) + (h[1] ^ h[2] ^ h[3]) + h[4] + w[t%SHA_BUFF_COUNT] + 0x6ed9eba1; +// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// h[4] = h[3]; +// h[3] = h[2]; +// h[2] = rol(h[1],30); +// h[1] = h[0]; +// h[0] = tmp; +// } +// if((t>=40)&&(t<60)) { +// tmp = rol(h[0], 5) + ((h[1] & h[2]) | (h[1] & h[3]) | (h[2] & h[3])) + h[4] + w[t%SHA_BUFF_COUNT] + +// 0x8f1bbcdc; +// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// h[4] = h[3]; +// h[3] = h[2]; +// h[2] = rol(h[1],30); +// h[1] = h[0]; +// h[0] = tmp; +// } +// if((t>=60)&&(t<80)) { +// tmp = rol(h[0],5) + (h[1] ^ h[2] ^ h[3]) + h[4] + w[t%SHA_BUFF_COUNT] + 0xca62c1d6; +// //HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// h[4] = h[3]; +// h[3] = h[2]; +// h[2] = rol(h[1],30); +// h[1] = h[0]; +// h[0] = tmp; +// } +// } +// HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// +// h[0] += 0x67452301 ; +// h[1] += 0xefcdab89; +// h[2] += 0x98badcfe; +// h[3] += 0x10325476; +// h[4] += 0xc3d2e1f0; +// // HDCP_DEBUG_PRINTF(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +// } +// +// /* ---------------------------------------------------------------------- +// * Outer SHA algorithm: take an arbitrary length byte string, +// * convert it into 16-word blocks with the prescribed padding at +// * the end,and pass those blocks to the core SHA algorithm. +// */ +// +// void SHA_Simple(void *p,LONG len,BYTE *output) +// { +// // SHA_State s; +// int i, t ; +// ULONG c ; +// char *pBuff = p ; +// +// for(i=0;i < len;i+=4) +// { +// +// t=i/4; +// w[t]=0; +// *((char *)&c)= pBuff[i]; +// *((char *)&c+1)= pBuff[i+1]; +// *((char *)&c+2)= pBuff[i+2]; +// *((char *)&c+3)= pBuff[i+3]; +// w[t]=c; +// } +// +// c=0x80; +// c<<=((3-len%4)*8); +// w[t] |= c; +// +// /* +// for( i = 0 ; i < len ; i++ ) +// { +// t = i/4 ; +// if( i%4 == 0 ) +// { +// w[t] = 0 ; +// } +// c = pBuff[i] ; +// c &= 0xFF ; +// c <<= (3-(i%4))*8 ; +// w[t] |= c ; +// // HDCP_DEBUG_PRINTF(("pBuff[%d] = %02x, c = %08lX, w[%d] = %08lX\n",i,pBuff[i],c,t,w[t])); +// } +// +// t = i/4 ; +// if( i%4 == 0 ) +// { +// w[t] = 0 ; +// } +// c = 0x80; +// c <<= ((3-i%4)*8); +// w[t]|= c ; +// */ +// t++ ; +// for( ; t < 15 ; t++ ) +// { +// w[t] = 0 ; +// } +// w[15] = len*8 ; +// +// for( t = 0 ; t< 16 ; t++ ) +// { +// HDCP_DEBUG_PRINTF(("w[%2d] = %08lX\n",t,w[t])); +// } +// +// SHATransform(sha); +// +// for( i = 0 ; i < 5 ; i++ ) +// { +// output[i*4] = (BYTE)(sha[i]&0xFF); +// output[i*4+1] = (BYTE)((sha[i]>>8)&0xFF); +// output[i*4+2] = (BYTE)((sha[i]>>16)&0xFF); +// output[i*4+3] = (BYTE)((sha[i]>>24)&0xFF); +// } +// } +#endif // 0 + +#ifdef SUPPORT_SHA + +SYS_STATUS hdmitx_hdcp_CheckSHA(BYTE pM0[],USHORT BStatus,BYTE pKSVList[],int cDownStream,BYTE Vr[]) +{ + int i,n ; + + for(i = 0 ; i < cDownStream*5 ; i++) + { + SHABuff[i] = pKSVList[i] ; + } + SHABuff[i++] = BStatus & 0xFF ; + SHABuff[i++] = (BStatus>>8) & 0xFF ; + for(n = 0 ; n < 8 ; n++,i++) + { + SHABuff[i] = pM0[n] ; + } + n = i ; + // SHABuff[i++] = 0x80 ; // end mask + for(; i < 64 ; i++) + { + SHABuff[i] = 0 ; + } + // n = cDownStream * 5 + 2 /* for BStatus */ + 8 /* for M0 */ ; + // n *= 8 ; + // SHABuff[62] = (n>>8) & 0xff ; + // SHABuff[63] = (n>>8) & 0xff ; +/* + for(i = 0 ; i < 64 ; i++) + { + if(i % 16 == 0) + { + HDCP_DEBUG_PRINTF(("SHA[]: ")); + } + HDCP_DEBUG_PRINTF((" %02X",SHABuff[i])); + if((i%16)==15) + { + HDCP_DEBUG_PRINTF(("\n")); + } + } + */ + //SHA_Simple(SHABuff,n,V); + for(i = 0 ; i < 20 ; i++) + { + if(V[i] != Vr[i]) + { + HDCP_DEBUG_PRINTF(("V[] =")); + for(i = 0 ; i < 20 ; i++) + { + HDCP_DEBUG_PRINTF((" %02X",(int)V[i])); + } + HDCP_DEBUG_PRINTF(("\nVr[] =")); + for(i = 0 ; i < 20 ; i++) + { + HDCP_DEBUG_PRINTF((" %02X",(int)Vr[i])); + } + return ER_FAIL ; + } + } + return ER_SUCCESS ; +} + +#endif // SUPPORT_SHA + +SYS_STATUS hdmitx_hdcp_GetKSVList(BYTE *pKSVList,BYTE cDownStream) +{ + BYTE TimeOut = 100 ; + BYTE ucdata ; + + if( cDownStream == 0 ) + { + return ER_SUCCESS ; + } + if( /* cDownStream == 0 || */ pKSVList == NULL) + { + return ER_FAIL ; + } + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,0x74); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x43); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,cDownStream * 5); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); + + for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) + { + + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + if(ucdata & B_TX_DDC_DONE) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): DDC Done.\n")); + break ; + } + if(ucdata & B_TX_DDC_ERROR) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): DDC Fail by REG_TX_DDC_STATUS = %x.\n",ucdata)); + return ER_FAIL ; + } + delay1ms(5); + } + if(TimeOut == 0) + { + return ER_FAIL ; + } + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetKSVList(): KSV")); + for(TimeOut = 0 ; TimeOut < cDownStream * 5 ; TimeOut++) + { + pKSVList[TimeOut] = HDMITX_ReadI2C_Byte(REG_TX_DDC_READFIFO); + HDCP_DEBUG_PRINTF((" %02X",(int)pKSVList[TimeOut])); + } + HDCP_DEBUG_PRINTF(("\n")); + return ER_SUCCESS ; +} + +SYS_STATUS hdmitx_hdcp_GetVr(BYTE *pVr) +{ + BYTE TimeOut ; + BYTE ucdata ; + + if(pVr == NULL) + { + return ER_FAIL ; + } + HDMITX_WriteI2C_Byte(REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST); + HDMITX_WriteI2C_Byte(REG_TX_DDC_HEADER,0x74); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQOFF,0x20); + HDMITX_WriteI2C_Byte(REG_TX_DDC_REQCOUNT,20); + HDMITX_WriteI2C_Byte(REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD); + + for(TimeOut = 200 ; TimeOut > 0 ; TimeOut --) + { + ucdata = HDMITX_ReadI2C_Byte(REG_TX_DDC_STATUS); + if(ucdata & B_TX_DDC_DONE) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC Done.\n")); + break ; + } + if(ucdata & B_TX_DDC_ERROR) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC fail by REG_TX_DDC_STATUS = %x.\n",(int)ucdata)); + return ER_FAIL ; + } + delay1ms(5); + } + if(TimeOut == 0) + { + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_GetVr(): DDC fail by timeout.\n")); + return ER_FAIL ; + } + Switch_HDMITX_Bank(0); + + for(TimeOut = 0 ; TimeOut < 5 ; TimeOut++) + { + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL ,TimeOut); + pVr[TimeOut*4] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE1); + pVr[TimeOut*4+1] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE2); + pVr[TimeOut*4+2] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE3); + pVr[TimeOut*4+3] = (ULONG)HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE4); +// HDCP_DEBUG_PRINTF(("V' = %02X %02X %02X %02X\n",(int)pVr[TimeOut*4],(int)pVr[TimeOut*4+1],(int)pVr[TimeOut*4+2],(int)pVr[TimeOut*4+3])); + } + return ER_SUCCESS ; +} + +SYS_STATUS hdmitx_hdcp_GetM0(BYTE *pM0) +{ + int i ; + + if(!pM0) + { + return ER_FAIL ; + } + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,5); // read m0[31:0] from reg51~reg54 + pM0[0] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE1); + pM0[1] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE2); + pM0[2] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE3); + pM0[3] = HDMITX_ReadI2C_Byte(REG_TX_SHA_RD_BYTE4); + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,0); // read m0[39:32] from reg55 + pM0[4] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,1); // read m0[47:40] from reg55 + pM0[5] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,2); // read m0[55:48] from reg55 + pM0[6] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); + HDMITX_WriteI2C_Byte(REG_TX_SHA_SEL,3); // read m0[63:56] from reg55 + pM0[7] = HDMITX_ReadI2C_Byte(REG_TX_AKSV_RD_BYTE5); + + HDCP_DEBUG_PRINTF(("M[] =")); + for(i = 0 ; i < 8 ; i++) + { + HDCP_DEBUG_PRINTF(("0x%02x,",(int)pM0[i])); + } + HDCP_DEBUG_PRINTF(("\n")); + return ER_SUCCESS ; +} + +SYS_STATUS hdmitx_hdcp_Authenticate_Repeater() +{ + BYTE uc ,ii; + // BYTE revoked ; + // int i ; + BYTE cDownStream ; + + BYTE BCaps; + USHORT BStatus ; + USHORT TimeOut ; + + HDCP_DEBUG_PRINTF(("Authentication for repeater\n")); + // emily add for test,abort HDCP + // 2007/10/01 marked by jj_tseng@chipadvanced.com + // HDMITX_WriteI2C_Byte(0x20,0x00); + // HDMITX_WriteI2C_Byte(0x04,0x01); + // HDMITX_WriteI2C_Byte(0x10,0x01); + // HDMITX_WriteI2C_Byte(0x15,0x0F); + // delay1ms(100); + // HDMITX_WriteI2C_Byte(0x04,0x00); + // HDMITX_WriteI2C_Byte(0x10,0x00); + // HDMITX_WriteI2C_Byte(0x20,0x01); + // delay1ms(100); + // test07 = HDMITX_ReadI2C_Byte(0x7); + // test06 = HDMITX_ReadI2C_Byte(0x6); + // test08 = HDMITX_ReadI2C_Byte(0x8); + //~jj_tseng@chipadvanced.com + // end emily add for test + ////////////////////////////////////// + // Authenticate Fired + ////////////////////////////////////// + + hdmitx_hdcp_GetBCaps(&BCaps,&BStatus); + delay1ms(2); + if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) + { + HDCP_DEBUG_PRINTF(("HPD Before Fire Auth\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + hdmitx_hdcp_Auth_Fire(); + //delay1ms(550); // emily add for test + for(ii=0;ii<55;ii++) //delay1ms(550); // emily add for test + { + if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) + { + goto hdmitx_hdcp_Repeater_Fail ; + } + delay1ms(10); + } + for(TimeOut = /*250*6*/10 ; TimeOut > 0 ; TimeOut --) + { + HDCP_DEBUG_PRINTF(("TimeOut = %d wait part 1\n",TimeOut)); + if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) + { + HDCP_DEBUG_PRINTF(("HPD at wait part 1\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + uc = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1); + if(uc & B_TX_INT_DDC_BUS_HANG) + { + HDCP_DEBUG_PRINTF(("DDC Bus hang\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + uc = HDMITX_ReadI2C_Byte(REG_TX_INT_STAT2); + + if(uc & B_TX_INT_AUTH_FAIL) + { + /* + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); + */ + HDCP_DEBUG_PRINTF(("hdmitx_hdcp_Authenticate_Repeater(): B_TX_INT_AUTH_FAIL.\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + // emily add for test + // test =(HDMITX_ReadI2C_Byte(0x7)&0x4)>>2 ; + if(uc & B_TX_INT_KSVLIST_CHK) + { + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR0,B_TX_CLR_KSVLISTCHK); + HDMITX_WriteI2C_Byte(REG_TX_INT_CLR1,0); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,B_TX_INTACTDONE); + HDMITX_WriteI2C_Byte(REG_TX_SYS_STATUS,0); + HDCP_DEBUG_PRINTF(("B_TX_INT_KSVLIST_CHK\n")); + break ; + } + delay1ms(5); + } + if(TimeOut == 0) + { + HDCP_DEBUG_PRINTF(("Time out for wait KSV List checking interrupt\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + /////////////////////////////////////// + // clear KSVList check interrupt. + /////////////////////////////////////// + + for(TimeOut = 500 ; TimeOut > 0 ; TimeOut --) + { + HDCP_DEBUG_PRINTF(("TimeOut=%d at wait FIFO ready\n",TimeOut)); + if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) + { + HDCP_DEBUG_PRINTF(("HPD at wait FIFO ready\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + if(hdmitx_hdcp_GetBCaps(&BCaps,&BStatus) == ER_FAIL) + { + HDCP_DEBUG_PRINTF(("Get BCaps fail\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + if(BCaps & B_TX_CAP_KSV_FIFO_RDY) + { + HDCP_DEBUG_PRINTF(("FIFO Ready\n")); + break ; + } + delay1ms(5); + + } + if(TimeOut == 0) + { + HDCP_DEBUG_PRINTF(("Get KSV FIFO ready TimeOut\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } + HDCP_DEBUG_PRINTF(("Wait timeout = %d\n",TimeOut)); + + hdmitx_ClearDDCFIFO(); + hdmitx_GenerateDDCSCLK(); + cDownStream = (BStatus & M_TX_DOWNSTREAM_COUNT); + + if(/*cDownStream == 0 ||*/ cDownStream > 6 || BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER)) + { + HDCP_DEBUG_PRINTF(("Invalid Down stream count,fail\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } +#ifdef SUPPORT_SHA + if(hdmitx_hdcp_GetKSVList(KSVList,cDownStream) == ER_FAIL) + { + goto hdmitx_hdcp_Repeater_Fail ; + } +#if 0 + for(i = 0 ; i < cDownStream ; i++) + { + revoked=FALSE ; uc = 0 ; + for( TimeOut = 0 ; TimeOut < 5 ; TimeOut++ ) + { + // check bit count + uc += countbit(KSVList[i*5+TimeOut]); + } + if( uc != 20 ) revoked = TRUE ; + + if(revoked) + { +// HDCP_DEBUG_PRINTF(("KSVFIFO[%d] = %02X %02X %02X %02X %02X is revoked\n",i,(int)KSVList[i*5],(int)KSVList[i*5+1],(int)KSVList[i*5+2],(int)KSVList[i*5+3],(int)KSVList[i*5+4])); + goto hdmitx_hdcp_Repeater_Fail ; + } + } +#endif + + if(hdmitx_hdcp_GetVr(Vr) == ER_FAIL) + { + goto hdmitx_hdcp_Repeater_Fail ; + } + if(hdmitx_hdcp_GetM0(M0) == ER_FAIL) + { + goto hdmitx_hdcp_Repeater_Fail ; + } + // do check SHA + if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL) + { + goto hdmitx_hdcp_Repeater_Fail ; + } + if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&HDMITX_ReadI2C_Byte(REG_TX_INT_STAT1)) + { + HDCP_DEBUG_PRINTF(("HPD at Final\n")); + goto hdmitx_hdcp_Repeater_Fail ; + } +#endif // SUPPORT_SHA + + hdmitx_hdcp_ResumeRepeaterAuthenticate(); + hdmiTxDev[0].bAuthenticated = TRUE ; + return ER_SUCCESS ; + +hdmitx_hdcp_Repeater_Fail: + hdmitx_hdcp_CancelRepeaterAuthenticate(); + return ER_FAIL ; +} + +////////////////////////////////////////////////////////////////////// +// Function: hdmitx_hdcp_ResumeAuthentication +// Parameter: N/A +// Return: N/A +// Remark: called by interrupt handler to restart Authentication and Encryption. +// Side-Effect: as Authentication and Encryption. +////////////////////////////////////////////////////////////////////// + +void hdmitx_hdcp_ResumeAuthentication() +{ + setHDMITX_AVMute(TRUE); + if(hdmitx_hdcp_Authenticate() == ER_SUCCESS) + { + } + setHDMITX_AVMute(FALSE); +} + +#endif // SUPPORT_HDCP diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h new file mode 100755 index 000000000000..453149a26aa3 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_hdcp.h @@ -0,0 +1,87 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#ifndef _HDMITX_HDCP_H_ +#define _HDMITX_HDCP_H_ + + +#define REG_TX_HDCP_DESIRE 0x20 + #define B_TX_ENABLE_HDPC11 (1<<1) + #define B_TX_CPDESIRE (1<<0) + +#define REG_TX_AUTHFIRE 0x21 +#define REG_TX_LISTCTRL 0x22 + #define B_TX_LISTFAIL (1<<1) + #define B_TX_LISTDONE (1<<0) + +#define REG_TX_AKSV 0x23 +#define REG_TX_AKSV0 0x23 +#define REG_TX_AKSV1 0x24 +#define REG_TX_AKSV2 0x25 +#define REG_TX_AKSV3 0x26 +#define REG_TX_AKSV4 0x27 + +#define REG_TX_AN 0x28 +#define REG_TX_AN_GEN 0x30 +#define REG_TX_ARI 0x38 +#define REG_TX_ARI0 0x38 +#define REG_TX_ARI1 0x39 +#define REG_TX_APJ 0x3A + +#define REG_TX_BKSV 0x3B +#define REG_TX_BRI 0x40 +#define REG_TX_BRI0 0x40 +#define REG_TX_BRI1 0x41 +#define REG_TX_BPJ 0x42 +#define REG_TX_BCAP 0x43 + #define B_TX_CAP_HDMI_REPEATER (1<<6) + #define B_TX_CAP_KSV_FIFO_RDY (1<<5) + #define B_TX_CAP_HDMI_FAST_MODE (1<<4) + #define B_CAP_HDCP_1p1 (1<<1) + #define B_TX_CAP_FAST_REAUTH (1<<0) +#define REG_TX_BSTAT 0x44 +#define REG_TX_BSTAT0 0x44 +#define REG_TX_BSTAT1 0x45 + #define B_TX_CAP_HDMI_MODE (1<<12) + #define B_TX_CAP_DVI_MODE (0<<12) + #define B_TX_MAX_CASCADE_EXCEEDED (1<<11) + #define M_TX_REPEATER_DEPTH (0x7<<8) + #define O_TX_REPEATER_DEPTH 8 + #define B_TX_DOWNSTREAM_OVER (1<<7) + #define M_TX_DOWNSTREAM_COUNT 0x7F + +#define REG_TX_AUTH_STAT 0x46 +#define B_TX_AUTH_DONE (1<<7) +//////////////////////////////////////////////////// +// Function Prototype +//////////////////////////////////////////////////// + +BOOL getHDMITX_AuthenticationDone(); +void hdmitx_hdcp_ClearAuthInterrupt(); +void hdmitx_hdcp_ResetAuth(); +void hdmitx_hdcp_Auth_Fire(); +void hdmitx_hdcp_StartAnCipher(); +void hdmitx_hdcp_StopAnCipher(); +void hdmitx_hdcp_GenerateAn(); +SYS_STATUS hdmitx_hdcp_GetBCaps(PBYTE pBCaps ,PUSHORT pBStatus); +SYS_STATUS hdmitx_hdcp_GetBKSV(BYTE *pBKSV); + +void hdmitx_hdcp_Reset(); +SYS_STATUS hdmitx_hdcp_Authenticate(); +SYS_STATUS hdmitx_hdcp_VerifyIntegration(); +void hdmitx_hdcp_CancelRepeaterAuthenticate(); +void hdmitx_hdcp_ResumeRepeaterAuthenticate(); +SYS_STATUS hdmitx_hdcp_CheckSHA(BYTE pM0[],USHORT BStatus,BYTE pKSVList[],int cDownStream,BYTE Vr[]); +SYS_STATUS hdmitx_hdcp_GetKSVList(BYTE *pKSVList,BYTE cDownStream); +SYS_STATUS hdmitx_hdcp_GetVr(BYTE *pVr); +SYS_STATUS hdmitx_hdcp_GetM0(BYTE *pM0); +SYS_STATUS hdmitx_hdcp_Authenticate_Repeater(); +void hdmitx_hdcp_ResumeAuthentication(); +#endif // _HDMITX_HDCP_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c new file mode 100755 index 000000000000..f9662f553190 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.c @@ -0,0 +1,190 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#include "hdmitx.h" +#include "hdmitx_drv.h" + +#ifdef HDMITX_INPUT_INFO +extern HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT] ; + +LONG CalcRCLK(); +LONG CalcAudFS(); +LONG CalcRCLK(); + +#define InitCEC() HDMITX_SetI2C_Byte(0x0F, 0x08, 0x00) +#define DisableCEC() HDMITX_SetI2C_Byte(0x0F, 0x08, 0x08) + +LONG CalcAudFS() +{ + // LONG RCLK ; + LONG Cnt ; + LONG FS ; + + // RCLK = CalcRCLK(); + Switch_HDMITX_Bank(0); + Cnt = (LONG)HDMITX_ReadI2C_Byte(0x60); + FS = hdmiTxDev[0].RCLK / 2 ; + FS /= Cnt ; + HDMITX_DEBUG_PRINTF1(("FS = %ld RCLK = %ld, Cnt = %ld\n",FS,hdmiTxDev[0].RCLK,Cnt)) ; + return FS ; +} + +LONG CalcPCLK() +{ + BYTE uc, div ; + int i ; + long sum , count, PCLK ; + + Switch_HDMITX_Bank(0); + uc = HDMITX_ReadI2C_Byte(0x5F) & 0x80 ; + + if( ! uc ) + { + return 0 ; + } + // InitCEC(); + // // uc = CEC_ReadI2C_Byte(0x09) & 0xFE ; + // CEC_WriteI2C_Byte(0x09, 1); + // delay1ms(100); + // CEC_WriteI2C_Byte(0x09, 0); + // RCLK = CEC_ReadI2C_Byte(0x47); + // RCLK <<= 8 ; + // RCLK |= CEC_ReadI2C_Byte(0x46); + // RCLK <<= 8 ; + // RCLK |= CEC_ReadI2C_Byte(0x45); + // DisableCEC(); + // // RCLK *= 160 ; // RCLK /= 100 ; + // // RCLK in KHz. + + HDMITX_SetI2C_Byte(0xD7, 0xF0, 0x80); + delay1ms(1); + HDMITX_SetI2C_Byte(0xD7, 0x80, 0x00); + + count = HDMITX_ReadI2C_Byte(0xD7) & 0xF ; + count <<= 8 ; + count |= HDMITX_ReadI2C_Byte(0xD8); + + for( div = 7 ; div > 0 ; div-- ) + { + // printf("div = %d\n",(int)div) ; + if(count < (1<<(11-div)) ) + { + break ; + } + } + HDMITX_SetI2C_Byte(0xD7, 0x70, div<<4); + + uc = HDMITX_ReadI2C_Byte(0xD7) & 0x7F ; + for( i = 0 , sum = 0 ; i < 100 ; i ++ ) + { + HDMITX_WriteI2C_Byte(0xD7, uc|0x80) ; + delay1ms(1); + HDMITX_WriteI2C_Byte(0xD7, uc) ; + + count = HDMITX_ReadI2C_Byte(0xD7) & 0xF ; + count <<= 8 ; + count |= HDMITX_ReadI2C_Byte(0xD8); + sum += count ; + } + sum /= 100 ; count = sum ; + + HDMITX_DEBUG_PRINTF1(("RCLK(in GetPCLK) = %ld\n",hdmiTxDev[0].RCLK)); + HDMITX_DEBUG_PRINTF1(("div = %d, count = %d\n",(int)div,(int)count) ); + HDMITX_DEBUG_PRINTF1(("count = %ld\n",count) ); + + PCLK = hdmiTxDev[0].RCLK * 128 / count * 16 ; + PCLK *= (1<> 4 ; + HDMITX_SetI2C_Byte(0xA8,8,0) ; + return hTotal ; +} + +USHORT hdmitx_getInputVTotal() +{ + BYTE uc ; + USHORT vTotal ; + HDMITX_SetI2C_Byte(0x0F,1,0) ; + HDMITX_SetI2C_Byte(0xA8,8,8) ; + + uc = HDMITX_ReadI2C_Byte(0x99) ; + vTotal = ((USHORT)uc&0xF)<<8 ; + uc = HDMITX_ReadI2C_Byte(0x98) ; + vTotal |= uc; + HDMITX_SetI2C_Byte(0xA8,8,0) ; + return vTotal ; +} + +BOOL hdmitx_isInputInterlace() +{ + BYTE uc ; + + HDMITX_SetI2C_Byte(0x0F,1,0) ; + HDMITX_SetI2C_Byte(0xA8,8,8) ; + + uc = HDMITX_ReadI2C_Byte(0xA5) ; + HDMITX_SetI2C_Byte(0xA8,8,0) ; + return uc&(1<<4)?TRUE:FALSE ; +} + +BYTE hdmitx_getAudioCount() +{ + return HDMITX_ReadI2C_Byte(REG_TX_AUD_COUNT) ; +} +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h new file mode 100755 index 000000000000..b28ce9409658 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_input.h @@ -0,0 +1,26 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ +#ifndef _HDMITX_DEBUG_H_ +#define _HDMITX_DEBUG_H_ + + +#ifdef HDMITX_INPUT_INFO +LONG CalcPCLK(); +LONG CalcAudFS(); +LONG CalcRCLK(); +BYTE hdmitx_getAudioCount() ; + +USHORT hdmitx_getInputHTotal(); +USHORT hdmitx_getInputVTotal(); +BOOL hdmitx_isInputInterlace(); +#endif + +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.c b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.c new file mode 100755 index 000000000000..5ffb5abd1bac --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.c @@ -0,0 +1,1371 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// This is the sample program for CAT6611 driver usage. +/////////////////////////////////////////////////////////////////////////////// +#include +#include + +#include "hdmitx.h" +#include "hdmitx_sys.h" + +_CODE HDMITXDEV InstanceData = +{ + + 0, // BYTE I2C_DEV ; + HDMI_TX_I2C_SLAVE_ADDR, // BYTE I2C_ADDR ; + + ///////////////////////////////////////////////// + // Interrupt Type + ///////////////////////////////////////////////// + 0x40, // BYTE bIntType ; // = 0 ; + ///////////////////////////////////////////////// + // Video Property + ///////////////////////////////////////////////// + INPUT_SIGNAL_TYPE ,// BYTE bInputVideoSignalType ; // for Sync Embedded,CCIR656,InputDDR + + ///////////////////////////////////////////////// + // Audio Property + ///////////////////////////////////////////////// + I2S_FORMAT, // BYTE bOutputAudioMode ; // = 0 ; + FALSE , // BYTE bAudioChannelSwap ; // = 0 ; + 0x01, // BYTE bAudioChannelEnable ; + INPUT_SAMPLE_FREQ ,// BYTE bAudFs ; + 0, // unsigned long TMDSClock ; + FALSE, // BYTE bAuthenticated:1 ; + FALSE, // BYTE bHDMIMode: 1; + FALSE, // BYTE bIntPOL:1 ; // 0 = Low Active + FALSE, // BYTE bHPD:1 ; +}; + +#ifdef HDMITX_INPUT_INFO +// HDMI_VTiming currVTiming ; +//////////////////////////////////////////////////////////////////////////////// +// HDMI VTable +//////////////////////////////////////////////////////////////////////////////// +static HDMI_VTiming _CODE s_VMTable[] = { + + { 1,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},//640x480@60Hz + { 2,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz + { 3,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz + { 4,0,1280,720,1650,750,74250000L,0x2E,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@60Hz + { 5,0,1920,540,2200,562,74250000L,0x2E,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@60Hz + { 6,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz + { 7,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz + { 8,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz + { 9,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz + {10,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz + {11,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz + {12,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz + {13,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz + {14,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz + {15,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz + {16,0,1920,1080,2200,1125,148500000L,0x17,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@60Hz + {17,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz + {18,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz + {19,0,1280,720,1980,750,74250000L,0x2E,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@50Hz + {20,0,1920,540,2640,562,74250000L,0x2E,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@50Hz + {21,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz + {22,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz + {23,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz + {24,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz + {25,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz + {26,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz + {27,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz + {28,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz + {29,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz + {30,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz + {31,0,1920,1080,2640,1125,148500000L,0x17,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@50Hz + {32,0,1920,1080,2750,1125,74250000L,0x2E,638,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@24Hz + {33,0,1920,1080,2640,1125,74250000L,0x2E,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@25Hz + {34,0,1920,1080,2200,1125,74250000L,0x2E,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@30Hz + + {35,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz + {36,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz + {37,1,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz + {38,2,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz + + {39,0,1920,540,2304,625,72000000L,0x17,32,168,184,23,5,57,INTERLACE,Vneg,Hpos},//1920x1080@50Hz + // 100Hz + {40,0,1920,540,2640,562,148500000L,0x17,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@100Hz + {41,0,1280,720,1980,750,148500000L,0x17,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@100Hz + {42,0,720,576,864,625, 54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz + {43,0,720,576,864,625, 54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz + {44,1,720,288,864,312, 27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz + {45,1,720,288,864,312, 27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz + // 120Hz + {46,0,1920,540,2200,562,148500000L,0x17,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@120Hz + {47,0,1280,720,1650,750,148500000L,0x17,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@120Hz + {48,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz + {49,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz + {50,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz + {51,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz + + // 200Hz + {52,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz + {53,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz + {54,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz + {55,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz + // 240Hz + {56,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz + {57,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz + {58,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz + {59,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz + // 720p low resolution + {60,0,1280, 720,3300, 750, 59400000L,0x3A,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@24Hz + {61,0,1280, 720,3960, 750, 74250000L,0x2E,2420,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@25Hz + {62,0,1280, 720,3300, 750, 74250000L,0x2E,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@30Hz + // 1080p high refresh rate + {63,0,1920,1080,2200,1125,297000000L,0x0B, 88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@120Hz + {64,0,1920,1080,2640,1125,297000000L,0x0B,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@100Hz + // VESA mode + {0,0,640,350,832,445,31500000L,0x6D,32,64,96,32,3,60,PROG,Vneg,Hpos},// 640x350@85 + {0,0,640,400,832,445,31500000L,0x6D,32,64,96,1,3,41,PROG,Vneg,Hneg},// 640x400@85 + {0,0,832,624,1152,667,57283000L,0x3C,32,64,224,1,3,39,PROG,Vneg,Hneg},// 832x624@75Hz + {0,0,720,350,900,449,28322000L,0x7A,18,108,54,59,2,38,PROG,Vneg,Hneg},// 720x350@70Hz + {0,0,720,400,900,449,28322000L,0x7A,18,108,54,13,2,34,PROG,Vpos,Hneg},// 720x400@70Hz + {0,0,720,400,936,446,35500000L,0x61,36,72,108,1,3,42,PROG,Vpos,Hneg},// 720x400@85 + {0,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},// 640x480@60 + {0,0,640,480,832,520,31500000L,0x6D,24,40,128,9,3,28,PROG,Vneg,Hneg},// 640x480@72 + {0,0,640,480,840,500,31500000L,0x6D,16,64,120,1,3,16,PROG,Vneg,Hneg},// 640x480@75 + {0,0,640,480,832,509,36000000L,0x60,56,56,80,1,3,25,PROG,Vneg,Hneg},// 640x480@85 + {0,0,800,600,1024,625,36000000L,0x60,24,72,128,1,2,22,PROG,Vpos,Hpos},// 800x600@56 + {0,0,800,600,1056,628,40000000L,0x56,40,128,88,1,4,23,PROG,Vpos,Hpos},// 800x600@60 + {0,0,800,600,1040,666,50000000L,0x45,56,120,64,37,6,23,PROG,Vpos,Hpos},// 800x600@72 + {0,0,800,600,1056,625,49500000L,0x45,16,80,160,1,3,21,PROG,Vpos,Hpos},// 800x600@75 + {0,0,800,600,1048,631,56250000L,0x3D,32,64,152,1,3,27,PROG,Vpos,Hpos},// 800X600@85 + {0,0,848,480,1088,517,33750000L,0x66,16,112,112,6,8,23,PROG,Vpos,Hpos},// 840X480@60 + {0,0,1024,384,1264,408,44900000L,0x4C,8,176,56,0,4,20,INTERLACE,Vpos,Hpos},//1024x768(I)@87Hz + {0,0,1024,768,1344,806,65000000L,0x35,24,136,160,3,6,29,PROG,Vneg,Hneg},// 1024x768@60 + {0,0,1024,768,1328,806,75000000L,0x2E,24,136,144,3,6,29,PROG,Vneg,Hneg},// 1024x768@70 + {0,0,1024,768,1312,800,78750000L,0x2B,16,96,176,1,3,28,PROG,Vpos,Hpos},// 1024x768@75 + {0,0,1024,768,1376,808,94500000L,0x24,48,96,208,1,3,36,PROG,Vpos,Hpos},// 1024x768@85 + {0,0,1152,864,1600,900,108000000L,0x20,64,128,256,1,3,32,PROG,Vpos,Hpos},// 1152x864@75 + {0,0,1280,768,1440,790,68250000L,0x32,48,32,80,3,7,12,PROG,Vneg,Hpos},// 1280x768@60-R + {0,0,1280,768,1664,798,79500000L,0x2B,64,128,192,3,7,20,PROG,Vpos,Hneg},// 1280x768@60 + {0,0,1280,768,1696,805,102250000L,0x21,80,128,208,3,7,27,PROG,Vpos,Hneg},// 1280x768@75 + {0,0,1280,768,1712,809,117500000L,0x1D,80,136,216,3,7,31,PROG,Vpos,Hneg},// 1280x768@85 + + {0,0,1280,800,1440, 823, 71000000L,0x31, 48, 32, 80,3,6,14,PROG,Vpos,Hneg},// 1280x800@60Hz + {0,0,1280,800,1680, 831, 83500000L,0x29, 72,128,200,3,6,22,PROG,Vpos,Hneg},// 1280x800@60Hz + {0,0,1280,800,1696, 838,106500000L,0x20, 80,128,208,3,6,29,PROG,Vpos,Hneg},// 1280x800@75Hz + {0,0,1280,800,1712, 843,122500000L,0x1C, 80,136,216,3,6,34,PROG,Vpos,Hneg},// 1280x800@85Hz + + + {0,0,1280,960,1800,1000,108000000L,0x20,96,112,312,1,3,36,PROG,Vpos,Hpos},// 1280x960@60 + {0,0,1280,960,1728,1011,148500000L,0x17,64,160,224,1,3,47,PROG,Vpos,Hpos},// 1280x960@85 + {0,0,1280,1024,1688,1066,108000000L,0x20,48,112,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@60 + {0,0,1280,1024,1688,1066,135000000L,0x19,16,144,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@75 + {0,0,1280,1024,1728,1072,157500000L,0x15,64,160,224,1,3,44,PROG,Vpos,Hpos},// 1280X1024@85 + {0,0,1360,768,1792,795,85500000L,0x28,64,112,256,3,6,18,PROG,Vpos,Hpos},// 1360X768@60 + + {0,0,1366,768,1792,798,85500000L,0x28, 70,143,213,3,3,24,PROG,Vpos,Hpos},// 1366X768@60 + {0,0,1366,768,1500,800,72000000L,0x30, 14, 56, 64,1,3,28,PROG,Vpos,Hpos},// 1360X768@60 + {0,0,1400,1050,1560,1080,101000000L,0x22,48,32,80,3,4,23,PROG,Vneg,Hpos},// 1400x768@60-R + {0,0,1400,1050,1864,1089,121750000L,0x1C,88,144,232,3,4,32,PROG,Vpos,Hneg},// 1400x768@60 + {0,0,1400,1050,1896,1099,156000000L,0x16,104,144,248,3,4,42,PROG,Vpos,Hneg},// 1400x1050@75 + {0,0,1400,1050,1912,1105,179500000L,0x13,104,152,256,3,4,48,PROG,Vpos,Hneg},// 1400x1050@85 + {0,0,1440,900,1600,926,88750000L,0x26,48,32,80,3,6,17,PROG,Vneg,Hpos},// 1440x900@60-R + {0,0,1440,900,1904,934,106500000L,0x20,80,152,232,3,6,25,PROG,Vpos,Hneg},// 1440x900@60 + {0,0,1440,900,1936,942,136750000L,0x19,96,152,248,3,6,33,PROG,Vpos,Hneg},// 1440x900@75 + {0,0,1440,900,1952,948,157000000L,0x16,104,152,256,3,6,39,PROG,Vpos,Hneg},// 1440x900@85 + {0,0,1600,1200,2160,1250,162000000L,0x15,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@60 + {0,0,1600,1200,2160,1250,175500000L,0x13,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@65 + {0,0,1600,1200,2160,1250,189000000L,0x12,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@70 + {0,0,1600,1200,2160,1250,202500000L,0x11,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@75 + {0,0,1600,1200,2160,1250,229500000L,0x0F,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@85 + {0,0,1680,1050,1840,1080,119000000L,0x1D,48,32,80,3,6,21,PROG,Vneg,Hpos},// 1680x1050@60-R + {0,0,1680,1050,2240,1089,146250000L,0x17,104,176,280,3,6,30,PROG,Vpos,Hneg},// 1680x1050@60 + {0,0,1680,1050,2272,1099,187000000L,0x12,120,176,296,3,6,40,PROG,Vpos,Hneg},// 1680x1050@75 + {0,0,1680,1050,2288,1105,214750000L,0x10,128,176,304,3,6,46,PROG,Vpos,Hneg},// 1680x1050@85 + {0,0,1792,1344,2448,1394,204750000L,0x10,128,200,328,1,3,46,PROG,Vpos,Hneg},// 1792x1344@60 + {0,0,1792,1344,2456,1417,261000000L,0x0D,96,216,352,1,3,69,PROG,Vpos,Hneg},// 1792x1344@75 + {0,0,1856,1392,2528,1439,218250000L,0x0F,96,224,352,1,3,43,PROG,Vpos,Hneg},// 1856x1392@60 + {0,0,1856,1392,2560,1500,288000000L,0x0C,128,224,352,1,3,104,PROG,Vpos,Hneg},// 1856x1392@75 + {0,0,1920,1200,2080,1235,154000000L,0x16,48,32,80,3,6,26,PROG,Vneg,Hpos},// 1920x1200@60-R + {0,0,1920,1200,2592,1245,193250000L,0x11,136,200,336,3,6,36,PROG,Vpos,Hneg},// 1920x1200@60 + {0,0,1920,1200,2608,1255,245250000L,0x0E,136,208,344,3,6,46,PROG,Vpos,Hneg},// 1920x1200@75 + {0,0,1920,1200,2624,1262,281250000L,0x0C,144,208,352,3,6,53,PROG,Vpos,Hneg},// 1920x1200@85 + {0,0,1920,1440,2600,1500,234000000L,0x0E,128,208,344,1,3,56,PROG,Vpos,Hneg},// 1920x1440@60 + {0,0,1920,1440,2640,1500,297000000L,0x0B,144,224,352,1,3,56,PROG,Vpos,Hneg},// 1920x1440@75 +}; +#define SizeofVMTable (sizeof(s_VMTable)/sizeof(HDMI_VTiming)) + +void HDMITX_MonitorInputVideoChange(); +void HDMITX_MonitorInputAudioChange(); + +#else +#define SizeofVMTable 0 +#endif + +#define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a))) + +//////////////////////////////////////////////////////////////////////////////// +// EDID +//////////////////////////////////////////////////////////////////////////////// +static _XDATA RX_CAP RxCapability ; +static BOOL bChangeMode = FALSE ; +static BOOL bChangeAudio = FALSE ; + +_XDATA unsigned char CommunBuff[128] ; +// _XDATA AVI_InfoFrame AviInfo; +// _XDATA Audio_InfoFrame AudioInfo ; +// _XDATA VendorSpecific_InfoFrame VS_Info; +_CODE BYTE CA[] = { 0,0,0, 02, 0x3, 0x7, 0xB, 0xF, 0x1F } ; +//////////////////////////////////////////////////////////////////////////////// +// Program utility. +//////////////////////////////////////////////////////////////////////////////// + + +BYTE bInputColorMode = INPUT_COLOR_MODE; +BYTE OutputColorDepth = INPUT_COLOR_DEPTH ; +BYTE bOutputColorMode = OUTPUT_COLOR_MODE ; + +BYTE iVideoModeSelect=0 ; + +ULONG VideoPixelClock ; +BYTE VIC ; // 480p60 +BYTE pixelrep ; // no pixelrepeating +HDMI_Aspec aspec ; +HDMI_Colorimetry Colorimetry ; + +ULONG ulAudioSampleFS = INPUT_SAMPLE_FREQ_HZ ; +// BYTE bAudioSampleFreq = INPUT_SAMPLE_FREQ ; +BYTE bOutputAudioChannel = OUTPUT_CHANNEL ; + +BOOL bHDMIMode; +BYTE bAudioEnable ; +BYTE HPDStatus = FALSE; +BYTE HPDChangeStatus = FALSE; +BYTE bOutputAudioType=CNOFIG_INPUT_AUDIO_TYPE; +//////////////////////////////////////////////////////////////////////////////// +// Function Prototype. +//////////////////////////////////////////////////////////////////////////////// +BYTE ParseEDID(); +static BOOL ParseCEAEDID(BYTE *pCEAEDID); +void ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep); +void ConfigAudioInfoFrm(); +void Config_GeneralPurpose_Infoframe(BYTE *p3DInfoFrame); +void ConfigfHdmiVendorSpecificInfoFrame(BYTE _3D_Stru); +void InitHDMITX_Variable(); +void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode); +void HDMITX_SetOutput(); +int HDMITX_DevLoopProc(); +//////////////////////////////////////////////////////////////////////////////// +// Function Body. +//////////////////////////////////////////////////////////////////////////////// + +void InitHDMITX_Variable() +{ + printk( "[%s]\n", __FUNCTION__); + HDMITX_InitTxDev(&InstanceData); + HPDStatus = FALSE; + HPDChangeStatus = FALSE; +} + +BOOL AudioModeDetect(void) +{ + setHDMITX_AudioChannelEnable(bAudioEnable); + return TRUE; +} + +void HDMITX_ChangeColorDepth(BYTE colorDepth) +{ +#ifdef IT6615 + HDMITX_DEBUG_PRINTF(("OHDMITX_ChangeColorDepth(%02X)\n",(int)colorDepth)) ; + OutputColorDepth = colorDepth ; +#else + OutputColorDepth = 0 ; +#endif +} + +void HDMITX_SetOutput() +{ + VIDEOPCLKLEVEL level ; + unsigned long TMDSClock = VideoPixelClock*(pixelrep+1); + HDMITX_DisableAudioOutput(); + HDMITX_EnableHDCP(FALSE); + + if( TMDSClock>80000000L ) + { + level = PCLK_HIGH ; + } + else if(TMDSClock>20000000L) + { + level = PCLK_MEDIUM ; + } + else + { + level = PCLK_LOW ; + } +#ifdef IT6615 + HDMITX_DEBUG_PRINTF(("OutputColorDepth = %02X\n",(int)OutputColorDepth)) ; + setHDMITX_ColorDepthPhase(OutputColorDepth,0); +#endif + + setHDMITX_VideoSignalType(InstanceData.bInputVideoSignalType); + #ifdef SUPPORT_SYNCEMBEDDED + if(InstanceData.bInputVideoSignalType & T_MODE_SYNCEMB) + { + setHDMITX_SyncEmbeddedByVIC(VIC,InstanceData.bInputVideoSignalType); + } + #endif + + HDMITX_DEBUG_PRINTF(("level = %d, ,bInputColorMode=%x,bOutputColorMode=%x,bHDMIMode=%x\n",(int)level,(int)bInputColorMode,(int)bOutputColorMode ,(int)bHDMIMode)) ; + HDMITX_EnableVideoOutput(level,bInputColorMode,bOutputColorMode ,bHDMIMode); + + if( bHDMIMode ) + { + #ifdef OUTPUT_3D_MODE + ConfigfHdmiVendorSpecificInfoFrame(OUTPUT_3D_MODE); + #endif + //HDMITX_EnableHDCP(TRUE); + ConfigAVIInfoFrame(VIC, pixelrep); + + HDMITX_SetAudioOutput(); + + // if( bAudioEnable ) + // { + // ConfigAudioInfoFrm(); + // #ifdef SUPPORT_HBR_AUDIO + // HDMITX_EnableAudioOutput(T_AUDIO_HBR, CONFIG_INPUT_AUDIO_SPDIF, 768000L,8,NULL,TMDSClock); + // #else + // // HDMITX_EnableAudioOutput(T_AUDIO_LPCM, FALSE, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock); + // HDMITX_EnableAudioOutput(CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_SPDIF, ulAudioSampleFS,bOutputAudioChannel,NULL,TMDSClock); + // #endif + // } + + } + else + { + HDMITX_EnableAVIInfoFrame(FALSE ,NULL); + HDMITX_EnableVSInfoFrame(FALSE,NULL); + } + setHDMITX_AVMute(FALSE); + bChangeMode = FALSE ; + DumpHDMITXReg() ; +} + +void HDMITX_ChangeAudioOption(BYTE Option, BYTE channelNum, BYTE AudioFs) +{ + + switch(Option ) + { + case T_AUDIO_HBR : + bOutputAudioType = T_AUDIO_HBR ; + ulAudioSampleFS = 768000L ; + bOutputAudioChannel = 8 ; + return ; + case T_AUDIO_NLPCM : + bOutputAudioType = T_AUDIO_NLPCM ; + bOutputAudioChannel = 2 ; + break ; + default: + bOutputAudioType = T_AUDIO_LPCM ; + if( channelNum < 1 ) + { + bOutputAudioChannel = 1 ; + } + else if( channelNum > 8 ) + { + bOutputAudioChannel = 8 ; + } + else + { + bOutputAudioChannel = channelNum ; + } + break ; + } + + switch(AudioFs) + { + case AUDFS_44p1KHz: + ulAudioSampleFS = 44100L ; + break ; + case AUDFS_88p2KHz: + ulAudioSampleFS = 88200L ; + break ; + case AUDFS_176p4KHz: + ulAudioSampleFS = 176400L ; + break ; + + case AUDFS_48KHz: + ulAudioSampleFS = 48000L ; + break ; + case AUDFS_96KHz: + ulAudioSampleFS = 96000L ; + break ; + case AUDFS_192KHz: + ulAudioSampleFS = 192000L ; + break ; + + case AUDFS_768KHz: + ulAudioSampleFS = 768000L ; + break ; + + case AUDFS_32KHz: + ulAudioSampleFS = 32000L ; + break ; + default: + ulAudioSampleFS = 48000L ; + break ; + } + HDMITX_DEBUG_PRINTF(("HDMITX_ChangeAudioOption():bOutputAudioType = %02X, ulAudioSampleFS = %8ld, bOutputAudioChannel = %d\n",(int)bOutputAudioType,ulAudioSampleFS,(int)bOutputAudioChannel)) ; + bChangeAudio = TRUE ; +} + +void HDMITX_SetAudioOutput() +{ + if( bAudioEnable ) + { + ConfigAudioInfoFrm(); + // HDMITX_EnableAudioOutput(T_AUDIO_LPCM, FALSE, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock); + HDMITX_EnableAudioOutput( + //CNOFIG_INPUT_AUDIO_TYPE, + bOutputAudioType, + CONFIG_INPUT_AUDIO_SPDIF, + ulAudioSampleFS, + bOutputAudioChannel, + NULL, // pointer to cahnnel status. + VideoPixelClock*(pixelrep+1)); + // if you have channel status , set here. + // setHDMITX_ChStat(BYTE ucIEC60958ChStat[]); + bChangeAudio = FALSE ; + } +} + +int HDMITX_DevLoopProc() +{ + static BYTE DevLoopCount = 0 ; + CheckHDMITX(&HPDStatus,&HPDChangeStatus); + + if( HPDChangeStatus ) + { + if( HPDStatus ) + { + HDMITX_PowerOn(); + ParseEDID(); + bOutputColorMode = F_MODE_RGB444; + + if( RxCapability.ValidHDMI ) + { + bHDMIMode = TRUE ; + + if(RxCapability.VideoMode & (1<<6)) + { + bAudioEnable = TRUE ; + } + if( RxCapability.VideoMode & (1<<5)) + { + bOutputColorMode &= ~F_MODE_CLRMOD_MASK ; + bOutputColorMode |= F_MODE_YUV444; + } + else if (RxCapability.VideoMode & (1<<4)) + { + bOutputColorMode &= ~F_MODE_CLRMOD_MASK ; + bOutputColorMode |= F_MODE_YUV422 ; + } + + #ifdef IT6615 + if(RxCapability.dc.uc & (HDMI_DC_SUPPORT_36|HDMI_DC_SUPPORT_30)) + { + setHDMITX_ColorDepthPhase(OutputColorDepth,0); + } + else + { + OutputColorDepth = B_TX_CD_NODEF; + } + #else + OutputColorDepth = B_TX_CD_NODEF; + #endif + } + else + { + bHDMIMode = FALSE ; + bAudioEnable = FALSE ; + OutputColorDepth = B_TX_CD_NODEF; + // HDMITX_DisableAudioOutput(); + // HDMITX_DisableVideoOutput(); + #ifdef SUPPORT_HDCP + HDMITX_EnableHDCP(FALSE); + #endif + } + HDMITX_DEBUG_PRINTF(("HPD change HDMITX_SetOutput();\n")); + //HDMITX_SetOutput(); + bChangeMode=TRUE; + bChangeAudio = TRUE ; + } + else + { + // unplug mode, ... + HDMITX_DEBUG_PRINTF(("HPD OFF HDMITX_DisableVideoOutput()\n")); + HDMITX_DisableVideoOutput(); + HDMITX_PowerDown(); + bChangeAudio = FALSE ; + } + } + else // no stable but need to process mode change procedure + { + if( DevLoopCount >= 20 ) + { + DevLoopCount = 0 ; + } + + #ifdef HDMITX_AUTO_MONITOR_INPUT + if( DevLoopCount == 0 ) + { + HDMITX_MonitorInputVideoChange(); + HDMITX_MonitorInputAudioChange(); + } + #endif + + if(HPDStatus) + { + #ifdef HDMITX_AUTO_MONITOR_INPUT + if( bChangeMode && ( VIC > 0 ) ) + #else + if( bChangeMode ) + #endif + { + HDMITX_DEBUG_PRINTF(("Mode change HDMITX_SetOutput();\n")); + HDMITX_SetOutput(); + // HDMITX_EnableHDCP(TRUE); + + bChangeMode = FALSE ; + } + if(getHDMITX_LinkStatus()) + { + // AudioModeDetect(); + #ifdef SUPPORT_HDCP + if(getHDMITX_AuthenticationDone() ==FALSE) + { + HDMITX_DEBUG_PRINTF(("getHDMITX_AuthenticationDone() ==FALSE\n") ); + HDMITX_EnableHDCP(TRUE); + setHDMITX_AVMute(FALSE); + } + #endif + } + + if(bChangeAudio) + { + HDMITX_SetAudioOutput() ; + } + } + } + + DevLoopCount ++ ; + return HPDStatus; +} + +#ifdef HDMITX_AUTO_MONITOR_INPUT + +void HDMITX_MonitorInputAudioChange() +{ + static ULONG prevAudioSampleFS = 0 ; + LONG AudioFS ; + + if( !bAudioEnable ) + { + prevAudioSampleFS = 0 ; + } + else + { + AudioFS = CalcAudFS() ; + HDMITX_DEBUG_PRINTF1(("Audio Chagne, Audio clock = %ldHz\n",AudioFS)) ; + if( AudioFS > 188000L ) // 192KHz + { + ulAudioSampleFS = 192000L ; + } + else if( AudioFS > 144000L ) // 176.4KHz + { + ulAudioSampleFS = 176400L ; + } + else if( AudioFS > 93000L ) // 96KHz + { + ulAudioSampleFS = 96000L ; + } + else if( AudioFS > 80000L ) // 88.2KHz + { + ulAudioSampleFS = 88200L ; + } + else if( AudioFS > 45000L ) // 48 KHz + { + ulAudioSampleFS = 48000L ; + } + else if( AudioFS > 36000L ) // 44.1KHz + { + ulAudioSampleFS = 44100L ; + } + else // 32KHz + { + ulAudioSampleFS = 32000L ; + } + + if(!bChangeMode) + { + if( ulAudioSampleFS != prevAudioSampleFS ) + { + HDMITX_DEBUG_PRINTF(("ulAudioSampleFS = %ldHz -> %ldHz\n",ulAudioSampleFS,ulAudioSampleFS)) ; + ConfigAudioInfoFrm(); + HDMITX_EnableAudioOutput(CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_SPDIF, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0); + // HDMITX_EnableAudioOutput(T_AUDIO_LPCM, FALSE, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0); + + } + } + + prevAudioSampleFS = ulAudioSampleFS ; + + } +} + +int HDMITX_SearchVICIndex( ULONG PCLK, USHORT HTotal, USHORT VTotal, BYTE ScanMode ) +{ + #define SEARCH_COUNT 4 + unsigned long pclkDiff; + int i; + char hit; + int iMax[SEARCH_COUNT]={0}; + char hitMax[SEARCH_COUNT]={0}; + char i2; + + for( i = 0 ; i < SizeofVMTable; i++ ) + { + if( s_VMTable[i].VIC == 0 ) break ; + + hit=0; + + if( ScanMode == s_VMTable[i].ScanMode ) + { + hit++; + + if( ScanMode == INTERLACE ) + { + if( DIFF(VTotal/2, s_VMTable[i].VTotal) < 10 ) + { + hit++; + } + } + else + { + if( DIFF(VTotal, s_VMTable[i].VTotal) < 10 ) + { + hit++; + } + } + + if( hit == 2 ) // match scan mode and v-total + { + if( DIFF(HTotal, s_VMTable[i].HTotal) < 40 ) + { + hit++; + + pclkDiff = DIFF(PCLK, s_VMTable[i].PCLK); + pclkDiff = (pclkDiff * 100) / s_VMTable[i].PCLK; + + if( pclkDiff < 100 ) + { + hit += ( 100 - pclkDiff ); + } + } + } + } + + HDMITX_DEBUG_PRINTF(("i = %d, hit = %d\n",i,(int)hit)); + + if( hit ) + { + for( i2=0 ; i2 %d\n",(int)i2, iMax[i2], i )); + hitMax[i2] = hit; + iMax[i2]=i; + break; + } + } + } + } + + i=-1; + hit=0; + for( i2=0 ; i2 hit ) + { + hit = hitMax[i2]; + i = iMax[i2]; + } + } + + if( hit > 2 ) + { + HDMITX_DEBUG_PRINTF(("i = %d, hit = %d\n",i,(int)hit)); + HDMITX_DEBUG_PRINTF((">> mode : %d %u x %u @%lu (%s)\n", (int)s_VMTable[i].VIC, s_VMTable[i].HActive, s_VMTable[i].VActive, s_VMTable[i].PCLK, (s_VMTable[i].ScanMode==0)?"i":"p" )); + } + else + { + i=-1; + HDMITX_DEBUG_PRINTF(("no matched\n")); + } + + return i; +} + +void HDMITX_MonitorInputVideoChange() +{ + static ULONG prevPCLK = 0 ; + static USHORT prevHTotal = 0 ; + static USHORT prevVTotal = 0 ; + static BYTE prevScanMode ; + ULONG currPCLK ; + ULONG diff ; + USHORT currHTotal, currVTotal ; + BYTE currScanMode ; + int i ; + + currPCLK = CalcPCLK() ; + currHTotal = hdmitx_getInputHTotal() ; + currVTotal = hdmitx_getInputVTotal() ; + currScanMode = hdmitx_isInputInterlace() ? INTERLACE:PROG ; + diff = DIFF(currPCLK,prevPCLK); + + HDMITX_DEBUG_PRINTF(("HDMITX_MonitorInputVideoChange : pclk=%lu, ht=%u, vt=%u, dif=%lu\n", currPCLK, currHTotal, currVTotal, diff )); + + if( currHTotal == 0 || currVTotal == 0 || currPCLK == 0 ) + { + bChangeMode = FALSE; + return ; + } + + if( diff > currPCLK/20) // 5% torrenlance + { + bChangeMode = TRUE ; + } + else + { + diff = DIFF(currHTotal, prevHTotal) ; + if( diff > 20 ) + { + bChangeMode = TRUE ; + } + diff = DIFF(currVTotal, prevVTotal) ; + if( diff > 20 ) + { + bChangeMode = TRUE ; + } + } + + if( bChangeMode ) + { + HDMITX_DEBUG_PRINTF(("PCLK = %ld -> %ld\n",prevPCLK, currPCLK)); + HDMITX_DEBUG_PRINTF(("HTotal = %d -> %d\n",prevHTotal, currHTotal)); + HDMITX_DEBUG_PRINTF(("VTotal = %d -> %d\n",prevVTotal, currVTotal)); + HDMITX_DEBUG_PRINTF(("ScanMode = %s -> %s\n",prevScanMode?"P":"I", currScanMode?"P":"I")); + + HDMITX_DEBUG_PRINTF(("PCLK = %ld,(%dx%d) %s %s\n",currPCLK, currHTotal,currVTotal, (currScanMode==INTERLACE)?"INTERLACED":"PROGRESS",bChangeMode?"CHANGE MODE":"NO CHANGE MODE")); + + setHDMITX_AVMute(TRUE); + + #if 0 + for( i = 0 ; (i < SizeofVMTable) && ( s_VMTable[i].VIC != 0 ); i++ ) + { + if( s_VMTable[i].VIC == 0 ) break ; + if( DIFF(currPCLK, s_VMTable[i].PCLK) > (s_VMTable[i].PCLK/20)) + { + continue ; + } + if( DIFF(currHTotal, s_VMTable[i].HTotal) > 40 ) + { + continue ; + } + if( currScanMode != s_VMTable[i].ScanMode ) + { + continue ; + } + if( currScanMode == INTERLACE ) + { + if( DIFF(currVTotal/2, s_VMTable[i].VTotal) > 10 ) + { + continue ; + } + } + else + { + if( DIFF(currVTotal, s_VMTable[i].VTotal) > 10 ) + { + continue ; + } + } + printf("i = %d, VIC = %d\n",i,(int)s_VMTable[i].VIC) ; + + break ; + } + #else + i = HDMITX_SearchVICIndex( currPCLK, currHTotal, currVTotal, currScanMode ); + #endif + + if( i >= 0 ) + { + VIC = s_VMTable[i].VIC; + pixelrep = s_VMTable[i].PixelRep ; + VideoPixelClock = currPCLK ; + } + else + { + VIC = 0; + pixelrep = 0; + VideoPixelClock = 0 ; + } + } + + prevPCLK = currPCLK ; + prevHTotal = currHTotal ; + prevVTotal = currVTotal ; + prevScanMode = currScanMode ; + +} +#endif // HDMITX_AUTO_MONITOR_INPUT + +void HDMITX_ChangeDisplayOption(HDMI_Video_Type OutputVideoTiming, HDMI_OutputColorMode OutputColorMode) +{ + printk( "[%s] Vic=%d\n", __FUNCTION__,OutputVideoTiming); + //HDMI_Video_Type t=HDMI_480i60_16x9; + if((F_MODE_RGB444)==(bOutputColorMode&F_MODE_CLRMOD_MASK))//Force output RGB in RGB only case + { + OutputColorMode=F_MODE_RGB444; + } + else if ((F_MODE_YUV422)==(bOutputColorMode&F_MODE_CLRMOD_MASK))//YUV422 only + { + if(OutputColorMode==HDMI_YUV444){OutputColorMode=F_MODE_YUV422;} + } + else if ((F_MODE_YUV444)==(bOutputColorMode&F_MODE_CLRMOD_MASK))//YUV444 only + { + if(OutputColorMode==HDMI_YUV422){OutputColorMode=F_MODE_YUV444;} + } + switch(OutputVideoTiming) + { + case HDMI_640x480p60: + VIC = 1 ; + VideoPixelClock = 25000000 ; + pixelrep = 0 ; + aspec = HDMI_4x3 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_480p60: + VIC = 2 ; + VideoPixelClock = 27000000 ; + pixelrep = 0 ; + aspec = HDMI_4x3 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_480p60_16x9: + VIC = 3 ; + VideoPixelClock = 27000000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_720p60: + VIC = 4 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_1080i60: + VIC = 5 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_480i60: + VIC = 6 ; + VideoPixelClock = 13500000 ; + pixelrep = 1 ; + aspec = HDMI_4x3 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_480i60_16x9: + VIC = 7 ; + VideoPixelClock = 13500000 ; + pixelrep = 1 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_1080p60: + VIC = 16 ; + VideoPixelClock = 148500000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_576p50: + VIC = 17 ; + VideoPixelClock = 27000000 ; + pixelrep = 0 ; + aspec = HDMI_4x3 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_576p50_16x9: + VIC = 18 ; + VideoPixelClock = 27000000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_720p50: + VIC = 19 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_1080i50: + VIC = 20 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_576i50: + VIC = 21 ; + VideoPixelClock = 13500000 ; + pixelrep = 1 ; + aspec = HDMI_4x3 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_576i50_16x9: + VIC = 22 ; + VideoPixelClock = 13500000 ; + pixelrep = 1 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU601 ; + break ; + case HDMI_1080p50: + VIC = 31 ; + VideoPixelClock = 148500000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_1080p24: + VIC = 32 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_1080p25: + VIC = 33 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + case HDMI_1080p30: + VIC = 34 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + break ; + + case HDMI_720p30: + VIC = 0 ; + VideoPixelClock = 74250000 ; + pixelrep = 0 ; + aspec = HDMI_16x9 ; + Colorimetry = HDMI_ITU709 ; + + #ifdef SUPPORT_SYNCEMBEDDED + /* + VTiming.HActive=1280 ; + VTiming.VActive=720 ; + VTiming.HTotal=3300 ; + VTiming.VTotal=750 ; + VTiming.PCLK=VideoPixelClock ; + VTiming.xCnt=0x2E ; + VTiming.HFrontPorch= 1760; + VTiming.HSyncWidth= 40 ; + VTiming.HBackPorch= 220 ; + VTiming.VFrontPorch= 5; + VTiming.VSyncWidth= 5 ; + VTiming.VBackPorch= 20 ; + VTiming.ScanMode=PROG ; + VTiming.VPolarity=Vneg ; + VTiming.HPolarity=Hneg ; + */ + #endif + break ; + default: + bChangeMode = FALSE ; + return ; + } + switch(OutputColorMode) + { + case HDMI_YUV444: + bOutputColorMode = F_MODE_YUV444 ; + break ; + case HDMI_YUV422: + bOutputColorMode = F_MODE_YUV422 ; + break ; + case HDMI_RGB444: + default: + bOutputColorMode = F_MODE_RGB444 ; + break ; + } + if( Colorimetry == HDMI_ITU709 ) + { + bInputColorMode |= F_VIDMODE_ITU709 ; + } + else + { + bInputColorMode &= ~F_VIDMODE_ITU709 ; + } + // if( Colorimetry != HDMI_640x480p60) + if( OutputVideoTiming != HDMI_640x480p60) + { + bInputColorMode |= F_VIDMODE_16_235 ; + } + else + { + bInputColorMode &= ~F_VIDMODE_16_235 ; + } + bChangeMode = TRUE ; +} + +void ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep) +{ + AVI_InfoFrame *AviInfo; + AviInfo = (AVI_InfoFrame *)CommunBuff ; + + AviInfo->pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ; + AviInfo->pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ; + AviInfo->pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ; + + switch(bOutputColorMode) + { + case F_MODE_YUV444: + // AviInfo->info.ColorMode = 2 ; + AviInfo->pktbyte.AVI_DB[0] = (2<<5)|(1<<4); + break ; + case F_MODE_YUV422: + // AviInfo->info.ColorMode = 1 ; + AviInfo->pktbyte.AVI_DB[0] = (1<<5)|(1<<4); + break ; + case F_MODE_RGB444: + default: + // AviInfo->info.ColorMode = 0 ; + AviInfo->pktbyte.AVI_DB[0] = (0<<5)|(1<<4); + break ; + } + AviInfo->pktbyte.AVI_DB[1] = 8 ; + AviInfo->pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4); // 4:3 or 16:9 + AviInfo->pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6); // 4:3 or 16:9 + AviInfo->pktbyte.AVI_DB[2] = 0 ; + AviInfo->pktbyte.AVI_DB[3] = VIC ; + AviInfo->pktbyte.AVI_DB[4] = pixelrep & 3 ; + AviInfo->pktbyte.AVI_DB[5] = 0 ; + AviInfo->pktbyte.AVI_DB[6] = 0 ; + AviInfo->pktbyte.AVI_DB[7] = 0 ; + AviInfo->pktbyte.AVI_DB[8] = 0 ; + AviInfo->pktbyte.AVI_DB[9] = 0 ; + AviInfo->pktbyte.AVI_DB[10] = 0 ; + AviInfo->pktbyte.AVI_DB[11] = 0 ; + AviInfo->pktbyte.AVI_DB[12] = 0 ; + + HDMITX_EnableAVIInfoFrame(TRUE, (unsigned char *)AviInfo); +} + +//////////////////////////////////////////////////////////////////////////////// +// Function: ConfigAudioInfoFrm +// Parameter: NumChannel, number from 1 to 8 +// Return: ER_SUCCESS for successfull. +// Remark: Evaluate. The speakerplacement is only for reference. +// For production, the caller of hdmitx_SetAudioInfoFrame should program +// Speaker placement by actual status. +// Side-Effect: +//////////////////////////////////////////////////////////////////////////////// + +void ConfigAudioInfoFrm() +{ + int i ; + + Audio_InfoFrame *AudioInfo ; + AudioInfo = (Audio_InfoFrame *)CommunBuff ; + + HDMITX_DEBUG_PRINTF(("ConfigAudioInfoFrm(%d)\n",2)); + + AudioInfo->pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ; + AudioInfo->pktbyte.AUD_HB[1] = 1 ; + AudioInfo->pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ; + AudioInfo->pktbyte.AUD_DB[0] = 1 ; + for( i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++ ) + { + AudioInfo->pktbyte.AUD_DB[i] = 0 ; + } + HDMITX_EnableAudioInfoFrame(TRUE, (unsigned char *)AudioInfo); +} + +void ConfigfHdmiVendorSpecificInfoFrame(BYTE _3D_Stru) +{ + VendorSpecific_InfoFrame *VS_Info; + + VS_Info=(VendorSpecific_InfoFrame *)CommunBuff ; + + VS_Info->pktbyte.VS_HB[0] = VENDORSPEC_INFOFRAME_TYPE|0x80; + VS_Info->pktbyte.VS_HB[1] = VENDORSPEC_INFOFRAME_VER; + VS_Info->pktbyte.VS_HB[2] = (_3D_Stru == Side_by_Side)?6:5; + VS_Info->pktbyte.VS_DB[0] = 0x03; + VS_Info->pktbyte.VS_DB[1] = 0x0C; + VS_Info->pktbyte.VS_DB[2] = 0x00; + VS_Info->pktbyte.VS_DB[3] = 0x40; + switch(_3D_Stru) + { + case Side_by_Side: + case Frame_Pcaking: + case Top_and_Botton: + VS_Info->pktbyte.VS_DB[4] = (_3D_Stru<<4); + break; + default: + VS_Info->pktbyte.VS_DB[4] = (Frame_Pcaking<<4); + break ; + } + VS_Info->pktbyte.VS_DB[5] = 0x00; + HDMITX_EnableVSInfoFrame(TRUE,(BYTE *)VS_Info); +} + +///////////////////////////////////////////////////////////////////// +// ParseEDID() +// Check EDID check sum and EDID 1.3 extended segment. +///////////////////////////////////////////////////////////////////// + +BYTE ParseEDID() +{ + // collect the EDID ucdata of segment 0 + _XDATA unsigned char *EDID_Buf; + BYTE CheckSum ; + BYTE BlockCount ; + BYTE err ; + BYTE bValidCEA = FALSE ; + BYTE i; + #if Debug_message + BYTE j ; + #endif // Debug_message + + EDID_Buf = CommunBuff; + RxCapability.ValidCEA = FALSE ; + RxCapability.ValidHDMI = FALSE ; + RxCapability.dc.uc = 0; + + getHDMITX_EDIDBlock(0, EDID_Buf); + + for( i = 0, CheckSum = 0 ; i < 128 ; i++ ) + { + CheckSum += EDID_Buf[i] ; CheckSum &= 0xFF ; + } + //Eep_Write(0x80, 0x80, EDID_Buf); + if( CheckSum != 0 ) + { + return FALSE ; + } + if( EDID_Buf[0] != 0x00 || + EDID_Buf[1] != 0xFF || + EDID_Buf[2] != 0xFF || + EDID_Buf[3] != 0xFF || + EDID_Buf[4] != 0xFF || + EDID_Buf[5] != 0xFF || + EDID_Buf[6] != 0xFF || + EDID_Buf[7] != 0x00) + { + return FALSE ; + } + /* + for( i = 0 ; i < 128 ; i++ ) + { + HDMITX_DEBUG_PRINTF(("%02X%c",(int)EDID_Buf[i],(7 == (i&7))?'\n':' ')); + } + */ + + BlockCount = EDID_Buf[0x7E] ; + + if( BlockCount == 0 ) + { + return TRUE ; // do nothing. + } + else if ( BlockCount > 4 ) + { + BlockCount = 4 ; + } + // read all segment for test + for( i = 1 ; i <= BlockCount ; i++ ) + { + err = getHDMITX_EDIDBlock(i, EDID_Buf); + + #if Debug_message + for( j = 0 ; j < 128 ; j++ ) + { + EDID_DEBUG_PRINTF(("%02X%c",(int)EDID_Buf[j],(7 == (j&7))?'\n':' ')); + } + #endif // Debug_message + + if( err ) + { + if( !bValidCEA && EDID_Buf[0] == 0x2 && EDID_Buf[1] == 0x3 ) + { + err = ParseCEAEDID(EDID_Buf); + EDID_DEBUG_PRINTF(("err = %s\n",err?"SUCCESS":"FAIL")); + if( err ) + { + EDID_DEBUG_PRINTF(("RxCapability.IEEEOUI = %lx\n",RxCapability.IEEEOUI)); + + if(RxCapability.IEEEOUI==0x0c03) + { + RxCapability.ValidHDMI = TRUE ; + bValidCEA = TRUE ; + } + else + { + RxCapability.ValidHDMI = FALSE ; + } + } + } + } + } + return err ; +} + +static BOOL ParseCEAEDID(BYTE *pCEAEDID) +{ + BYTE offset,End ; + BYTE count ; + BYTE tag ; + int i ; + + if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return FALSE ; // not a CEA BLOCK. + End = pCEAEDID[2] ; // CEA description. + + RxCapability.VDOMode[0] = 0x00 ; + RxCapability.VDOMode[1] = 0x00 ; + RxCapability.VDOMode[2] = 0x00 ; + RxCapability.VDOMode[3] = 0x00 ; + RxCapability.VDOMode[4] = 0x00 ; + RxCapability.VDOMode[5] = 0x00 ; + RxCapability.VDOMode[6] = 0x00 ; + RxCapability.VDOMode[7] = 0x00 ; + RxCapability.PA[0] = 0x00 ; + RxCapability.PA[1] = 0x00 ; + + RxCapability.VideoMode = pCEAEDID[3] ; + + RxCapability.NativeVDOMode = 0xff ; + + for( offset = 4 ; offset < End ; ) + { + tag = pCEAEDID[offset] >> 5 ; + count = pCEAEDID[offset] & 0x1f ; + switch( tag ) + { + case 0x01: // Audio Data Block ; + RxCapability.AUDDesCount = count/3 ; + EDID_DEBUG_PRINTF(("RxCapability.AUDDesCount = %d\n",(int)RxCapability.AUDDesCount)); + offset++ ; + for( i = 0 ; i < RxCapability.AUDDesCount && i < MAX_AUDDES_COUNT ; i++ ) + { + RxCapability.AUDDes[i].uc[0] = pCEAEDID[offset+i*3] ; + RxCapability.AUDDes[i].uc[1] = pCEAEDID[offset+i*3+1] ; + RxCapability.AUDDes[i].uc[2] = pCEAEDID[offset+i*3+2] ; + } + offset += count ; + break ; + + case 0x02: // Video Data Block ; + offset ++ ; + for( i = 0,RxCapability.NativeVDOMode = 0xff ; i < count ; i++) + { + BYTE VIC ; + VIC = pCEAEDID[offset+i] & (~0x80); + // if( FindModeTableEntryByVIC(VIC) != -1 ) + if(VIC<64) + { + RxCapability.VDOMode[VIC/8] |= (1<<(VIC%8)); + EDID_DEBUG_PRINTF(("VIC = %d, RxCapability.VDOMode[%d]=%02X\n",(int)VIC,(int)VIC/8,(int)RxCapability.VDOMode[VIC/8] )); + if(( pCEAEDID[offset+i] & 0x80 )&&(RxCapability.NativeVDOMode==0xFF)) + { + RxCapability.NativeVDOMode = VIC ; + EDID_DEBUG_PRINTF(("native = %d\n",RxCapability.NativeVDOMode)); + } + } + } + offset += count ; + break ; + + case 0x03: // Vendor Specific Data Block ; + offset ++ ; + RxCapability.IEEEOUI = (ULONG)pCEAEDID[offset+2] ; + RxCapability.IEEEOUI <<= 8 ; + RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset+1] ; + RxCapability.IEEEOUI <<= 8 ; + RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset] ; + EDID_DEBUG_PRINTF(("IEEEOUI = %02X %02X %02X %lx",(int)pCEAEDID[offset+2],(int)pCEAEDID[offset+1],(int)pCEAEDID[offset],RxCapability.IEEEOUI)); + if( RxCapability.IEEEOUI== 0x0C03) + { + BYTE nextoffset ; + RxCapability.PA[0] = pCEAEDID[offset+3] ; + RxCapability.PA[1] = pCEAEDID[offset+4] ; + if(count>5) + { + RxCapability.dc.uc = pCEAEDID[offset+5]&0x70; + } + if(count>6) + { + RxCapability.MaxTMDSClock = pCEAEDID[offset+6]; + } + if(count>7) + { + nextoffset = 8 ; + if(pCEAEDID[offset+7] & 0x80) { nextoffset += 2 ; } // latency + if(pCEAEDID[offset+7] & 0x40) { nextoffset += 2 ; } // interlace latency + if(pCEAEDID[offset+7] & 0x20) { + EDID_DEBUG_PRINTF(("next offset = %d",(int)nextoffset)); + RxCapability.Valid3D = (pCEAEDID[offset+nextoffset] & 0x80)?TRUE:FALSE ; + } // interlace latency + + } + } + offset += count ; // ignore the remaind. + + break ; + + case 0x04: // Speaker Data Block ; + offset ++ ; + RxCapability.SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ; + RxCapability.SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ; + RxCapability.SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ; + offset += 3 ; + break ; + case 0x05: // VESA Data Block ; + offset += count+1 ; + break ; + case 0x07: // Extended Data Block ; + offset += count+1 ; //ignore + break ; + default: + offset += count+1 ; // ignore + } + } + RxCapability.ValidCEA = TRUE ; + return TRUE ; +} diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.h b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.h new file mode 100755 index 000000000000..df7c3e7ba63d --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/hdmitx_sys.h @@ -0,0 +1,15 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +#ifndef _HDMITX_SYS_H_ +#define _HDMITX_SYS_H_ +#include "cat66121_hdmi_hw.h" +#endif // _HDMITX_SYS_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c new file mode 100755 index 000000000000..2cfd6d284092 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.c @@ -0,0 +1,152 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Hermes.Wu@ite.com.tw +// @date 2011/08/26 +// @fileversion: COMMON_FILE_1.01 +//******************************************/ + +#include +//#include +#include "sha1.h" + + +#ifndef DISABLE_HDCP + +#define WCOUNT 17 +ULONG VH[5]; +ULONG w[WCOUNT]; + +#define rol(x,y)(((x)<< (y))| (((ULONG)x)>> (32-y))) + + +void SHATransform(ULONG * h) +{ + int t; + ULONG tmp; + + + h[0]=0x67452301; + h[1]=0xefcdab89; + h[2]=0x98badcfe; + h[3]=0x10325476; + h[4]=0xc3d2e1f0; + + for (t=0; t < 20; t++){ + if(t>=16) + { + tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; + w[(t)% WCOUNT]=rol(tmp,1); + } + HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); + + tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[3] & ~h[1]))+ h[4] + w[(t)% WCOUNT] + 0x5a827999; + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); + + h[4]=h[3]; + h[3]=h[2]; + h[2]=rol(h[1],30); + h[1]=h[0]; + h[0]=tmp; + + } + for (t=20; t < 40; t++){ + tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; + w[(t)% WCOUNT]=rol(tmp,1); + HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); + tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0x6ed9eba1; + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); + h[4]=h[3]; + h[3]=h[2]; + h[2]=rol(h[1],30); + h[1]=h[0]; + h[0]=tmp; + } + for (t=40; t < 60; t++){ + tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; + w[(t)% WCOUNT]=rol(tmp,1); + HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); + tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[1] & h[3])| (h[2] & h[3]))+ h[4] + w[(t)% WCOUNT] + 0x8f1bbcdc; + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); + h[4]=h[3]; + h[3]=h[2]; + h[2]=rol(h[1],30); + h[1]=h[0]; + h[0]=tmp; + } + for (t=60; t < 80; t++) + { + tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT]; + w[(t)% WCOUNT]=rol(tmp,1); + HDCP_DEBUG_PRINTF2(("w[%d]=%08lX\n",t,w[(t)% WCOUNT])); + tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0xca62c1d6; + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); + h[4]=h[3]; + h[3]=h[2]; + h[2]=rol(h[1],30); + h[1]=h[0]; + h[0]=tmp; + } + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); + h[0] +=0x67452301; + h[1] +=0xefcdab89; + h[2] +=0x98badcfe; + h[3] +=0x10325476; + h[4] +=0xc3d2e1f0; + + HDCP_DEBUG_PRINTF2(("%08lX %08lX %08lX %08lX %08lX\n",h[0],h[1],h[2],h[3],h[4])); +} + +void SHA_Simple(void *p,WORD len,BYTE *output) +{ + // SHA_State s; + WORD i,t; + ULONG c; + BYTE *pBuff=p; + + for(i=0;i < len;i++) + { + t=i/4; + if(i%4==0) + { + w[t]=0; + } + c=pBuff[i]; + c <<=(3-(i%4))*8; + w[t] |=c; + HDCP_DEBUG_PRINTF2(("pBuff[%d]=%02X,c=%08lX,w[%d]=%08lX\n",(int)i,(int)pBuff[i],c,(int)t,w[t])); + } + t=i/4; + if(i%4==0) + { + w[t]=0; + } + //c=0x80 << ((3-i%4)*24); + c=0x80; + c <<=((3-i%4)*8); + w[t]|=c;t++; + for(; t < 15;t++) + { + w[t]=0; + } + w[15]=len*8; + + for(i = 0 ; i < 16 ; i++) + { + HDCP_DEBUG_PRINTF2(("w[%d] = %08lX\n",i,w[i])); + } + + SHATransform(VH); + + for(i=0;i < 5;i++) + { + output[i*4+3]=(BYTE)((VH[i]>>24)&0xFF); + output[i*4+2]=(BYTE)((VH[i]>>16)&0xFF); + output[i*4+1]=(BYTE)((VH[i]>>8)&0xFF); + output[i*4+0]=(BYTE)(VH[i]&0xFF); + } +} +#endif diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h new file mode 100755 index 000000000000..19c18c4e049f --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/sha1.h @@ -0,0 +1,46 @@ +///***************************************** +// Copyright (C)2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-chih.Tseng@ite.com.tw +// @date 2010/06/04 +// @fileversion: COMMON_FILE_1.01 +//******************************************/ + +#ifndef _SHA_1_H_ +#define _SHA_1_H_ + +#ifdef _MCU_8051_ + #include "Mcu.h" +#endif + +#include + +#if Debug_message + #include +#endif + +#include "config.h" +#include "typedef.h" + +#ifndef HDCP_DEBUG_PRINTF + #define HDCP_DEBUG_PRINTF(x) +#endif //HDCP_DEBUG_PRINTF + +#ifndef HDCP_DEBUG_PRINTF1 + #define HDCP_DEBUG_PRINTF1(x) +#endif //HDCP_DEBUG_PRINTF1 + +#ifndef HDCP_DEBUG_PRINTF2 + #define HDCP_DEBUG_PRINTF2(x) +#endif //HDCP_DEBUG_PRINTF2 + + +#ifndef DISABLE_HDCP +void SHA_Simple(void *p,WORD len,BYTE *output); +void SHATransform(ULONG * h); +#endif + +#endif // _SHA_1_H_ diff --git a/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h b/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h new file mode 100755 index 000000000000..0ec9ecae8762 --- /dev/null +++ b/drivers/video/rockchip/hdmi/chips/cat66121/typedef.h @@ -0,0 +1,380 @@ +///***************************************** +// Copyright (C) 2009-2014 +// ITE Tech. Inc. All Rights Reserved +// Proprietary and Confidential +///***************************************** +// @file +// @author Jau-Chih.Tseng@ite.com.tw +// @date 2012/12/20 +// @fileversion: ITE_HDMITX_SAMPLE_3.14 +//******************************************/ + +#ifndef _TYPEDEF_H_ +#define _TYPEDEF_H_ + +////////////////////////////////////////////////// +// data type +////////////////////////////////////////////////// +#ifdef _MCU_8051_ + #define _CODE code + #define _DATA data + #define _XDATA xdata + #define _IDATA idata + typedef bit BOOL ; +#else + #define _CODE const + #define _DATA + #define _IDATA + #define _XDATA + typedef int BOOL ; +#endif // _MCU_8051_ + +typedef _CODE unsigned char cBYTE; + + +typedef char CHAR,*PCHAR ; +typedef unsigned char uchar,*puchar ; +typedef unsigned char UCHAR,*PUCHAR ; +typedef unsigned char byte,*pbyte ; +typedef unsigned char BYTE,*PBYTE ; + +typedef short SHORT,*PSHORT ; +typedef unsigned short *pushort ; +typedef unsigned short USHORT,*PUSHORT ; +typedef unsigned short word,*pword ; +typedef unsigned short WORD,*PWORD ; +typedef unsigned int UINT,*PUINT ; + +typedef long LONG,*PLONG ; +typedef unsigned long *pulong ; +typedef unsigned long ULONG,*PULONG ; +typedef unsigned long dword,*pdword ; +typedef unsigned long DWORD,*PDWORD ; + +#define FALSE 0 +#define TRUE 1 + +#define SUCCESS 0 +#define FAIL -1 + +#define ON 1 +#define OFF 0 + +#define LO_ACTIVE TRUE +#define HI_ACTIVE FALSE + + +typedef enum _SYS_STATUS { + ER_SUCCESS = 0, + ER_FAIL, + ER_RESERVED +} SYS_STATUS ; + +#define ABS(x) (((x)>=0)?(x):(-(x))) + + + + + +/////////////////////////////////////////////////////////////////////// +// Video Data Type +/////////////////////////////////////////////////////////////////////// + +#define F_MODE_RGB444 0 +#define F_MODE_YUV422 1 +#define F_MODE_YUV444 2 +#define F_MODE_CLRMOD_MASK 3 + + +#define F_MODE_INTERLACE 1 + +#define F_VIDMODE_ITU709 (1<<4) +#define F_VIDMODE_ITU601 0 + +#define F_VIDMODE_0_255 0 +#define F_VIDMODE_16_235 (1<<5) + +#define F_VIDMODE_EN_UDFILT (1<<6) +#define F_VIDMODE_EN_DITHER (1<<7) + +#define T_MODE_CCIR656 (1<<0) +#define T_MODE_SYNCEMB (1<<1) +#define T_MODE_INDDR (1<<2) +#define T_MODE_PCLKDIV2 (1<<3) +#define T_MODE_DEGEN (1<<4) +#define T_MODE_SYNCGEN (1<<5) +///////////////////////////////////////////////////////////////////// +// Packet and Info Frame definition and datastructure. +///////////////////////////////////////////////////////////////////// + + +#define VENDORSPEC_INFOFRAME_TYPE 0x81 +#define AVI_INFOFRAME_TYPE 0x82 +#define SPD_INFOFRAME_TYPE 0x83 +#define AUDIO_INFOFRAME_TYPE 0x84 +#define MPEG_INFOFRAME_TYPE 0x85 + +#define VENDORSPEC_INFOFRAME_VER 0x01 +#define AVI_INFOFRAME_VER 0x02 +#define SPD_INFOFRAME_VER 0x01 +#define AUDIO_INFOFRAME_VER 0x01 +#define MPEG_INFOFRAME_VER 0x01 + +#define VENDORSPEC_INFOFRAME_LEN 5 +#define AVI_INFOFRAME_LEN 13 +#define SPD_INFOFRAME_LEN 25 +#define AUDIO_INFOFRAME_LEN 10 +#define MPEG_INFOFRAME_LEN 10 + +#define ACP_PKT_LEN 9 +#define ISRC1_PKT_LEN 16 +#define ISRC2_PKT_LEN 16 + +typedef union _VendorSpecific_InfoFrame +{ + struct { + BYTE Type ; + BYTE Ver ; + BYTE Len ; + + BYTE CheckSum; + + BYTE IEEE_0;//PB1 + BYTE IEEE_1;//PB2 + BYTE IEEE_2;//PB3 + + BYTE Rsvd:5 ;//PB4 + BYTE HDMI_Video_Format:3 ; + + BYTE Reserved_PB5:4 ;//PB5 + BYTE _3D_Structure:4 ; + + BYTE Reserved_PB6:4 ;//PB6 + BYTE _3D_Ext_Data:4 ; + } info ; + struct { + BYTE VS_HB[3] ; + BYTE CheckSum; + BYTE VS_DB[28] ; + } pktbyte ; +} VendorSpecific_InfoFrame ; + +typedef union _AVI_InfoFrame +{ + + struct { + BYTE Type; + BYTE Ver; + BYTE Len; + + BYTE checksum ; + + BYTE Scan:2; + BYTE BarInfo:2; + BYTE ActiveFmtInfoPresent:1; + BYTE ColorMode:2; + BYTE FU1:1; + + BYTE ActiveFormatAspectRatio:4; + BYTE PictureAspectRatio:2; + BYTE Colorimetry:2; + + BYTE Scaling:2; + BYTE FU2:6; + + BYTE VIC:7; + BYTE FU3:1; + + BYTE PixelRepetition:4; + BYTE FU4:4; + + short Ln_End_Top; + short Ln_Start_Bottom; + short Pix_End_Left; + short Pix_Start_Right; + } info; + + struct { + BYTE AVI_HB[3]; + BYTE checksum ; + BYTE AVI_DB[AVI_INFOFRAME_LEN]; + } pktbyte; +} AVI_InfoFrame; + +typedef union _Audio_InfoFrame { + + struct { + BYTE Type; + BYTE Ver; + BYTE Len; + BYTE checksum ; + + BYTE AudioChannelCount:3; + BYTE RSVD1:1; + BYTE AudioCodingType:4; + + BYTE SampleSize:2; + BYTE SampleFreq:3; + BYTE Rsvd2:3; + + BYTE FmtCoding; + + BYTE SpeakerPlacement; + + BYTE Rsvd3:3; + BYTE LevelShiftValue:4; + BYTE DM_INH:1; + } info; + + struct { + BYTE AUD_HB[3]; + BYTE checksum ; + BYTE AUD_DB[5]; + } pktbyte; + +} Audio_InfoFrame; + +typedef union _MPEG_InfoFrame { + struct { + BYTE Type; + BYTE Ver; + BYTE Len; + BYTE checksum ; + + ULONG MpegBitRate; + + BYTE MpegFrame:2; + BYTE Rvsd1:2; + BYTE FieldRepeat:1; + BYTE Rvsd2:3; + } info; + struct { + BYTE MPG_HB[3]; + BYTE checksum ; + BYTE MPG_DB[MPEG_INFOFRAME_LEN]; + } pktbyte; +} MPEG_InfoFrame; + +typedef union _SPD_InfoFrame { + struct { + BYTE Type; + BYTE Ver; + BYTE Len; + BYTE checksum ; + + char VN[8]; + char PD[16]; + BYTE SourceDeviceInfomation; + } info; + struct { + BYTE SPD_HB[3]; + BYTE checksum ; + BYTE SPD_DB[SPD_INFOFRAME_LEN]; + } pktbyte; +} SPD_InfoFrame; + +/////////////////////////////////////////////////////////////////////////// +// Using for interface. +/////////////////////////////////////////////////////////////////////////// + +#define PROG 1 +#define INTERLACE 0 +#define Vneg 0 +#define Hneg 0 +#define Vpos 1 +#define Hpos 1 + +typedef struct { + WORD H_ActiveStart; + WORD H_ActiveEnd; + WORD H_SyncStart; + WORD H_SyncEnd; + WORD V_ActiveStart; + WORD V_ActiveEnd; + WORD V_SyncStart; + WORD V_SyncEnd; + WORD V2_ActiveStart; + WORD V2_ActiveEnd; + WORD HTotal; + WORD VTotal; +} CEAVTiming; + +typedef struct { + BYTE VIC ; + BYTE PixelRep ; + WORD HActive; + WORD VActive; + WORD HTotal; + WORD VTotal; + ULONG PCLK; + BYTE xCnt; + WORD HFrontPorch; + WORD HSyncWidth; + WORD HBackPorch; + BYTE VFrontPorch; + BYTE VSyncWidth; + BYTE VBackPorch; + BYTE ScanMode:1; + BYTE VPolarity:1; + BYTE HPolarity:1; +} HDMI_VTiming; + +////////////////////////////////////////////////////////////////// +// Audio relate definition and macro. +////////////////////////////////////////////////////////////////// + +// 2008/08/15 added by jj_tseng@chipadvanced +#define F_AUDIO_ON (1<<7) +#define F_AUDIO_HBR (1<<6) +#define F_AUDIO_DSD (1<<5) +#define F_AUDIO_NLPCM (1<<4) +#define F_AUDIO_LAYOUT_1 (1<<3) +#define F_AUDIO_LAYOUT_0 (0<<3) + +// HBR - 1100 +// DSD - 1010 +// NLPCM - 1001 +// LPCM - 1000 + +#define T_AUDIO_MASK 0xF0 +#define T_AUDIO_OFF 0 +#define T_AUDIO_HBR (F_AUDIO_ON|F_AUDIO_HBR) +#define T_AUDIO_DSD (F_AUDIO_ON|F_AUDIO_DSD) +#define T_AUDIO_NLPCM (F_AUDIO_ON|F_AUDIO_NLPCM) +#define T_AUDIO_LPCM (F_AUDIO_ON) + +// for sample clock +#define AUDFS_22p05KHz 4 +#define AUDFS_44p1KHz 0 +#define AUDFS_88p2KHz 8 +#define AUDFS_176p4KHz 12 + +#define AUDFS_24KHz 6 +#define AUDFS_48KHz 2 +#define AUDFS_96KHz 10 +#define AUDFS_192KHz 14 + +#define AUDFS_768KHz 9 + +#define AUDFS_32KHz 3 +#define AUDFS_OTHER 1 + +// Audio Enable +#define ENABLE_SPDIF (1<<4) +#define ENABLE_I2S_SRC3 (1<<3) +#define ENABLE_I2S_SRC2 (1<<2) +#define ENABLE_I2S_SRC1 (1<<1) +#define ENABLE_I2S_SRC0 (1<<0) + +#define AUD_SWL_NOINDICATE 0x0 +#define AUD_SWL_16 0x2 +#define AUD_SWL_17 0xC +#define AUD_SWL_18 0x4 +#define AUD_SWL_20 0xA // for maximum 20 bit +#define AUD_SWL_21 0xD +#define AUD_SWL_22 0x5 +#define AUD_SWL_23 0x9 +#define AUD_SWL_24 0xB + + +#endif // _TYPEDEF_H_ -- 2.34.1