.platform_data = &bu92747guw_pdata,
},
#endif
+#ifdef CONFIG_MFD_RK610
+ {
+ .type = "rk610_ctl",
+ .addr = 0x40,
+ .flags = 0,
+ },
+#endif
+#ifdef CONFIG_RK610_TVOUT
+ {
+ .type = "rk610_tvout",
+ .addr = 0x42,
+ .flags = 0,
+ },
+#endif
+#ifdef CONFIG_RK610_HDMI
+ {
+ .type = "rk610_hdmi",
+ .addr = 0x46,
+ .flags = 0,
+ .irq = RK29_PIN1_PD7,
+ },
+#endif
+#ifdef CONFIG_SND_SOC_RK610
+ {
+ .type = "rk610_i2c_codec",
+ .addr = 0x60,
+ .flags = 0,
+ },
+#endif
};
#endif
// rate parent band NR NF NO
CODEC_PLL(108000, 24, LOW, 1, 18, 4), // for TV
CODEC_PLL(648000, 24, HIGH, 1, 27, 1),
- CODEC_PLL(148500, 27, LOW, 1, 22, 4), // for HDMI
- CODEC_PLL(297000, 27, LOW, 1, 22, 2),
+ CODEC_PLL(148500, 27, LOW, 2, 88, 8), //change for jetta hdmi dclk jitter 20120322// for HDMI
+ CODEC_PLL(297000, 27, LOW, 2, 88, 4), //change for jetta hdmi dclk jitter 20120322// for HDMI
CODEC_PLL(445500, 27, LOW, 2, 33, 1),
CODEC_PLL(594000, 27, HIGH, 1, 22, 1),
CODEC_PLL(891000, 27, HIGH, 1, 33, 1),
config TPS65911_COMPARATOR
tristate
+config MFD_RK610
+ bool "RK610(Jetta) Multimedia support"
+ depends on I2C=y && GPIOLIB
+ select MFD_CORE
+ help
+ if you say yes here you get support for the RK610, with func as
+ HDMI LCD LVDS TVOUT CODEC.
endif # MFD_SUPPORT
menu "Multimedia Capabilities Port drivers"
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
+obj-$(CONFIG_MFD_RK610) += rk610-core.o
\ No newline at end of file
--- /dev/null
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <asm/gpio.h>
+#include <linux/mfd/rk610_core.h>
+#include <linux/clk.h>
+#include <mach/iomux.h>
+#include <linux/err.h>
+
+#define RK610_RESET_PIN RK29_PIN6_PC1
+
+static struct i2c_client *rk610_control_client = NULL;
+#ifdef CONFIG_RK610_LCD
+extern int rk610_lcd_init(struct i2c_client *client);
+#else
+int rk610_lcd_init(struct i2c_client *client){}
+#endif
+int rk610_control_send_byte(const char reg, const char data)
+{
+ int ret;
+
+ printk("reg = 0x%02x, val=0x%02x\n", reg ,data);
+
+ if(rk610_control_client == NULL)
+ return -1;
+ //i2c_master_reg8_send
+ ret = i2c_master_reg8_send(rk610_control_client, reg, &data, 1, 100*1000);
+ if (ret > 0)
+ ret = 0;
+
+ return ret;
+}
+
+#ifdef CONFIG_SND_SOC_RK610
+static unsigned int current_pll_value = 0;
+int rk610_codec_pll_set(unsigned int rate)
+{
+ char N, M, NO, DIV;
+ unsigned int F;
+ char data;
+
+ if(current_pll_value == rate)
+ return 0;
+
+ // Input clock is 12MHz.
+ if(rate == 11289600) {
+ // For 11.2896MHz, N = 2 M= 75 F = 0.264(0x43958) NO = 8
+ N = 2;
+ NO = 3;
+ M = 75;
+ F = 0x43958;
+ DIV = 5;
+ }
+ else if(rate == 12288000) {
+ // For 12.2888MHz, N = 2 M= 75 F = 0.92(0xEB851) NO = 8
+ N = 2;
+ NO = 3;
+ M = 75;
+ F = 0xEB851;
+ DIV = 5;
+ }
+ else {
+ printk(KERN_ERR "[%s] not support such frequency\n", __FUNCTION__);
+ return -1;
+ }
+
+ //Enable codec pll fractional number and power down.
+ data = 0x00;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
+ msleep(10);
+
+ data = (N << 4) | NO;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON0, data);
+ // M
+ data = M;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON1, data);
+ // F
+ data = F & 0xFF;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON2, data);
+ data = (F >> 8) & 0xFF;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON3, data);
+ data = (F >> 16) & 0xFF;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON4, data);
+
+ // i2s mclk = codec_pll/5;
+ i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
+ data &= ~CLOCK_CON1_I2S_DVIDER_MASK;
+ data |= (DIV - 1);
+ rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
+
+ // Power up codec pll.
+ data |= C_PLL_POWER_ON;
+ rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
+
+ current_pll_value = rate;
+ printk(KERN_ERR "[%s] rate %u\n", __FUNCTION__, rate);
+
+ return 0;
+}
+
+void rk610_control_init_codec(void)
+{
+ struct i2c_client *client = rk610_control_client;
+ char data = 0;
+ int ret;
+
+ if(rk610_control_client == NULL)
+ return;
+ printk(KERN_ERR "[%s] start\n", __FUNCTION__);
+
+ //gpio_set_value(RK610_RESET_PIN, GPIO_LOW); //reset rk601
+ // mdelay(100);
+ //gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
+ //mdelay(100);
+
+ // Set i2c glitch timeout.
+ data = 0x22;
+ ret = i2c_master_reg8_send(client, RK610_CONTROL_REG_I2C_CON, &data, 1, 20*1000);
+
+// rk610_codec_pll_set(11289600);
+
+ //use internal codec, enable DAC ADC LRCK output.
+// i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
+// data = CODEC_CON_BIT_DAC_LRCL_OUTPUT_DISABLE | CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
+// data = CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
+ data = 0;
+ rk610_control_send_byte(RK610_CONTROL_REG_CODEC_CON, data);
+
+ // Select internal i2s clock from codec_pll.
+ i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
+// data |= CLOCK_CON1_I2S_CLK_CODEC_PLL;
+ data = 0;
+ rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
+
+ i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
+ printk(KERN_ERR "[%s] RK610_CONTROL_REG_CODEC_CON is %x\n", __FUNCTION__, data);
+
+ i2c_master_reg8_recv(client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
+ printk(KERN_ERR "[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
+}
+#endif
+#ifdef CONFIG_RK610_DEBUG
+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=rk610_control_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 = rk610_control_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),
+};
+#endif
+static int rk610_control_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct clk *iis_clk;
+
+ iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
+ if (IS_ERR(iis_clk)) {
+ printk("failed to get i2s clk\n");
+ ret = PTR_ERR(iis_clk);
+ }else{
+ printk("got i2s clk ok!\n");
+ clk_enable(iis_clk);
+ clk_set_rate(iis_clk, 11289600);
+ rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
+ clk_put(iis_clk);
+ }
+
+ rk610_control_client = client;
+ msleep(100);
+ if(RK610_RESET_PIN != INVALID_GPIO) {
+ ret = gpio_request(RK610_RESET_PIN, "rk610 reset");
+ if (ret){
+ printk(KERN_ERR "rk610_control_probe request gpio fail\n");
+ }
+ else {
+ printk(KERN_ERR "rk610_control_probe request gpio ok\n");
+ gpio_direction_output(RK610_RESET_PIN, GPIO_HIGH);
+ msleep(100);
+ gpio_direction_output(RK610_RESET_PIN, GPIO_LOW);
+ msleep(100);
+ gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
+ }
+ }
+ rk610_lcd_init(client);
+ #ifdef CONFIG_RK610_DEBUG
+ device_create_file(&(client->dev), &rk610_attrs[0]);
+ #endif
+ return 0;
+}
+
+static int rk610_control_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static const struct i2c_device_id rk610_control_id[] = {
+ { "rk610_ctl", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rk610_control_id);
+
+static struct i2c_driver rk610_control_driver = {
+ .driver = {
+ .name = "rk610_ctl",
+ },
+ .probe = rk610_control_probe,
+ .remove = rk610_control_remove,
+ .id_table = rk610_control_id,
+};
+
+static int __init rk610_control_init(void)
+{
+ return i2c_add_driver(&rk610_control_driver);
+}
+
+static void __exit rk610_control_exit(void)
+{
+ i2c_del_driver(&rk610_control_driver);
+}
+
+fs_initcall(rk610_control_init);
+//module_init(rk610_control_init);
+module_exit(rk610_control_exit);
+
+
+MODULE_DESCRIPTION("RK610 control driver");
+MODULE_AUTHOR("Rock-chips, <www.rock-chips.com>");
+MODULE_LICENSE("GPL");
+
comment "Display hardware drivers"
depends on DISPLAY_SUPPORT
source "drivers/video/display/screen/Kconfig"
+source "drivers/video/display/lcd/Kconfig"
+source "drivers/video/display/tve/Kconfig"
endmenu
+
# Display drivers
-display-objs := display-sysfs.o
+display-objs := display-sys.o
obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
obj-$(CONFIG_DISPLAY_SUPPORT) += screen/
+obj-y += lcd/
+obj-y += tve/
\ No newline at end of file
--- /dev/null
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/idr.h>
+#include <linux/err.h>
+#include <linux/kdev_t.h>
+#include <linux/display-sys.h>
+
+static struct list_head display_device_list;
+
+static ssize_t display_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
+}
+
+static ssize_t display_show_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
+}
+
+static ssize_t display_show_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int enable;
+ if(dsp->ops && dsp->ops->getenable)
+ enable = dsp->ops->getenable(dsp);
+ else
+ return 0;
+ return snprintf(buf, PAGE_SIZE, "%d\n", enable);
+}
+
+static ssize_t display_store_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int enable;
+
+ sscanf(buf, "%d", &enable);
+ if(dsp->ops && dsp->ops->setenable)
+ dsp->ops->setenable(dsp, enable);
+ return size;
+}
+
+static ssize_t display_show_connect(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int connect;
+ if(dsp->ops && dsp->ops->getstatus)
+ connect = dsp->ops->getstatus(dsp);
+ else
+ return 0;
+ return snprintf(buf, PAGE_SIZE, "%d\n", connect);
+}
+
+static int mode_string(char *buf, unsigned int offset,
+ const struct fb_videomode *mode)
+{
+// char m = 'U';
+ char v = 'p';
+
+// if (mode->flag & FB_MODE_IS_DETAILED)
+// m = 'D';
+// if (mode->flag & FB_MODE_IS_VESA)
+// m = 'V';
+// if (mode->flag & FB_MODE_IS_STANDARD)
+// m = 'S';
+
+ if (mode->vmode & FB_VMODE_INTERLACED)
+ v = 'i';
+ if (mode->vmode & FB_VMODE_DOUBLE)
+ v = 'd';
+
+ return snprintf(&buf[offset], PAGE_SIZE - offset, "%dx%d%c-%d\n",
+ mode->xres, mode->yres, v, mode->refresh);
+}
+static ssize_t display_show_modes(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ struct list_head *modelist, *pos;
+ struct fb_modelist *fb_modelist;
+ const struct fb_videomode *mode;
+ int i;
+ if(dsp->ops && dsp->ops->getmodelist)
+ {
+ if(dsp->ops->getmodelist(dsp, &modelist))
+ return -EINVAL;
+ }
+ else
+ return 0;
+
+ i = 0;
+ list_for_each(pos, modelist) {
+ fb_modelist = list_entry(pos, struct fb_modelist, list);
+ mode = &fb_modelist->mode;
+ i += mode_string(buf, i, mode);
+ }
+ return i;
+}
+
+static ssize_t display_show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ struct fb_videomode mode;
+
+ if(dsp->ops && dsp->ops->getmode)
+ if(dsp->ops->getmode(dsp, &mode) == 0)
+ return mode_string(buf, 0, &mode);
+ return 0;
+}
+
+static ssize_t display_store_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ char mstr[100];
+ struct list_head *modelist, *pos;
+ struct fb_modelist *fb_modelist;
+ struct fb_videomode *mode;
+ size_t i;
+
+ if(dsp->ops && dsp->ops->getmodelist)
+ {
+ if(dsp->ops && dsp->ops->getmodelist)
+ {
+ if(dsp->ops->getmodelist(dsp, &modelist))
+ return -EINVAL;
+ }
+ list_for_each(pos, modelist) {
+ fb_modelist = list_entry(pos, struct fb_modelist, list);
+ mode = &fb_modelist->mode;
+ i = mode_string(mstr, 0, mode);
+ if (strncmp(mstr, buf, max(count, i)) == 0) {
+ if(dsp->ops && dsp->ops->setmode)
+ dsp->ops->setmode(dsp, mode);
+ return count;
+ }
+ }
+ }
+ return -EINVAL;
+}
+
+static struct device_attribute display_attrs[] = {
+ __ATTR(name, S_IRUGO, display_show_name, NULL),
+ __ATTR(type, S_IRUGO, display_show_type, NULL),
+ __ATTR(enable, S_IRUGO | /*S_IWUGO*/S_IWUSR, display_show_enable, display_store_enable),
+ __ATTR(connect, S_IRUGO, display_show_connect, NULL),
+ __ATTR(modes, S_IRUGO, display_show_modes, NULL),
+ __ATTR(mode, S_IRUGO | /*S_IWUGO*/S_IWUSR, display_show_mode, display_store_mode)
+};
+
+static int display_suspend(struct device *dev, pm_message_t state)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->suspend))
+ dsp->driver->suspend(dsp, state);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+static int display_resume(struct device *dev)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->resume))
+ dsp->driver->resume(dsp);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+void rk_display_device_enable(struct rk_display_device *ddev)
+{
+#ifndef CONFIG_DISPLAY_AUTO_SWITCH
+ return;
+#else
+ struct list_head *pos, *head = &display_device_list;
+ struct rk_display_device *dev = NULL, *dev_enabled = NULL, *dev_enable = NULL;
+ int enable = 0,connect, has_connect = 0;
+
+ list_for_each(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ enable = dev->ops->getenable(dev);
+ connect = dev->ops->getstatus(dev);
+ if(connect)
+ dev_enable = dev;
+ if(enable == 1)
+ dev_enabled = dev;
+ }
+ // If no device is connected, enable highest priority device.
+ if(dev_enable == NULL) {
+ dev->ops->setenable(dev, 1);
+ return;
+ }
+
+ if(dev_enable == dev_enabled) {
+ if(dev_enable != ddev)
+ ddev->ops->setenable(ddev, 0);
+ }
+ else {
+ if(dev_enabled)
+ dev_enabled->ops->setenable(dev_enabled, 0);
+ dev_enable->ops->setenable(dev_enable, 1);
+ }
+
+
+#endif
+}
+EXPORT_SYMBOL(rk_display_device_enable);
+
+void rk_display_device_enable_other(struct rk_display_device *ddev)
+{
+#ifndef CONFIG_DISPLAY_AUTO_SWITCH
+ return;
+#else
+ struct list_head *pos, *head = &display_device_list;
+ struct rk_display_device *dev;
+ int connect = 0;
+
+ list_for_each_prev(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ if(dev != ddev)
+ {
+ connect = dev->ops->getstatus(dev);
+ if(connect)
+ {
+ dev->ops->setenable(dev, 1);
+ return;
+ }
+ }
+ }
+#endif
+}
+EXPORT_SYMBOL(rk_display_device_enable_other);
+
+void rk_display_device_disable_other(struct rk_display_device *ddev)
+{
+#ifndef CONFIG_DISPLAY_AUTO_SWITCH
+ return;
+#else
+ struct list_head *pos, *head = &display_device_list;
+ struct rk_display_device *dev;
+ int enable = 0;
+
+ list_for_each(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ if(dev != ddev)
+ {
+ enable = dev->ops->getenable(dev);
+ if(enable)
+ dev->ops->setenable(dev, 0);
+ }
+ }
+ ddev->ops->setenable(ddev, 1);
+#endif
+}
+EXPORT_SYMBOL(rk_display_device_disable_other);
+
+void rk_display_device_select(int priority)
+{
+ struct list_head *pos, *head = &display_device_list;
+ struct rk_display_device *dev;
+ int enable, found = 0;
+
+ list_for_each(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ if(dev->priority == priority)
+ found = 1;
+ }
+
+ if(!found)
+ {
+ printk("[%s] select display interface %d not exist\n", __FUNCTION__, priority);
+ return;
+ }
+
+ list_for_each(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ enable = dev->ops->getenable(dev);
+ if(dev->priority == priority)
+ {
+ if(!enable)
+ dev->ops->setenable(dev, 1);
+ }
+ else if(enable)
+ dev->ops->setenable(dev, 0);
+ }
+}
+EXPORT_SYMBOL(rk_display_device_select);
+static struct mutex allocated_dsp_lock;
+static DEFINE_IDR(allocated_dsp);
+static struct class *display_class;
+
+struct rk_display_device *rk_display_device_register(struct rk_display_driver *driver,
+ struct device *parent, void *devdata)
+{
+ struct rk_display_device *new_dev = NULL;
+ int ret = -EINVAL;
+
+ if (unlikely(!driver))
+ return ERR_PTR(ret);
+
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
+ mutex_unlock(&allocated_dsp_lock);
+ if (!ret)
+ return ERR_PTR(ret);
+
+ new_dev = kzalloc(sizeof(struct rk_display_device), GFP_KERNEL);
+ if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
+ // Reserve the index for this display
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+
+ if (!ret) {
+ new_dev->dev = device_create(display_class, parent,
+ MKDEV(0, 0), new_dev,
+ "%s", new_dev->type);
+ if (!IS_ERR(new_dev->dev)) {
+ new_dev->parent = parent;
+ new_dev->driver = driver;
+ new_dev->dev->driver = parent->driver;
+ mutex_init(&new_dev->lock);
+ // Add new device to display device list.
+ {
+ struct list_head *pos, *head = &display_device_list;
+ struct rk_display_device *dev;
+
+ list_for_each(pos, head) {
+ dev = list_entry(pos, struct rk_display_device, list);
+ if(dev->priority > new_dev->priority)
+ break;
+ }
+ list_add_tail(&new_dev->list, pos);
+ }
+ return new_dev;
+ }
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ ret = -EINVAL;
+ }
+ }
+ kfree(new_dev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(rk_display_device_register);
+
+void rk_display_device_unregister(struct rk_display_device *ddev)
+{
+ if (!ddev)
+ return;
+ // Free device
+ mutex_lock(&ddev->lock);
+ device_unregister(ddev->dev);
+ mutex_unlock(&ddev->lock);
+ // Mark device index as avaliable
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, ddev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ list_del(&ddev->list);
+ kfree(ddev);
+}
+EXPORT_SYMBOL(rk_display_device_unregister);
+
+static int __init rk_display_class_init(void)
+{
+ display_class = class_create(THIS_MODULE, "display");
+ if (IS_ERR(display_class)) {
+ printk(KERN_ERR "Failed to create display class\n");
+ display_class = NULL;
+ return -EINVAL;
+ }
+ display_class->dev_attrs = display_attrs;
+ display_class->suspend = display_suspend;
+ display_class->resume = display_resume;
+ mutex_init(&allocated_dsp_lock);
+ INIT_LIST_HEAD(&display_device_list);
+ return 0;
+}
+
+static void __exit rk_display_class_exit(void)
+{
+ class_destroy(display_class);
+}
+
+subsys_initcall(rk_display_class_init);
+module_exit(rk_display_class_exit);
+
+
+MODULE_AUTHOR("zhengyang@rock-chips.com");
+MODULE_DESCRIPTION("Driver for rk display device");
+MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * display-sysfs.c - Display output driver sysfs interface
- *
- * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/module.h>
-#include <linux/display.h>
-#include <linux/ctype.h>
-#include <linux/idr.h>
-#include <linux/err.h>
-#include <linux/kdev_t.h>
-#include <linux/slab.h>
-
-static ssize_t display_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
-}
-
-static ssize_t display_show_type(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
-}
-
-static ssize_t display_show_contrast(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t rc = -ENXIO;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver) && dsp->driver->get_contrast)
- rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
- mutex_unlock(&dsp->lock);
- return rc;
-}
-
-static ssize_t display_store_contrast(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t ret = -EINVAL, size;
- int contrast;
- char *endp;
-
- contrast = simple_strtoul(buf, &endp, 0);
- size = endp - buf;
-
- if (isspace(*endp))
- size++;
-
- if (size != count)
- return ret;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver && dsp->driver->set_contrast)) {
- pr_debug("display: set contrast to %d\n", contrast);
- dsp->driver->set_contrast(dsp, contrast);
- ret = count;
- }
- mutex_unlock(&dsp->lock);
- return ret;
-}
-
-static ssize_t display_show_max_contrast(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t rc = -ENXIO;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver))
- rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
- mutex_unlock(&dsp->lock);
- return rc;
-}
-
-static struct device_attribute display_attrs[] = {
- __ATTR(name, S_IRUGO, display_show_name, NULL),
- __ATTR(type, S_IRUGO, display_show_type, NULL),
- __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
- __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
-};
-
-static int display_suspend(struct device *dev, pm_message_t state)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver->suspend))
- dsp->driver->suspend(dsp, state);
- mutex_unlock(&dsp->lock);
- return 0;
-};
-
-static int display_resume(struct device *dev)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver->resume))
- dsp->driver->resume(dsp);
- mutex_unlock(&dsp->lock);
- return 0;
-};
-
-static struct mutex allocated_dsp_lock;
-static DEFINE_IDR(allocated_dsp);
-static struct class *display_class;
-
-struct display_device *display_device_register(struct display_driver *driver,
- struct device *parent, void *devdata)
-{
- struct display_device *new_dev = NULL;
- int ret = -EINVAL;
-
- if (unlikely(!driver))
- return ERR_PTR(ret);
-
- mutex_lock(&allocated_dsp_lock);
- ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
- mutex_unlock(&allocated_dsp_lock);
- if (!ret)
- return ERR_PTR(ret);
-
- new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
- if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
- // Reserve the index for this display
- mutex_lock(&allocated_dsp_lock);
- ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
- mutex_unlock(&allocated_dsp_lock);
-
- if (!ret) {
- new_dev->dev = device_create(display_class, parent,
- MKDEV(0, 0), new_dev,
- "display%d", new_dev->idx);
- if (!IS_ERR(new_dev->dev)) {
- new_dev->parent = parent;
- new_dev->driver = driver;
- mutex_init(&new_dev->lock);
- return new_dev;
- }
- mutex_lock(&allocated_dsp_lock);
- idr_remove(&allocated_dsp, new_dev->idx);
- mutex_unlock(&allocated_dsp_lock);
- ret = -EINVAL;
- }
- }
- kfree(new_dev);
- return ERR_PTR(ret);
-}
-EXPORT_SYMBOL(display_device_register);
-
-void display_device_unregister(struct display_device *ddev)
-{
- if (!ddev)
- return;
- // Free device
- mutex_lock(&ddev->lock);
- device_unregister(ddev->dev);
- mutex_unlock(&ddev->lock);
- // Mark device index as available
- mutex_lock(&allocated_dsp_lock);
- idr_remove(&allocated_dsp, ddev->idx);
- mutex_unlock(&allocated_dsp_lock);
- kfree(ddev);
-}
-EXPORT_SYMBOL(display_device_unregister);
-
-static int __init display_class_init(void)
-{
- display_class = class_create(THIS_MODULE, "display");
- if (IS_ERR(display_class)) {
- printk(KERN_ERR "Failed to create display class\n");
- display_class = NULL;
- return -EINVAL;
- }
- display_class->dev_attrs = display_attrs;
- display_class->suspend = display_suspend;
- display_class->resume = display_resume;
- mutex_init(&allocated_dsp_lock);
- return 0;
-}
-
-static void __exit display_class_exit(void)
-{
- class_destroy(display_class);
-}
-
-module_init(display_class_init);
-module_exit(display_class_exit);
-
-MODULE_DESCRIPTION("Display Hardware handling");
-MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
-MODULE_LICENSE("GPL");
-
--- /dev/null
+config RK610_LCD
+ bool "RK610(Jetta) lcd support"
+ depends on MFD_RK610
+ default y if MFD_RK610
+ help
+ Support Jetta(RK610) to output LCD1 and LVDS.
--- /dev/null
+#
+# Makefile for the jetta tv control.
+#
+obj-$(CONFIG_RK610_LCD) += rk610_lcd.o
--- /dev/null
+#include <linux/fb.h>\r
+#include <linux/delay.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+\r
+#include <linux/hdmi.h>\r
+#include "rk610_lcd.h"\r
+#include <linux/mfd/rk610_core.h>\r
+#include "../../rk29_fb.h"\r
+static struct i2c_client *rk610_g_lcd_client=NULL;\r
+//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
+//{\r
+ //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+//}\r
+\r
+static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+static void rk610_scaler_pll_enable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+}\r
+static void rk610_scaler_pll_disable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+}\r
+static void rk610_scaler_enable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+}\r
+static void rk610_scaler_disable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+}\r
+static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,bool enable)\r
+{\r
+ char c=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ if(SCREEN_LVDS == screen->type){\r
+ c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \\r
+ |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
+ |LVDS_OUTPUT_FORMAT(screen->hw_format) ; \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
+ c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
+ }else if(SCREEN_RGB == screen->type){\r
+ c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC(enable?LCD1_FROM_SCL : LCD1_FROM_LCD0);\r
+ rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
+ }\r
+ return 0;\r
+}\r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin )\r
+{\r
+ char c=0;\r
+ char M=0,N=0,OD=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ /***************SET SCALER PLL FROM CLKIN ,DIV 0*/\r
+ if(screen->s_pixclock != 0){\r
+ OD = (screen->s_pixclock)&0x3;\r
+ N = (screen->s_pixclock >>4)&0xf;\r
+ M = (screen->s_pixclock >>8)&0xff;\r
+ }else {\r
+ RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n");\r
+ }\r
+ c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0);\r
+ rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c);\r
+ \r
+ c = S_DIV_N(N)| S_DIV_OD(OD);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c);\r
+ c = S_DIV_M(M);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c);\r
+ rk610_scaler_pll_enable(client);\r
+ return 0;\r
+}\r
+\r
+\r
+static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act)\r
+ {\r
+ char c;\r
+ u32 hfactor_f,vfactor_f,scl_factor_f;\r
+ int hfactor;\r
+ int vfactor;\r
+ struct scl_hv_info HV2;\r
+ hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1);\r
+ if(hfactor_f==4096)\r
+ {hfactor = 0x1000;}\r
+ else if(hfactor_f>(int)hfactor_f)\r
+ {hfactor = (int)hfactor_f+1;}\r
+ else\r
+ {hfactor = (int)hfactor_f;}\r
+ \r
+ scl_factor_f = Vin_act/Vout_act;\r
+ if(scl_factor_f<2)\r
+ {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);}\r
+ else\r
+ {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} \r
+ if(vfactor_f==4096)\r
+ {vfactor = 0x1000;}\r
+ else if(vfactor_f>(int)vfactor_f)\r
+ {vfactor = (int)vfactor_f+1;}\r
+ else\r
+ {vfactor = (int)vfactor_f;}\r
+ \r
+ HV2.scl_h= hfactor;\r
+ HV2.scl_v= vfactor; \r
+ /* SCL FACTOR */\r
+ c = SCL_H_FACTOR_LSB(HV2.scl_h);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON1, &c);\r
+ c = SCL_H_FACTOR_MSB(HV2.scl_h);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON2, &c);\r
+\r
+ c = SCL_V_FACTOR_LSB(HV2.scl_v);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON3, &c);\r
+ c = SCL_V_FACTOR_MSB(HV2.scl_v);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON4, &c);\r
+ return 0;\r
+ }\r
+\r
+static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen)\r
+{\r
+ switch(screen->hdmi_resolution){\r
+ case HDMI_1920x1080p_60Hz:\r
+ case HDMI_1920x1080p_50Hz:\r
+ rk610_scaler_pll_set(client,screen,148500000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res);\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ case HDMI_1280x720p_50Hz:\r
+ rk610_scaler_pll_set(client,screen,74250000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,1280,screen->x_res,720,screen->y_res);\r
+ break;\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ rk610_scaler_pll_set(client,screen,27000000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,720,screen->x_res,576,screen->y_res);\r
+ break;\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ rk610_scaler_pll_set(client,screen,27000000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,720,screen->x_res,480,screen->y_res);\r
+ break;\r
+ default :\r
+ RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); \r
+ return -1;\r
+ break;\r
+ }\r
+}\r
+static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen)\r
+{\r
+ char c;\r
+ int h_st = screen->s_hsync_st;\r
+ int hs_end = screen->s_hsync_len;\r
+ int h_act_st = hs_end + screen->s_left_margin;\r
+ int xres = screen->x_res;\r
+ int h_act_end = h_act_st + xres;\r
+ int h_total = h_act_end + screen->s_right_margin;\r
+ int v_st = screen->s_vsync_st;\r
+ int vs_end = screen->s_vsync_len;\r
+ int v_act_st = vs_end + screen->s_upper_margin;\r
+ int yres = screen->y_res; \r
+ int v_act_end = v_act_st + yres;\r
+ int v_total = v_act_end + screen->s_lower_margin;\r
+\r
+ /* SCL display Frame start point */\r
+ c = SCL_DSP_HST_LSB(h_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON5, &c);\r
+ c = SCL_DSP_HST_MSB(h_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON6, &c);\r
+\r
+ c = SCL_DSP_VST_LSB(v_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON7, &c);\r
+ c = SCL_DSP_VST_MSB(v_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON8, &c);\r
+ /* SCL output timing */\r
+\r
+ c = SCL_DSP_HTOTAL_LSB(h_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON9, &c);\r
+ c = SCL_DSP_HTOTAL_MSB(h_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON10, &c);\r
+\r
+ c = SCL_DSP_HS_END(hs_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON11, &c);\r
+\r
+ c = SCL_DSP_HACT_ST_LSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON12, &c);\r
+ c = SCL_DSP_HACT_ST_MSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON13, &c);\r
+\r
+ c = SCL_DSP_HACT_END_LSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON14, &c);\r
+ c = SCL_DSP_HACT_END_MSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON15, &c);\r
+\r
+ c = SCL_DSP_VTOTAL_LSB(v_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON16, &c);\r
+ c = SCL_DSP_VTOTAL_MSB(v_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON17, &c);\r
+\r
+ c = SCL_DSP_VS_END(vs_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON18, &c);\r
+\r
+ c = SCL_DSP_VACT_ST(v_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON19, &c);\r
+\r
+ c = SCL_DSP_VACT_END_LSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON20, &c);\r
+ c = SCL_DSP_VACT_END_MSB(v_act_end); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON21, &c);\r
+ \r
+ c = SCL_H_BORD_ST_LSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON22, &c);\r
+ c = SCL_H_BORD_ST_MSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON23, &c);\r
+\r
+ c = SCL_H_BORD_END_LSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON24, &c);\r
+ c = SCL_H_BORD_END_MSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON25, &c);\r
+\r
+ c = SCL_V_BORD_ST(v_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON26, &c);\r
+\r
+ c = SCL_V_BORD_END_LSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON27, &c);\r
+ c = SCL_V_BORD_END_MSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON28, &c);\r
+ \r
+ return 0;\r
+}\r
+static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen)\r
+{\r
+\r
+ RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution);\r
+ rk610_scaler_fator_config(client,screen);\r
+ rk610_scaler_enable(client);\r
+ rk610_scaler_output_timing_config(client,screen); \r
+ \r
+ return 0;\r
+\r
+}\r
+#endif\r
+static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale\r
+{\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ rk610_scaler_pll_disable(client);\r
+ rk610_scaler_disable(client);\r
+ \r
+ return 0;\r
+}\r
+int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale\r
+{\r
+ int ret=0;\r
+ struct i2c_client *client = rk610_g_lcd_client;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ if(client == NULL){\r
+ RK610_ERR(&client->dev,"%s client == NULL FAIL\n",__FUNCTION__);\r
+ return -1;\r
+ }\r
+ \r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+ if(enable == 1){\r
+ rk610_output_config(client,screen,1);\r
+ ret = rk610_scaler_chg(client,screen);\r
+ }\r
+ else \r
+#endif\r
+ {\r
+ rk610_output_config(client,screen,0);\r
+ ret = rk610_lcd_scaler_bypass(client,enable);\r
+ }\r
+ return ret;\r
+}\r
+int rk610_lcd_init(struct i2c_client *client)\r
+{\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ rk610_g_lcd_client = client;\r
+ return 0;\r
+}\r
--- /dev/null
+#ifndef _RK610_LCD_H\r
+#define _RK610_LCD_H\r
+#include "../screen/screen.h"\r
+#define ENABLE 1\r
+#define DISABLE 0\r
+/* LVDS config */\r
+/* LVDS ÍⲿÁ¬Ïß½Ó·¨ */\r
+#define LVDS_8BIT_1 0x00\r
+#define LVDS_8BIT_2 0x01\r
+#define LVDS_8BIT_3 0x10\r
+#define LVDS_6BIT 0x11\r
+//LVDS lane input format\r
+#define DATA_D0_MSB 0\r
+#define DATA_D7_MSB 1\r
+//LVDS input source\r
+#define FROM_LCD1 0\r
+#define FROM_LCD0_OR_SCL 1\r
+\r
+/* LCD1 config */\r
+#define LCD1_AS_IN 0\r
+#define LCD1_AS_OUT 1\r
+\r
+//LCD1 output source\r
+#define LCD1_FROM_LCD0 0\r
+#define LCD1_FROM_SCL 1\r
+\r
+/* clock config */\r
+#define S_PLL_FROM_DIV 0\r
+#define S_PLL_FROM_CLKIN 1\r
+#define S_PLL_DIV(x) ((x)&0x7)\r
+/*********S_PLL_CON************/\r
+//S_PLL_CON0\r
+#define S_DIV_N(x) (((x)&0xf)<<4)\r
+#define S_DIV_OD(x) (((x)&3)<<0)\r
+//S_PLL_CON1\r
+#define S_DIV_M(x) ((x)&0xff)\r
+//S_PLL_CON2\r
+#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock\r
+#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock\r
+#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN\r
+#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers\r
+#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass\r
+//LVDS_CON0\r
+#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable\r
+#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable \r
+#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable \r
+#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7\r
+#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler\r
+#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format \r
+//LVDS_CON1\r
+#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable\r
+#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down\r
+//LCD1_CON\r
+#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output\r
+#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler\r
+//SCL_CON0\r
+#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass\r
+#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv\r
+#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv\r
+#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv\r
+#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable\r
+//SCL_CON1\r
+#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0]\r
+//SCL_CON2\r
+#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8]\r
+//SCL_CON3\r
+#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0]\r
+//SCL_CON4\r
+#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8]\r
+//SCL_CON5\r
+#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0]\r
+//SCL_CON6\r
+#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8]\r
+//SCL_CON7\r
+#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0]\r
+//SCL_CON8\r
+#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8]\r
+//SCL_CON9\r
+#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0]\r
+//SCL_CON10\r
+#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
+//SCL_CON11\r
+#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end\r
+//SCL_CON12\r
+#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0]\r
+//SCL_CON13\r
+#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8]\r
+//SCL_CON14\r
+#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0]\r
+//SCL_CON15\r
+#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
+//SCL_CON16\r
+#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0]\r
+//SCL_CON17\r
+#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
+//SCL_CON18\r
+#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end\r
+//SCL_CON19\r
+#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0]\r
+//SCL_CON20\r
+#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0]\r
+//SCL_CON21\r
+#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
+//SCL_CON22\r
+#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0]\r
+//SCL_CON23\r
+#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8]\r
+//SCL_CON24\r
+#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0]\r
+//SCL_CON25\r
+#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8]\r
+//SCL_CON26\r
+#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0]\r
+//SCL_CON27\r
+#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0]\r
+//SCL_CON25\r
+#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8]\r
+#if 0\r
+/****************LCD STRUCT********/\r
+#define PLL_CLKOD(i) ((i) & 0x03)\r
+#define PLL_NO_1 PLL_CLKOD(0)
+#define PLL_NO_2 PLL_CLKOD(1)
+#define PLL_NO_4 PLL_CLKOD(2)
+#define PLL_NO_8 PLL_CLKOD(3)\r
+#define SCALE_PLL(_parent_rate , _rate, _m, _n, _od) \\r
+{ \
+ .parent_rate = _parent_rate, \\r
+ .rate = _rate, \\r
+ .m = _m, \\r
+ .n = _n, \\r
+ .od = _od, \\r
+}\r
+#endif\r
+struct rk610_pll_info{\r
+ u32 parent_rate;\r
+ u32 rate;\r
+ int m;\r
+ int n;\r
+ int od;\r
+};\r
+struct lcd_mode_inf{\r
+ int h_pw;\r
+ int h_bp;\r
+ int h_vd;\r
+ int h_fp;\r
+ int v_pw;\r
+ int v_bp;\r
+ int v_vd;\r
+ int v_fp;\r
+ int f_hst;\r
+ int f_vst;\r
+ struct rk610_pll_info pllclk;\r
+};\r
+struct scl_hv_info{\r
+ int scl_h ;\r
+ int scl_v;\r
+ };\r
+struct rk610_lcd_info{\r
+ int enable;\r
+ struct scl_hv_info scl;\r
+ struct lcd_mode_inf *lcd_mode;\r
+};\r
+extern int rk610_lcd_init(struct i2c_client *client);\r
+extern int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable );\r
+#endif\r
bool "RGB A050VL01"
config LCD_B101EW05
bool "RGB lcd panel B101EW05"
+config LCD_HDMI_1024x768
+ depends on MFD_RK610
+ bool "RGB Hannstar LCD_HDMI_1024X768"
+ ---help---
+ if support RK610, this setting can support dual screen output
+config LCD_HDMI_800x480
+ depends on MFD_RK610
+ bool "RGB Hannstar LCD_HDMI_800x480"
+ ---help---
+ if support RK610, this setting can support dual screen output
endchoice
obj-$(CONFIG_LCD_HX8357) += lcd_hx8357.o
obj-$(CONFIG_LCD_HSD100PXN) += lcd_hsd100pxn.o
+obj-$(CONFIG_LCD_HDMI_1024x768) += lcd_hdmi_1024x768.o
+obj-$(CONFIG_LCD_HDMI_800x480) += lcd_hdmi_800x480.o
obj-$(CONFIG_LCD_HSD07PFW1) += lcd_hsd07pfw1.o
obj-$(CONFIG_LCD_B101AW06) += lcd_B101AW06.o
obj-$(CONFIG_LCD_NT35510) += lcd_nt35510.o
--- /dev/null
+#include <linux/fb.h>\r
+#include <linux/delay.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+#include "screen.h"\r
+#include <linux/hdmi.h>\r
+#include "../../rk29_fb.h"\r
+#include "../lcd/rk610_lcd.h"\r
+\r
+/* Base */\r
+#define OUT_TYPE SCREEN_LVDS\r
+\r
+#define OUT_FORMAT LVDS_8BIT_3\r
+#define OUT_FACE OUT_D888_P666 \r
+#define OUT_CLK 65000000\r
+#define LCDC_ACLK 500000000//312000000 //29 lcdc axi DMA ƵÂÊ\r
+\r
+/* Timing */\r
+#define H_PW 48 //10\r
+#define H_BP 88 //100\r
+#define H_VD 800 //1024\r
+#define H_FP 40 //210\r
+\r
+#define V_PW 3 //10\r
+#define V_BP 32 //10\r
+#define V_VD 480 //768\r
+#define V_FP 13 //18\r
+\r
+#define LCD_WIDTH 202\r
+#define LCD_HEIGHT 152\r
+\r
+/* scaler Timing */\r
+//1920*1080*60\r
+#define S_OUT_CLK SCALE_RATE(148500000,66000000)\r
+#define S_H_PW 100\r
+#define S_H_BP 100\r
+#define S_H_VD 1024\r
+#define S_H_FP 151\r
+\r
+#define S_V_PW 5\r
+#define S_V_BP 15\r
+#define S_V_VD 768\r
+#define S_V_FP 12\r
+\r
+#define S_H_ST 1757\r
+#define S_V_ST 14\r
+\r
+//1920*1080*50\r
+#define S1_OUT_CLK SCALE_RATE(148500000,54000000)\r
+#define S1_H_PW 100\r
+#define S1_H_BP 100\r
+#define S1_H_VD 1024\r
+#define S1_H_FP 126\r
+\r
+#define S1_V_PW 5\r
+#define S1_V_BP 15\r
+#define S1_V_VD 768\r
+#define S1_V_FP 12\r
+\r
+#define S1_H_ST 1757\r
+#define S1_V_ST 14\r
+/* Other */\r
+#define DCLK_POL 0\r
+#define SWAP_RB 0 \r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+static int set_scaler_info(struct rk29fb_screen *screen, u8 hdmi_resolution)\r
+{\r
+ switch(hdmi_resolution){\r
+ case HDMI_1920x1080p_60Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S_OUT_CLK;\r
+ screen->s_hsync_len = S_H_PW;\r
+ screen->s_left_margin = S_H_BP;\r
+ screen->s_right_margin = S_H_FP;\r
+ screen->s_hsync_len = S_H_PW;\r
+ screen->s_upper_margin = S_V_BP;\r
+ screen->s_lower_margin = S_V_FP;\r
+ screen->s_vsync_len = S_V_PW;\r
+ screen->s_hsync_st = S_H_ST;\r
+ screen->s_vsync_st = S_V_ST;\r
+ break;\r
+ case HDMI_1920x1080p_50Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S1_OUT_CLK;\r
+ screen->s_hsync_len = S1_H_PW;\r
+ screen->s_left_margin = S1_H_BP;\r
+ screen->s_right_margin = S1_H_FP;\r
+ screen->s_hsync_len = S1_H_PW;\r
+ screen->s_upper_margin = S1_V_BP;\r
+ screen->s_lower_margin = S1_V_FP;\r
+ screen->s_vsync_len = S1_V_PW;\r
+ screen->s_hsync_st = S1_H_ST;\r
+ screen->s_vsync_st = S1_V_ST;\r
+ break;\r
+ default :\r
+ printk("%s lcd not support dual display at this hdmi resolution %d \n",__func__,hdmi_resolution);\r
+ return -1;\r
+ break;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+#else\r
+static int set_scaler_info(struct rk29fb_screen *screen, u8 hdmi_resolution){}\r
+#endif\r
+\r
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )\r
+{\r
+ /* screen type & face */\r
+ screen->type = OUT_TYPE;\r
+ screen->face = OUT_FACE;\r
+\r
+ /* Screen size */\r
+ screen->x_res = H_VD;\r
+ screen->y_res = V_VD;\r
+\r
+ screen->width = LCD_WIDTH;\r
+ screen->height = LCD_HEIGHT;\r
+\r
+ /* Timing */\r
+ screen->lcdc_aclk = LCDC_ACLK;\r
+ screen->pixclock = OUT_CLK;\r
+ screen->left_margin = H_BP;\r
+ screen->right_margin = H_FP;\r
+ screen->hsync_len = H_PW;\r
+ screen->upper_margin = V_BP;\r
+ screen->lower_margin = V_FP;\r
+ screen->vsync_len = V_PW;\r
+ \r
+ /* Pin polarity */\r
+ screen->pin_hsync = 0;\r
+ screen->pin_vsync = 0;\r
+ screen->pin_den = 0;\r
+ screen->pin_dclk = DCLK_POL;\r
+\r
+ /* Swap rule */\r
+ screen->swap_rb = SWAP_RB;\r
+ screen->swap_rg = 0;\r
+ screen->swap_gb = 0;\r
+ screen->swap_delta = 0;\r
+ screen->swap_dumy = 0;\r
+\r
+ /* Operation function*/\r
+ screen->init = NULL;\r
+ screen->standby = NULL;\r
+ screen->sscreen_get = set_scaler_info;\r
+#ifdef CONFIG_RK610_LCD\r
+ screen->sscreen_set = rk610_lcd_scaler_set_param;\r
+#endif\r
+}
\ No newline at end of file
--- /dev/null
+#include <linux/fb.h>\r
+#include <linux/delay.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+#include "screen.h"\r
+#include <linux/hdmi.h>\r
+#include "../../rk29_fb.h"\r
+#include "../lcd/rk610_lcd.h"\r
+\r
+/* Base */\r
+#define OUT_TYPE SCREEN_RGB\r
+\r
+#define OUT_FACE OUT_P888 \r
+#define OUT_CLK 33000000\r
+#define LCDC_ACLK 150000000//312000000 //29 lcdc axi DMA ƵÂÊ\r
+\r
+/* Timing */
+#define H_PW 1
+#define H_BP 88
+#define H_VD 800
+#define H_FP 40
+
+#define V_PW 3
+#define V_BP 29
+#define V_VD 480
+#define V_FP 13\r
+\r
+#define LCD_WIDTH 154\r
+#define LCD_HEIGHT 85\r
+\r
+/* scaler Timing */\r
+//1920*1080*60\r
+\r
+#define S_OUT_CLK SCALE_RATE(148500000,33000000)\r
+#define S_H_PW 1\r
+#define S_H_BP 88\r
+#define S_H_VD 800\r
+#define S_H_FP 211\r
+\r
+#define S_V_PW 3\r
+#define S_V_BP 10\r
+#define S_V_VD 480\r
+#define S_V_FP 7\r
+\r
+#define S_H_ST 244\r
+#define S_V_ST 11\r
+\r
+//1920*1080*50\r
+#define S1_OUT_CLK SCALE_RATE(148500000,30375000)\r
+#define S1_H_PW 1\r
+#define S1_H_BP 88\r
+#define S1_H_VD 800\r
+#define S1_H_FP 326\r
+
+#define S1_V_PW 3\r
+#define S1_V_BP 9\r
+#define S1_V_VD 480\r
+#define S1_V_FP 8\r
+\r
+#define S1_H_ST 270\r
+#define S1_V_ST 13\r
+//1280*720*60\r
+#define S2_OUT_CLK SCALE_RATE(74250000,33000000)\r
+#define S2_H_PW 1\r
+#define S2_H_BP 88\r
+#define S2_H_VD 800\r
+#define S2_H_FP 211\r
+
+#define S2_V_PW 3\r
+#define S2_V_BP 9\r
+#define S2_V_VD 480\r
+#define S2_V_FP 8\r
+\r
+#define S2_H_ST 0\r
+#define S2_V_ST 8\r
+//1280*720*50\r
+\r
+#define S3_OUT_CLK SCALE_RATE(74250000,30375000)\r
+#define S3_H_PW 1\r
+#define S3_H_BP 88\r
+#define S3_H_VD 800\r
+#define S3_H_FP 326\r
+
+#define S3_V_PW 3\r
+#define S3_V_BP 9\r
+#define S3_V_VD 480\r
+#define S3_V_FP 8\r
+\r
+#define S3_H_ST 0\r
+#define S3_V_ST 8\r
+\r
+//720*576*50\r
+#define S4_OUT_CLK SCALE_RATE(27000000,30000000)\r
+#define S4_H_PW 1\r
+#define S4_H_BP 88\r
+#define S4_H_VD 800\r
+#define S4_H_FP 263\r
+
+#define S4_V_PW 3\r
+#define S4_V_BP 9\r
+#define S4_V_VD 480\r
+#define S4_V_FP 28\r
+\r
+#define S4_H_ST 0\r
+#define S4_V_ST 33\r
+//720*480*60\r
+#define S5_OUT_CLK SCALE_RATE(27000000,31500000)\r
+#define S5_H_PW 1\r
+#define S5_H_BP 88\r
+#define S5_H_VD 800\r
+#define S5_H_FP 112\r
+
+#define S5_V_PW 3\r
+#define S5_V_BP 9\r
+#define S5_V_VD 480\r
+#define S5_V_FP 28\r
+\r
+#define S5_H_ST 0\r
+#define S5_V_ST 29\r
+/* Other */\r
+#define DCLK_POL 0\r
+#define SWAP_RB 0 \r
+\r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+static int set_scaler_info(struct rk29fb_screen *screen, u8 hdmi_resolution)\r
+{\r
+ switch(hdmi_resolution){\r
+ case HDMI_1920x1080p_60Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S_OUT_CLK;\r
+ screen->s_hsync_len = S_H_PW;\r
+ screen->s_left_margin = S_H_BP;\r
+ screen->s_right_margin = S_H_FP;\r
+ screen->s_hsync_len = S_H_PW;\r
+ screen->s_upper_margin = S_V_BP;\r
+ screen->s_lower_margin = S_V_FP;\r
+ screen->s_vsync_len = S_V_PW;\r
+ screen->s_hsync_st = S_H_ST;\r
+ screen->s_vsync_st = S_V_ST;\r
+ break;\r
+ case HDMI_1920x1080p_50Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S1_OUT_CLK;\r
+ screen->s_hsync_len = S1_H_PW;\r
+ screen->s_left_margin = S1_H_BP;\r
+ screen->s_right_margin = S1_H_FP;\r
+ screen->s_hsync_len = S1_H_PW;\r
+ screen->s_upper_margin = S1_V_BP;\r
+ screen->s_lower_margin = S1_V_FP;\r
+ screen->s_vsync_len = S1_V_PW;\r
+ screen->s_hsync_st = S1_H_ST;\r
+ screen->s_vsync_st = S1_V_ST;\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S2_OUT_CLK;\r
+ screen->s_hsync_len = S2_H_PW;\r
+ screen->s_left_margin = S2_H_BP;\r
+ screen->s_right_margin = S2_H_FP;\r
+ screen->s_hsync_len = S2_H_PW;\r
+ screen->s_upper_margin = S2_V_BP;\r
+ screen->s_lower_margin = S2_V_FP;\r
+ screen->s_vsync_len = S2_V_PW;\r
+ screen->s_hsync_st = S2_H_ST;\r
+ screen->s_vsync_st = S2_V_ST;\r
+ break;\r
+ case HDMI_1280x720p_50Hz:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S3_OUT_CLK;\r
+ screen->s_hsync_len = S3_H_PW;\r
+ screen->s_left_margin = S3_H_BP;\r
+ screen->s_right_margin = S3_H_FP;\r
+ screen->s_hsync_len = S3_H_PW;\r
+ screen->s_upper_margin = S3_V_BP;\r
+ screen->s_lower_margin = S3_V_FP;\r
+ screen->s_vsync_len = S3_V_PW;\r
+ screen->s_hsync_st = S3_H_ST;\r
+ screen->s_vsync_st = S3_V_ST;\r
+ break;\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S4_OUT_CLK;\r
+ screen->s_hsync_len = S4_H_PW;\r
+ screen->s_left_margin = S4_H_BP;\r
+ screen->s_right_margin = S4_H_FP;\r
+ screen->s_hsync_len = S4_H_PW;\r
+ screen->s_upper_margin = S4_V_BP;\r
+ screen->s_lower_margin = S4_V_FP;\r
+ screen->s_vsync_len = S4_V_PW;\r
+ screen->s_hsync_st = S4_H_ST;\r
+ screen->s_vsync_st = S4_V_ST;\r
+ break;\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ /* Scaler Timing */\r
+ screen->hdmi_resolution = hdmi_resolution;\r
+ screen->s_pixclock = S5_OUT_CLK;\r
+ screen->s_hsync_len = S5_H_PW;\r
+ screen->s_left_margin = S5_H_BP;\r
+ screen->s_right_margin = S5_H_FP;\r
+ screen->s_hsync_len = S5_H_PW;\r
+ screen->s_upper_margin = S5_V_BP;\r
+ screen->s_lower_margin = S5_V_FP;\r
+ screen->s_vsync_len = S5_V_PW;\r
+ screen->s_hsync_st = S5_H_ST;\r
+ screen->s_vsync_st = S5_V_ST;\r
+ break;\r
+ default :\r
+ printk("%s lcd not support dual display at this hdmi resolution %d \n",__func__,hdmi_resolution);\r
+ return -1;\r
+ break;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+#else\r
+static int set_scaler_info(struct rk29fb_screen *screen, u8 hdmi_resolution){}\r
+#endif\r
+\r
+void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )\r
+{\r
+ /* screen type & face */\r
+ screen->type = OUT_TYPE;\r
+ screen->face = OUT_FACE;\r
+\r
+ /* Screen size */\r
+ screen->x_res = H_VD;\r
+ screen->y_res = V_VD;\r
+\r
+ screen->width = LCD_WIDTH;\r
+ screen->height = LCD_HEIGHT;\r
+\r
+ /* Timing */\r
+ screen->lcdc_aclk = LCDC_ACLK;\r
+ screen->pixclock = OUT_CLK;\r
+ screen->left_margin = H_BP;\r
+ screen->right_margin = H_FP;\r
+ screen->hsync_len = H_PW;\r
+ screen->upper_margin = V_BP;\r
+ screen->lower_margin = V_FP;\r
+ screen->vsync_len = V_PW;\r
+ \r
+ /* Pin polarity */\r
+ screen->pin_hsync = 0;\r
+ screen->pin_vsync = 0;\r
+ screen->pin_den = 0;\r
+ screen->pin_dclk = DCLK_POL;\r
+\r
+ /* Swap rule */\r
+ screen->swap_rb = SWAP_RB;\r
+ screen->swap_rg = 0;\r
+ screen->swap_gb = 0;\r
+ screen->swap_delta = 0;\r
+ screen->swap_dumy = 0;\r
+\r
+ /* Operation function*/\r
+ screen->init = NULL;\r
+ screen->standby = NULL;\r
+ screen->sscreen_get = set_scaler_info;\r
+#ifdef CONFIG_RK610_LCD\r
+ screen->sscreen_set = rk610_lcd_scaler_set_param;\r
+#endif\r
+}\r
+\r
/* Base */
#define OUT_TYPE SCREEN_RGB
#define OUT_FACE OUT_P888
-#define OUT_CLK 28000000
+#define OUT_CLK 33000000
#define LCDC_ACLK 150000000 //29 lcdc axi DMA ƵÂÊ
/* Timing */
-#define H_PW 1
-#define H_BP 88
-#define H_VD 800
-#define H_FP 40
+#define H_PW 8 //10
+#define H_BP 88 //100
+#define H_VD 800 //1024
+#define H_FP 40 //210
-#define V_PW 3
-#define V_BP 29
-#define V_VD 480
-#define V_FP 13
+#define V_PW 3 //10
+#define V_BP 10 //10
+#define V_VD 480 //768
+#define V_FP 32 //18
/* Other */
-#define DCLK_POL 1
+#define DCLK_POL 0
#define SWAP_RB 0
-#define LCD_WIDTH 800 //need modify
-#define LCD_HEIGHT 480
+#define LCD_WIDTH 154 //need modify
+#define LCD_HEIGHT 85
#define TXD_PORT gLcd_info->txd_pin
#define CLK_PORT gLcd_info->clk_pin
+#ifndef _SCREEN_H
+#define _SCREEN_H
#include <mach/board.h>
+#ifdef CONFIG_HDMI_DUAL_DISP
+/* Scaler PLL CONFIG */
+#define S_PLL_NO_1 0
+#define S_PLL_NO_2 1
+#define S_PLL_NO_4 2
+#define S_PLL_NO_8 3
+#define S_PLL_M(x) (((x)&0xff)<<8)
+#define S_PLL_N(x) (((x)&0xf)<<4)
+#define S_PLL_NO(x) ((S_PLL_NO_##x)&0x3)
+
+enum{
+ HDMI_RATE_148500000,
+ HDMI_RATE_74250000,
+ HDMI_RATE_27000000,
+};
+/* Scaler clk setting */
+#define SCALE_PLL(_parent_rate,_rate,_m,_n,_no) \
+ HDMI_RATE_ ## _parent_rate ##_S_RATE_ ## _rate \
+ = S_PLL_M(_m) | S_PLL_N(_n) | S_PLL_NO(_no)
+#define SCALE_RATE(_parent_rate , _rate) \
+ (HDMI_RATE_ ## _parent_rate ## _S_RATE_ ## _rate)
+
+enum{
+ SCALE_PLL(148500000, 66000000, 16, 9, 4),
+ SCALE_PLL(148500000, 54000000, 16, 11, 4),
+ SCALE_PLL(148500000, 33000000, 16, 9, 8),
+ SCALE_PLL(148500000, 30375000, 18, 11, 8),
+ SCALE_PLL(148500000, 29700000, 16, 10, 8),
+ SCALE_PLL(148500000, 25312500, 15, 11, 8),
+
+ SCALE_PLL(74250000, 66000000, 32, 9, 4),
+ SCALE_PLL(74250000, 54000000, 32, 11, 4),
+ SCALE_PLL(74250000, 33000000, 32, 9, 8),
+ SCALE_PLL(74250000, 30375000, 36, 11, 8),
+ SCALE_PLL(74250000, 25312500, 30, 11, 8),
+
+ SCALE_PLL(27000000, 31500000, 28, 3, 8),
+ SCALE_PLL(27000000, 30000000, 80, 9, 8),
+};
+#endif
typedef enum _SCREEN_TYPE {
SCREEN_NULL = 0,
SCREEN_RGB,
+ SCREEN_LVDS,
SCREEN_MCU,
SCREEN_TVOUT,
SCREEN_HDMI,
/* Screen description */
typedef struct rk29fb_screen {
- /* screen type & out face */
+ /* screen type & hardware connect format & out face */
u16 type;
+ u16 hw_format;
u16 face;
/* Screen size */
u16 width;
u16 height;
+ u32 mode;
/* Timing */
u32 pixclock;
u16 left_margin;
u16 upper_margin;
u16 lower_margin;
u16 vsync_len;
-
+#ifdef CONFIG_HDMI_DUAL_DISP
+ /* Scaler mode Timing */
+ u32 s_pixclock;
+ u16 s_left_margin;
+ u16 s_right_margin;
+ u16 s_hsync_len;
+ u16 s_upper_margin;
+ u16 s_lower_margin;
+ u16 s_vsync_len;
+ u16 s_hsync_st;
+ u16 s_vsync_st;
+#endif
+ u8 hdmi_resolution;
/* mcu need */
u8 mcu_wrperiod;
u8 mcu_usefmk;
int (*refresh)(u8 arg);
int (*scandir)(u16 dir);
int (*disparea)(u8 area);
-
+ int (*sscreen_get)(struct rk29fb_screen *screen, u8 resolution);
+ int (*sscreen_set)(struct rk29fb_screen *screen, bool type);// 1: use scaler 0:bypass
} rk_screen;
+
extern void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info);
extern void set_tv_info(struct rk29fb_screen *screen);
extern void set_hdmi_info(struct rk29fb_screen *screen);
-
+#endif
--- /dev/null
+config RK610_TVOUT
+ bool "RK610(Jetta) tvout support"
+ depends on MFD_RK610
+ default y if MFD_RK610
+ help
+ Support Jetta(RK610) to output YPbPr and CVBS.
+
+config RK610_TVOUT_YPbPr
+ bool "support YPbPr output"
+ depends on RK610_TVOUT
+config RK610_TVOUT_CVBS
+ bool "support CVBS output"
+ depends on RK610_TVOUT
--- /dev/null
+#
+# Makefile for the jetta tv control.
+#
+obj-$(CONFIG_RK610_TVOUT) += rk610_tv.o
+obj-$(CONFIG_RK610_TVOUT_YPbPr) += rk610_tv_ypbpr.o
+obj-$(CONFIG_RK610_TVOUT_CVBS) += rk610_tv_cvbs.o
\ No newline at end of file
--- /dev/null
+/*
+ * rk610_tv.c
+ *
+ * Driver for rockchip rk610 tv control
+ * Copyright (C) 2009
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ *
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <asm/uaccess.h>
+#include "rk610_tv.h"
+#include "../../rk29_fb.h"
+
+#define DRV_NAME "rk610_tvout"
+#define RK610_I2C_RATE 100*1000
+
+volatile int rk610_tv_output_status = RK610_TVOUT_DEAULT;
+static struct i2c_client *rk610_tv_i2c_client = NULL;
+
+int rk610_tv_wirte_reg(u8 reg, u8 data)
+{
+ int ret;
+ if(rk610_tv_i2c_client == NULL)
+ return -1;
+ ret = i2c_master_reg8_send(rk610_tv_i2c_client, reg, &data, 1, RK610_I2C_RATE);
+ if (ret > 0)
+ ret = 0;
+ return ret;
+}
+
+int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode)
+{
+ struct rk29fb_screen *screen;
+
+ if(modedb == NULL)
+ return -1;
+ screen = kzalloc(sizeof(struct rk29fb_screen), GFP_KERNEL);
+ if(screen == NULL)
+ return -1;
+
+ memset(screen, 0, sizeof(struct rk29fb_screen));
+ /* screen type & face */
+ screen->type = SCREEN_HDMI;
+ screen->mode = modedb->vmode;
+ screen->face = modedb->flag;
+ /* Screen size */
+ screen->x_res = modedb->xres;
+ screen->y_res = modedb->yres;
+
+ /* Timing */
+ screen->pixclock = modedb->pixclock;
+
+ screen->lcdc_aclk = 500000000;
+ screen->left_margin = modedb->left_margin;
+ screen->right_margin = modedb->right_margin;
+ screen->hsync_len = modedb->hsync_len;
+ screen->upper_margin = modedb->upper_margin;
+ screen->lower_margin = modedb->lower_margin;
+ screen->vsync_len = modedb->vsync_len;
+
+ /* Pin polarity */
+ if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
+ screen->pin_hsync = 1;
+ else
+ screen->pin_hsync = 0;
+ if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
+ screen->pin_vsync = 1;
+ else
+ screen->pin_vsync = 0;
+ screen->pin_den = 0;
+ screen->pin_dclk = 0;
+
+ /* Swap rule */
+ screen->swap_rb = 0;
+ screen->swap_rg = 0;
+ screen->swap_gb = 0;
+ screen->swap_delta = 0;
+ screen->swap_dumy = 0;
+
+ /* Operation function*/
+ screen->init = NULL;
+ screen->standby = NULL;
+
+ switch(tv_mode)
+ {
+#ifdef CONFIG_RK610_TVOUT_CVBS
+ case TVOUT_CVBS_NTSC:
+ case TVOUT_CVBS_PAL:
+ screen->init = rk610_tv_cvbs_init;;
+ break;
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+ case TVOUT_YPbPr_720x480p_60:
+ case TVOUT_YPbPr_720x576p_50:
+ case TVOUT_YPbPr_1280x720p_50:
+ case TVOUT_YPbPr_1280x720p_60:
+ //case TVOUT_YPbPr_1920x1080i_50:
+ case TVOUT_YPbPr_1920x1080i_60:
+ case TVOUT_YPbPr_1920x1080p_50:
+ case TVOUT_YPbPr_1920x1080p_60:
+ screen->init = rk610_tv_ypbpr_init;
+ break;
+#endif
+ default:{
+ kfree(screen);
+ return -1;
+ }
+ break;
+ }
+ rk610_tv_output_status = tv_mode;
+ FB_Switch_Screen(screen, 1);
+ kfree(screen);
+ return 0;
+}
+
+int rk610_tv_standby(int type)
+{
+ int ret;
+
+ switch(type)
+ {
+ #ifdef CONFIG_RK610_TVOUT_CVBS
+ case RK610_TVOUT_CVBS:
+ if(rk610_cvbs_monspecs.enable == 0)
+ return 0;
+ #ifdef CONFIG_RK610_TVOUT_YPbPr
+ if(rk610_ypbpr_monspecs.enable == 1)
+ return 0;
+ #endif
+ break;
+ #endif
+ #ifdef CONFIG_RK610_TVOUT_YPbPr
+ case RK610_TVOUT_YPBPR:
+ if(rk610_ypbpr_monspecs.enable == 0)
+ return 0;
+ #ifdef CONFIG_RK610_TVOUT_CVBS
+ if(rk610_cvbs_monspecs.enable == 1)
+ return 0;
+ #endif
+ break;
+ #endif
+ default:
+ break;
+ }
+
+ ret = rk610_tv_wirte_reg(TVE_POWERCR, 0);
+ if(ret < 0){
+ printk("[%s] rk610_tv_wirte_reg err!\n", __FUNCTION__);
+ return ret;
+ }
+
+ ret = rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, 0);
+ if(ret < 0){
+ printk("[%s] rk610_control_send_byte err!\n", __FUNCTION__);
+ return ret;
+ }
+ return 0;
+}
+
+static int rk610_tv_probe(struct i2c_client *client,const struct i2c_device_id *id)
+{
+ int rc = 0;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ rc = -ENODEV;
+ goto failout;
+ }
+ rk610_tv_i2c_client = client;
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+ rk610_register_display_ypbpr(&client->dev);
+ if(rk610_tv_output_status > TVOUT_CVBS_PAL)
+ rk_display_device_enable(rk610_ypbpr_monspecs.ddev);
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_CVBS
+ rk610_register_display_cvbs(&client->dev);
+ if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
+ rk_display_device_enable(rk610_cvbs_monspecs.ddev);
+#endif
+
+ printk(KERN_INFO "rk610_tv ver 1.0 probe ok\n");
+ return 0;
+failout:
+ kfree(client);
+ return rc;
+}
+
+static int rk610_tv_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+
+static const struct i2c_device_id rk610_tv_id[] = {
+ { DRV_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rk610_tv_id);
+
+static struct i2c_driver rk610_tv_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ },
+ .id_table = rk610_tv_id,
+ .probe = rk610_tv_probe,
+ .remove = rk610_tv_remove,
+};
+
+static int __init rk610_tv_init(void)
+{
+ int ret = 0;
+ ret = i2c_add_driver(&rk610_tv_driver);
+ if(ret < 0){
+ printk("i2c_add_driver err, ret = %d\n", ret);
+ }
+ return ret;
+}
+
+static void __exit rk610_tv_exit(void)
+{
+ i2c_del_driver(&rk610_tv_driver);
+}
+
+module_init(rk610_tv_init);
+//late_initcall(rk610_tv_init);
+module_exit(rk610_tv_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("ROCKCHIP RK610 TV Output");
+MODULE_LICENSE("GPL");
+
+
--- /dev/null
+#ifndef _RK610_TV_H
+#define _RK610_TV_H
+#include <linux/display-sys.h>
+#include <linux/fb.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/rk29_iomap.h>
+#include "../screen/screen.h"
+#include "../../rk29_fb.h"
+#include <linux/mfd/rk610_core.h>
+
+#define TVE_VFCR 0x00
+ #define TVE_VFCR_ENABLE_SUBCARRIER_RESET 0 << 6
+ #define TVE_VFCR_DISABLE_SUBCARRIER_RESET 1 << 6
+ #define TVE_VFCR_VIN_RANGE_16_235 0 << 3
+ #define TVE_VFCR_VIN_RANGE_1_254 1 << 3
+ #define TVE_VFCR_BLACK_7_5_IRE 0 << 2
+ #define TVE_VFCR_BLACK_0_IRE 1 << 2
+ #define TVE_VFCR_NTSC 0
+ #define TVE_VFCR_PAL_M 1
+ #define TVE_VFCR_PAL_B_N 2
+ #define TVE_VFCR_PAL_NC 3
+
+#define TVE_VINCR 0x01
+ #define TVE_VINCR_PIX_DATA_DELAY(n) (n << 5)
+ #define TVE_VINCR_H_SYNC_POLARITY_NEGTIVE 0 << 4
+ #define TVE_VINCR_H_SYNC_POLARITY_POSITIVE 1 << 4
+ #define TVE_VINCR_V_SYNC_POLARITY_NEGTIVE 0 << 3
+ #define TVE_VINCR_V_SYNC_POLARITY_POSITIVE 1 << 3
+enum {
+ INPUT_FORMAT_BT601_SLAVE = 0,
+ INPUT_FORMAT_BT656,
+ INPUT_FORMAT_BT601_MASTER,
+ INPUT_FORMAT_INTERNAL_COLLOR_BAR
+};
+ #define TVE_VINCR_INPUT_FORMAT(n) (n << 1)
+ #define TVE_VINCR_VSYNC_FUNCTION_VSYNC 0
+ #define TVE_VINCR_VSYNC_FUNCTION_FIELD 1
+
+#define TVE_VOUTCR 0x02
+ #define TVE_VOUTCR_OUTPUT_CVBS 0 << 6
+ #define TVE_VOUTCR_OUTPUT_YPBPR 1 << 6
+ #define TVE_VOUTCR_OUTPUT_ENABLE_BLUE 1 << 5
+ #define TVE_VOUTCR_OUTPUT_ENABLE_BLACK 1 << 4
+ #define TVE_VOUTCR_DISABLE_CVBS_COLOR 1 << 3
+ #define TVE_VOUTCR_CVBS_Y2C_DELAY(n) (n << 0)
+
+#define TVE_POWERCR 0x03
+ #define TVE_PIX_CLK_INVERSE_ENABLE 1 << 4
+ #define TVE_DAC_CLK_INVERSE_DISABLE 1 << 3
+ #define TVE_DAC_Y_ENABLE 1 << 2
+ #define TVE_DAC_U_ENABLE 1 << 1
+ #define TVE_DAC_V_ENABLE 1 << 0
+
+#define TVE_HDTVCR 0x05
+ #define TVE_RESET 1 << 7
+ #define TVE_FILTER(n) (n << 5)
+ #define TVE_COLOR_CONVERT_REC601 0 << 4
+ #define TVE_COLOR_CONVERT_REC709 1 << 4
+ #define TVE_INPUT_DATA_RGB 0 << 3
+ #define TVE_INPUT_DATA_YUV 1 << 3
+ #define TVE_OUTPUT_50HZ 0 << 2
+ #define TVE_OUTPUT_60HZ 1 << 2
+ #define TVE_OUTPUT_MODE_PAL_NTSC 0
+ #define TVE_OUTPUT_MODE_576P 1
+ #define TVE_OUTPUT_MODE_480P 2
+ #define TVE_OUTPUT_MODE_720P 3
+
+#define TVE_YADJCR 0x06
+ #define TVE_OUTPUT_MODE_1080P 1 << 6
+ #define TVE_OUTPUT_MODE_1080I 1 << 5
+ #define TVE_Y_ADJ_VALUE(n) n
+#define TVE_YCBADJCR 0x07
+#define TVE_YCRADJCR 0x08
+
+/******************* TVOUT OUTPUT TYPE **********************/
+struct rk610_monspecs {
+ struct rk_display_device *ddev;
+ unsigned int enable;
+ struct fb_videomode *mode;
+ struct list_head modelist;
+ unsigned int mode_set;
+};
+
+enum {
+ TVOUT_CVBS_NTSC = 1,
+ TVOUT_CVBS_PAL,
+ TVOUT_YPbPr_720x480p_60,
+ TVOUT_YPbPr_720x576p_50,
+ TVOUT_YPbPr_1280x720p_50,
+ TVOUT_YPbPr_1280x720p_60,
+ //TVOUT_YPbPr_1920x1080i_50,
+ TVOUT_YPbPr_1920x1080i_60,
+ TVOUT_YPbPr_1920x1080p_50,
+ TVOUT_YPbPr_1920x1080p_60
+};
+
+#define RK610_TVOUT_DEAULT TVOUT_CVBS_NTSC
+
+enum {
+ RK610_TVOUT_CVBS = 0,
+ RK610_TVOUT_YC,
+ RK610_TVOUT_YPBPR,
+};
+
+extern volatile int rk610_tv_output_status;
+extern struct rk_display_ops rk610_display_ops;
+
+extern int FB_Switch_Screen( struct rk29fb_screen *screen, u32 enable );
+
+extern int rk610_tv_wirte_reg(u8 reg, u8 data);
+extern int rk610_tv_standby(int type);
+extern int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode);
+extern int rk610_register_display(struct device *parent);
+
+#ifdef CONFIG_RK610_TVOUT_YPbPr
+extern int rk610_tv_ypbpr_init(void);
+extern int rk610_register_display_ypbpr(struct device *parent);
+extern struct rk610_monspecs rk610_ypbpr_monspecs;
+#endif
+
+#ifdef CONFIG_RK610_TVOUT_CVBS
+extern int rk610_tv_cvbs_init(void);
+extern int rk610_register_display_cvbs(struct device *parent);
+extern struct rk610_monspecs rk610_cvbs_monspecs;
+#endif
+
+#endif
+
--- /dev/null
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/display-sys.h>
+#include "rk610_tv.h"
+
+
+#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
+#define RK610_LED_CVBS_PIN RK29_PIN4_PD3
+#else
+#define RK610_LED_CVBS_PIN INVALID_GPIO
+#endif
+
+#ifdef USE_RGB2CCIR
+static const struct fb_videomode rk610_cvbs_mode [] = {
+ //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag
+ { "NTSC", 60, 720, 480, 27000000, 116, 16, 25, 14, 6, 6, 0, 1, OUT_P888 },
+ { "PAL", 50, 720, 576, 27000000, 126, 12, 37, 6, 6, 6, 0, 1, OUT_P888 },
+};
+#else
+static const struct fb_videomode rk610_cvbs_mode [] = {
+ //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag
+ { "NTSC", 60, 720, 480, 27000000, 116, 16, 16, 3, 6, 3, 0, 1, OUT_CCIR656 },
+ { "PAL", 50, 720, 576, 27000000, 126, 12, 19, 2, 6, 3, 0, 1, OUT_CCIR656 },
+};
+#endif
+
+struct rk610_monspecs rk610_cvbs_monspecs;
+
+
+int rk610_tv_cvbs_init(void)
+{
+ unsigned char TVE_Regs[9];
+ unsigned char TVE_CON_Reg;
+ int ret, i;
+
+ rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
+
+ memset(TVE_Regs, 0, 9);
+ TVE_CON_Reg = TVE_CONTROL_CVBS_3_CHANNEL_ENALBE;
+ TVE_Regs[TVE_VINCR] = TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
+ TVE_Regs[TVE_POWERCR] = TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
+ TVE_Regs[TVE_VOUTCR] = TVE_VOUTCR_OUTPUT_CVBS;
+ TVE_Regs[TVE_YADJCR] = 0x17;
+ TVE_Regs[TVE_YCBADJCR] = 0x10;
+ TVE_Regs[TVE_YCRADJCR] = 0x10;
+
+ switch(rk610_tv_output_status) {
+ case TVOUT_CVBS_NTSC:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_7_5_IRE | TVE_VFCR_NTSC;
+ #ifdef USE_RGB2CCIR
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
+ TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_NTSC | RGB2CCIR_ENABLE;
+ #else
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
+ #endif
+ break;
+ case TVOUT_CVBS_PAL:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_B_N;
+ #ifdef USE_RGB2CCIR
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
+ TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_PAL | RGB2CCIR_ENABLE;
+ #else
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
+ #endif
+ break;
+ default:
+ return -1;
+ }
+
+ for(i = 0; i < sizeof(TVE_Regs); i++){
+// printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
+ ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
+ if(ret < 0){
+ printk(KERN_ERR "rk610_tv_wirte_reg %d err!\n", i);
+ return ret;
+ }
+ }
+// printk(KERN_ERR "TVE_CON_Reg = 0x%02x\n", TVE_CON_Reg);
+ rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
+ #ifdef USE_RGB2CCIR
+ rk610_control_send_byte(RK610_CONTROL_REG_CCIR_RESET, 0x01);
+ #endif
+ return 0;
+}
+
+static int rk610_cvbs_set_enable(struct rk_display_device *device, int enable)
+{
+ if(rk610_cvbs_monspecs.enable != enable || rk610_cvbs_monspecs.mode_set != rk610_tv_output_status)
+ {
+ if(enable == 0)
+ {
+ rk610_tv_standby(RK610_TVOUT_CVBS);
+ rk610_cvbs_monspecs.enable = 0;
+ if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+ gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
+ }
+ else if(enable == 1)
+ {
+ rk610_switch_fb(rk610_cvbs_monspecs.mode, rk610_cvbs_monspecs.mode_set);
+ rk610_cvbs_monspecs.enable = 1;
+ if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+ gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_LOW);
+ }
+ }
+ return 0;
+}
+
+static int rk610_cvbs_get_enable(struct rk_display_device *device)
+{
+ return rk610_cvbs_monspecs.enable;
+}
+
+static int rk610_cvbs_get_status(struct rk_display_device *device)
+{
+ if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
+ return 1;
+ else
+ return 0;
+}
+
+static int rk610_cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+ *modelist = &(rk610_cvbs_monspecs.modelist);
+ return 0;
+}
+
+static int rk610_cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
+ {
+ if(fb_mode_is_equal(&rk610_cvbs_mode[i], mode))
+ {
+ if( ((i + 1) != rk610_tv_output_status) )
+ {
+ rk610_cvbs_monspecs.mode_set = i + 1;
+ rk610_cvbs_monspecs.mode = (struct fb_videomode *)&rk610_cvbs_mode[i];
+ }
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int rk610_cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+ *mode = *(rk610_cvbs_monspecs.mode);
+ return 0;
+}
+
+static struct rk_display_ops rk610_cvbs_display_ops = {
+ .setenable = rk610_cvbs_set_enable,
+ .getenable = rk610_cvbs_get_enable,
+ .getstatus = rk610_cvbs_get_status,
+ .getmodelist = rk610_cvbs_get_modelist,
+ .setmode = rk610_cvbs_set_mode,
+ .getmode = rk610_cvbs_get_mode,
+};
+
+static int rk610_display_cvbs_probe(struct rk_display_device *device, void *devdata)
+{
+ device->owner = THIS_MODULE;
+ strcpy(device->type, "TV");
+ device->priority = DISPLAY_PRIORITY_TV;
+ device->priv_data = devdata;
+ device->ops = &rk610_cvbs_display_ops;
+ return 1;
+}
+
+static struct rk_display_driver display_rk610_cvbs = {
+ .probe = rk610_display_cvbs_probe,
+};
+
+int rk610_register_display_cvbs(struct device *parent)
+{
+ int i;
+
+ memset(&rk610_cvbs_monspecs, 0, sizeof(struct rk610_monspecs));
+ INIT_LIST_HEAD(&rk610_cvbs_monspecs.modelist);
+ for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
+ fb_add_videomode(&rk610_cvbs_mode[i], &rk610_cvbs_monspecs.modelist);
+ if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60) {
+ rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[rk610_tv_output_status - 1]);
+ rk610_cvbs_monspecs.mode_set = rk610_tv_output_status;
+ }
+ else {
+ rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[0]);
+ rk610_cvbs_monspecs.mode_set = TVOUT_CVBS_NTSC;
+ }
+ rk610_cvbs_monspecs.ddev = rk_display_device_register(&display_rk610_cvbs, parent, NULL);
+ if(RK610_LED_CVBS_PIN != INVALID_GPIO)
+ {
+ if(gpio_request(RK610_LED_CVBS_PIN, NULL) != 0)
+ {
+ gpio_free(RK610_LED_CVBS_PIN);
+ dev_err(rk610_cvbs_monspecs.ddev->dev, ">>>>>> RK610_LED_CVBS_PIN gpio_request err \n ");
+ return -1;
+ }
+ gpio_pull_updown(RK610_LED_CVBS_PIN,GPIOPullUp);
+ gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
+ }
+ return 0;
+}
--- /dev/null
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/display-sys.h>
+#include "rk610_tv.h"
+
+
+#ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
+#define RK610_LED_YPbPr_PIN RK29_PIN4_PD5
+#else
+#define RK610_LED_YPbPr_PIN INVALID_GPIO
+#endif
+#define E(fmt, arg...) printk("<3>!!!%s:%d: " fmt, __FILE__, __LINE__, ##arg)
+
+static const struct fb_videomode rk610_YPbPr_mode [] = {
+ //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag
+ { "YPbPr480p", 60, 720, 480, 27000000, 55, 19, 37, 5, 64, 5, 0, 0, OUT_P888 },
+ { "YPbPr576p", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, OUT_P888 },
+ { "YPbPr720p@50", 50, 1280, 720, 74250000, 600, 0, 20, 5, 100, 5, 0, 0, OUT_P888 },
+ { "YPbPr720p@60", 60, 1280, 720, 74250000, 270, 0, 20, 5, 100, 5, 0, 0, OUT_P888 },
+ //{ "YPbPr1080i@50", 50, 1920, 1080, 148500000, 620, 0, 15, 2, 100, 5, 0, 1, OUT_CCIR656 },
+ { "YPbPr1080i@60", 60, 1920, 1080, 148500000, 180, 0, 15, 2, 100, 5, 0, 1, OUT_CCIR656 },
+ { "YPbPr1080p@50", 50, 1920, 1080, 148500000, 620, 0, 36, 4, 100, 5, 0, 0, OUT_P888 },
+ { "YPbPr1080p@60", 60, 1920, 1080, 148500000, 180, 0, 36, 4, 100, 5, 0, 0, OUT_P888 },
+};
+
+struct rk610_monspecs rk610_ypbpr_monspecs;
+
+int rk610_tv_ypbpr_init(void)
+{
+ unsigned char TVE_Regs[9];
+ unsigned char TVE_CON_Reg;
+ int i, ret;
+
+ rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
+ memset(TVE_Regs, 0, 9);
+
+ TVE_CON_Reg = 0x00;
+
+ TVE_Regs[TVE_VINCR] = TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
+ TVE_Regs[TVE_POWERCR] = TVE_DAC_CLK_INVERSE_DISABLE | TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
+ TVE_Regs[TVE_VOUTCR] = TVE_VOUTCR_OUTPUT_YPBPR;
+ TVE_Regs[TVE_YADJCR] = 0x17;
+ TVE_Regs[TVE_YCBADJCR] = 0x10;
+ TVE_Regs[TVE_YCRADJCR] = 0x10;
+
+ switch(rk610_tv_output_status)
+ {
+ case TVOUT_YPbPr_720x480p_60:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_480P;
+ break;
+ case TVOUT_YPbPr_720x576p_50:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_576P;
+ break;
+ case TVOUT_YPbPr_1280x720p_50:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ | TVE_OUTPUT_MODE_720P;
+ break;
+ case TVOUT_YPbPr_1280x720p_60:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ | TVE_OUTPUT_MODE_720P;
+ break;
+ /*case TVOUT_YPbPr_1920x1080i_50:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_50HZ;
+ TVE_Regs[TVE_YADJCR] |= TVE_OUTPUT_MODE_1080I;
+ break;
+ */
+ case TVOUT_YPbPr_1920x1080i_60:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_60HZ;
+ TVE_Regs[TVE_YADJCR] |= TVE_OUTPUT_MODE_1080I;
+ break;
+ case TVOUT_YPbPr_1920x1080p_50:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_50HZ;
+ TVE_Regs[TVE_YADJCR] |= TVE_OUTPUT_MODE_1080P;
+ break;
+ case TVOUT_YPbPr_1920x1080p_60:
+ TVE_Regs[TVE_VFCR] = TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_NC;
+ TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
+ TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC709 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_60HZ;
+ TVE_Regs[TVE_YADJCR] |= TVE_OUTPUT_MODE_1080P;
+ break;
+ default:
+ return -1;
+ }
+
+ rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
+
+ for(i = 0; i < sizeof(TVE_Regs); i++){
+// printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
+ ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
+ if(ret < 0){
+ E("rk610_tv_wirte_reg %d err!\n", i);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int rk610_ypbpr_set_enable(struct rk_display_device *device, int enable)
+{
+ if(rk610_ypbpr_monspecs.enable != enable || rk610_ypbpr_monspecs.mode_set != rk610_tv_output_status)
+ {
+ if(enable == 0)
+ {
+ rk610_tv_standby(RK610_TVOUT_YPBPR);
+ rk610_ypbpr_monspecs.enable = 0;
+ if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+ gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
+ }
+ else if(enable == 1)
+ {
+ rk610_switch_fb(rk610_ypbpr_monspecs.mode, rk610_ypbpr_monspecs.mode_set);
+ rk610_ypbpr_monspecs.enable = 1;
+ if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+ gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_LOW);
+ }
+ }
+ return 0;
+}
+
+static int rk610_ypbpr_get_enable(struct rk_display_device *device)
+{
+ return rk610_ypbpr_monspecs.enable;
+}
+
+static int rk610_ypbpr_get_status(struct rk_display_device *device)
+{
+ if(rk610_tv_output_status > TVOUT_CVBS_PAL)
+ return 1;
+ else
+ return 0;
+}
+
+static int rk610_ypbpr_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+ *modelist = &(rk610_ypbpr_monspecs.modelist);
+ return 0;
+}
+
+static int rk610_ypbpr_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
+ {
+ if(fb_mode_is_equal(&rk610_YPbPr_mode[i], mode))
+ {
+ if( (i + 3) != rk610_tv_output_status )
+ {
+ rk610_ypbpr_monspecs.mode_set = i + 3;
+ rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&rk610_YPbPr_mode[i];
+ }
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int rk610_ypbpr_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+ *mode = *(rk610_ypbpr_monspecs.mode);
+ return 0;
+}
+
+static struct rk_display_ops rk610_ypbpr_display_ops = {
+ .setenable = rk610_ypbpr_set_enable,
+ .getenable = rk610_ypbpr_get_enable,
+ .getstatus = rk610_ypbpr_get_status,
+ .getmodelist = rk610_ypbpr_get_modelist,
+ .setmode = rk610_ypbpr_set_mode,
+ .getmode = rk610_ypbpr_get_mode,
+};
+
+static int rk610_display_YPbPr_probe(struct rk_display_device *device, void *devdata)
+{
+ device->owner = THIS_MODULE;
+ strcpy(device->type, "YPbPr");
+ device->priority = DISPLAY_PRIORITY_YPbPr;
+ device->priv_data = devdata;
+ device->ops = &rk610_ypbpr_display_ops;
+ return 1;
+}
+
+static struct rk_display_driver display_rk610_YPbPr = {
+ .probe = rk610_display_YPbPr_probe,
+};
+
+int rk610_register_display_ypbpr(struct device *parent)
+{
+ int i;
+
+ memset(&rk610_ypbpr_monspecs, 0, sizeof(struct rk610_monspecs));
+ INIT_LIST_HEAD(&rk610_ypbpr_monspecs.modelist);
+ for(i = 0; i < ARRAY_SIZE(rk610_YPbPr_mode); i++)
+ fb_add_videomode(&rk610_YPbPr_mode[i], &rk610_ypbpr_monspecs.modelist);
+ if(rk610_tv_output_status > TVOUT_CVBS_PAL) {
+ rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[rk610_tv_output_status - 3]);
+ rk610_ypbpr_monspecs.mode_set = rk610_tv_output_status;
+ }
+ else {
+ rk610_ypbpr_monspecs.mode = (struct fb_videomode *)&(rk610_YPbPr_mode[3]);
+ rk610_ypbpr_monspecs.mode_set = TVOUT_YPbPr_1280x720p_60;
+ }
+ rk610_ypbpr_monspecs.ddev = rk_display_device_register(&display_rk610_YPbPr, parent, NULL);
+ if(RK610_LED_YPbPr_PIN != INVALID_GPIO)
+ {
+ if(gpio_request(RK610_LED_YPbPr_PIN, NULL) != 0)
+ {
+ gpio_free(RK610_LED_YPbPr_PIN);
+ dev_err(rk610_ypbpr_monspecs.ddev->dev, ">>>>>> RK610_LED_YPbPr_PIN gpio_request err \n ");
+ return -1;
+ }
+ gpio_pull_updown(RK610_LED_YPbPr_PIN,GPIOPullUp);
+ gpio_direction_output(RK610_LED_YPbPr_PIN, GPIO_HIGH);
+ }
+ return 0;
+}
bool "enable hdmi save data"
help
Enable hdmi save data in rtc register
+
+config HDMI_DUAL_DISP
+ bool "dual display support"
+ depends on RK610_HDMI
+ help
+ Support output lcd and hdmi at the same time.
-#config HDMI_DUAL_DISP
-# bool "hdmi support dual display"
-# help
-# nothing
#config HDMI_DEBUG
# bool "hdmi debug"
endif
bool "anx7150"
config ANX9030
bool "anx9030"
+config RK610_HDMI
+ bool "RK610(Jetta) hdmi support"
+ depends on MFD_RK610
+ help
+ Support Jetta(RK610) to hdmi.
endchoice
-obj-$(CONFIG_ANX7150) += anx7150_hw.o anx7150.o
-
+obj-$(CONFIG_ANX7150) += anx7150/anx7150.o anx7150/anx7150_hw.o
+obj-$(CONFIG_RK610_HDMI) += rk610/rk610_hdmi.o rk610/rk610_hdmi_hw.o
+++ /dev/null
-#include <linux/kernel.h>\r
-#include <linux/delay.h>\r
-#include <linux/module.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/hdmi.h>\r
-#include <linux/i2c.h>\r
-#include <linux/interrupt.h>\r
-#include <mach/gpio.h>\r
-#include <mach/iomux.h>\r
-#include <mach/board.h>\r
-\r
-\r
-\r
-#include "anx7150.h"\r
-#include "anx7150_hw.h"\r
-int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
-{\r
- client->addr = ANX7150_I2C_ADDR0;\r
- return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
-}\r
-int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
-{\r
- client->addr = ANX7150_I2C_ADDR0;\r
- return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
-}\r
-int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val)\r
-{\r
- client->addr = ANX7150_I2C_ADDR1;\r
- return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
-}\r
-int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val)\r
-{\r
- client->addr = ANX7150_I2C_ADDR1;\r
- return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
-}\r
-\r
-static int anx7150_precent(struct hdmi *hdmi)\r
-{\r
- struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
-\r
- return gpio_get_value(anx->client->irq)?0:1;\r
-}\r
-static int anx7150_param_chg(struct anx7150_pdata *anx)\r
-{\r
- int resolution_real;\r
-\r
- hdmi_switch_fb(anx->hdmi, HDMI_ENABLE);\r
- resolution_real = ANX7150_Get_Optimal_resolution(anx->hdmi->resolution);\r
- HDMI_Set_Video_Format(resolution_real);\r
- HDMI_Set_Audio_Fs(anx->hdmi->audio_fs);\r
- ANX7150_API_HDCP_ONorOFF(anx->hdmi->hdcp_on);\r
- ANX7150_API_System_Config();\r
- ANX7150_Config_Video(anx->client);\r
-\r
- ANX7150_Config_Audio(anx->client);\r
- ANX7150_Config_Packet(anx->client);\r
- ANX7150_HDCP_Process(anx->client, anx->hdmi->display_on);\r
- ANX7150_PLAYBACK_Process();\r
-\r
- return 0;\r
-}\r
-\r
-static int anx7150_insert(struct hdmi *hdmi)\r
-{\r
- int tmo = 10;\r
- struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
-\r
- if(anx->init == 1)\r
- return -1;\r
-\r
- anx7150_plug(anx->client);\r
- hdmi_dbg(&anx->client->dev, "parse edid\n");\r
- if(ANX7150_Parse_EDID(anx->client,&anx->dev) < 0)\r
- {\r
- dev_info(hdmi->dev, "parse EDID error\n");\r
- anx7150_unplug(anx->client);\r
- return -1;\r
- }\r
- \r
- while(--tmo && ANX7150_GET_SENSE_STATE(anx->client) != 1)\r
- mdelay(10);\r
- if(tmo <= 0)\r
- {\r
- anx7150_unplug(anx->client);\r
- dev_dbg(hdmi->dev, "get sense_state error\n");\r
- return -1;\r
- }\r
- hdmi_set_spk(HDMI_DISABLE);\r
- hdmi_set_backlight(HDMI_DISABLE);\r
- hdmi->scale = hdmi->scale_set;\r
- anx7150_param_chg(anx);\r
- return 0;\r
-}\r
-static int anx7150_remove(struct hdmi *hdmi)\r
-{\r
- struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
-\r
- if(anx->init == 1)\r
- return -1;\r
-\r
- anx7150_unplug(anx->client);\r
- hdmi->scale = 100;\r
- hdmi_set_spk(HDMI_ENABLE);\r
- hdmi_switch_fb(hdmi, HDMI_DISABLE);\r
- hdmi_set_backlight(HDMI_ENABLE);\r
-\r
- return 0;\r
-}\r
-\r
-static int anx7150_set_param(struct hdmi *hdmi)\r
-{\r
- struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
- if(anx->init == 1)\r
- return 0;\r
-\r
- anx7150_param_chg(anx);\r
- return 0;\r
-}\r
-\r
-static int anx7150_init(struct hdmi *hdmi)\r
-{\r
- struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
-#ifdef CONFIG_HDMI_SAVE_DATA\r
- int hdmi_data = hdmi_get_data();\r
- if(hdmi_data<0){\r
- hdmi_set_data((hdmi->resolution&0x7)|((hdmi->scale&0x1f)<<3));\r
- }\r
- else{\r
- hdmi->resolution = hdmi_data&0x7;\r
- hdmi->scale_set= ((hdmi_data>>3)&0x1f) + MIN_SCALE;\r
- hdmi->scale = hdmi->scale_set;\r
- }\r
-#endif\r
- anx->init = 0;\r
- hdmi_changed(hdmi,1);\r
-\r
- return 0;\r
-}\r
-static void anx7150_init_work_func(struct work_struct *work)\r
-{\r
- struct anx7150_pdata *anx = container_of(work, struct anx7150_pdata, work.work);\r
-\r
- if(anx!=NULL)\r
- anx7150_init(anx->hdmi);\r
- else\r
- printk("anx7150_init_work_func err\n");\r
-}\r
-static struct hdmi_ops anx7150_ops = {\r
- .set_param = anx7150_set_param,\r
- .hdmi_precent = anx7150_precent,\r
- .insert = anx7150_insert,\r
- .remove = anx7150_remove,\r
- .init = anx7150_init,\r
-};\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-static void anx7150_early_suspend(struct early_suspend *h)\r
-{\r
- struct anx7150_pdata *anx = container_of(h,\r
- struct anx7150_pdata,\r
- early_suspend);\r
- dev_info(&anx->client->dev, "anx7150 enter early suspend\n");\r
- hdmi_suspend(anx->hdmi);\r
- return;\r
-}\r
-\r
-static void anx7150_early_resume(struct early_suspend *h)\r
-{\r
- struct anx7150_pdata *anx = container_of(h,\r
- struct anx7150_pdata,\r
- early_suspend);\r
- dev_info(&anx->client->dev, "anx7150 exit early suspend\n");\r
- hdmi_resume(anx->hdmi);\r
- return;\r
-}\r
-#endif\r
-\r
-static int anx7150_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)\r
-{\r
- int ret = 0;\r
- struct hdmi *hdmi = NULL;\r
- struct anx7150_pdata *anx = NULL;\r
-\r
- struct hdmi_platform_data *pdata = client->dev.platform_data;\r
-\r
- if(pdata && pdata->io_init)\r
- pdata->io_init();\r
-\r
- hdmi = hdmi_register(sizeof(struct anx7150_pdata), &client->dev);\r
- if (!hdmi)\r
- {\r
- dev_err(&client->dev, "fail to register hdmi\n");\r
- return -ENOMEM;\r
- }\r
- hdmi->ops = &anx7150_ops;\r
- hdmi->display_on = HDMI_DEFAULT_MODE;\r
- hdmi->hdcp_on = HDMI_DISABLE;\r
- hdmi->audio_fs = HDMI_I2S_DEFAULT_Fs;\r
- hdmi->resolution = HDMI_DEFAULT_RESOLUTION;\r
- hdmi->dual_disp = DUAL_DISP_CAP;\r
- hdmi->mode = DISP_ON_LCD;\r
- hdmi->scale = 100;\r
- hdmi->scale_set = 100;\r
- \r
- anx = hdmi_priv(hdmi);\r
- anx->init = 1;\r
- anx->hdmi = hdmi;\r
- i2c_set_clientdata(client, anx);\r
- anx->client = client;\r
-\r
- if((ret = gpio_request(client->irq, "hdmi gpio")) < 0)\r
- {\r
- dev_err(&client->dev, "fail to request gpio %d\n", client->irq);\r
- goto err_hdmi_unregister;\r
- }\r
- //gpio_pull_updown(client->irq,0);\r
- gpio_direction_input(client->irq);\r
-\r
- if(anx7150_detect_device(anx) < 0)\r
- {\r
- dev_err(&client->dev, "anx7150 is not exist\n");\r
- ret = -EIO;\r
- goto err_gpio_free;\r
- }\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- anx->early_suspend.suspend = anx7150_early_suspend;\r
- anx->early_suspend.resume = anx7150_early_resume;\r
- anx->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;\r
- register_early_suspend(&anx->early_suspend);\r
-#endif\r
- anx7150_unplug(anx->client);\r
- INIT_DELAYED_WORK(&anx->work,anx7150_init_work_func);\r
- schedule_delayed_work(&anx->work, msecs_to_jiffies(2000));\r
- dev_info(&client->dev, "anx7150 i2c probe ok\n");\r
- return 0;\r
-err_gpio_free:\r
- gpio_free(client->irq);\r
-err_hdmi_unregister:\r
- hdmi_unregister(hdmi);\r
- anx = NULL;\r
- return ret;\r
-}\r
-\r
-static int __devexit anx7150_i2c_remove(struct i2c_client *client)\r
-{\r
- struct anx7150_pdata *anx = (struct anx7150_pdata *)i2c_get_clientdata(client);\r
- struct hdmi *hdmi = anx->hdmi;\r
-\r
- gpio_free(client->irq);\r
- hdmi_unregister(hdmi);\r
- anx = NULL;\r
- return 0;\r
-}\r
-static const struct i2c_device_id anx7150_id[] = {\r
- { "anx7150", 0 },\r
- { }\r
-};\r
-\r
-static struct i2c_driver anx7150_i2c_driver = {\r
- .driver = {\r
- .name = "anx7150",\r
- .owner = THIS_MODULE,\r
- },\r
- .probe = &anx7150_i2c_probe,\r
- .remove = &anx7150_i2c_remove,\r
- .id_table = anx7150_id,\r
-};\r
-\r
-\r
-static int __init anx7150_module_init(void)\r
-{\r
- return i2c_add_driver(&anx7150_i2c_driver);\r
-}\r
-\r
-static void __exit anx7150_module_exit(void)\r
-{\r
- i2c_del_driver(&anx7150_i2c_driver);\r
-}\r
-\r
-module_init(anx7150_module_init);\r
-//fs_initcall(anx7150_module_init);\r
-module_exit(anx7150_module_exit);\r
-\r
-\r
+++ /dev/null
-#ifndef _ANX7150_H\r
-#define _ANX7150_H\r
-\r
-#include <linux/hdmi.h>\r
-#include <linux/earlysuspend.h>\r
-\r
-\r
-#define ANX7150_I2C_ADDR0 0X39\r
-#define ANX7150_I2C_ADDR1 0X3d\r
-\r
-#define ANX7150_SCL_RATE 100 * 1000\r
-\r
-\r
-/* HDMI auto switch */\r
-#define HDMI_AUTO_SWITCH HDMI_ENABLE\r
-\r
-/* HDMI reciver status */\r
-#define HDMI_RECIVER_INACTIVE 0\r
-#define HDMI_RECIVER_ACTIVE 1\r
-\r
-/* ANX7150 reciver HPD Status */\r
-#define HDMI_RECIVER_UNPLUG 0\r
-#define HDMI_RECIVER_PLUG 1\r
-\r
-#define LCD 0\r
-#define HDMI 1\r
-\r
-#define RK29_OUTPUT_STATUS_LCD LCD\r
-#define RK29_OUTPUT_STATUS_HDMI HDMI\r
-\r
-/* HDMI HDCP ENABLE */\r
-#define ANX7150_HDCP_EN HDMI_DISABLE\r
-\r
-/* ANX7150 state machine */\r
-enum{\r
- HDMI_INITIAL = 1,\r
- WAIT_HOTPLUG,\r
- READ_PARSE_EDID,\r
- WAIT_RX_SENSE,\r
- WAIT_HDMI_ENABLE,\r
- SYSTEM_CONFIG,\r
- CONFIG_VIDEO,\r
- CONFIG_AUDIO,\r
- CONFIG_PACKETS,\r
- HDCP_AUTHENTICATION,\r
- PLAY_BACK,\r
- RESET_LINK,\r
- UNKNOWN,\r
-};\r
-\r
-\r
-struct anx7150_dev_s{\r
- struct i2c_driver *i2c_driver;\r
- struct fasync_struct *async_queue;\r
- struct workqueue_struct *workqueue;\r
- struct delayed_work delay_work;\r
- struct miscdevice *mdev;\r
- void (*notifier_callback)(struct anx7150_dev_s *);\r
- int anx7150_detect;\r
- int resolution_set;\r
- int resolution_real;\r
- int i2s_Fs;\r
- int hdmi_enable;\r
- int hdmi_auto_switch;\r
- int reciver_status;\r
- int HPD_change_cnt;\r
- int HPD_status;\r
- int rk29_output_status;\r
- int hdcp_enable;\r
- int parameter_config;\r
- int rate;\r
- int fb_switch_state;\r
-\r
- struct hdmi *hdmi;\r
-};\r
-\r
-struct anx7150_pdata {\r
- int irq;\r
- int gpio;\r
- int init;\r
- int is_early_suspend;\r
- int is_changed;\r
- struct delayed_work work;\r
- struct hdmi *hdmi;\r
- struct i2c_client *client;\r
- struct anx7150_dev_s dev;\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- struct early_suspend early_suspend;
-#endif\r
-};\r
-\r
-\r
-\r
-int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val);\r
-int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val);\r
-int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val);\r
-int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val);\r
-\r
-#endif\r
--- /dev/null
+#include <linux/kernel.h>\r
+#include <linux/delay.h>\r
+#include <linux/module.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/hdmi.h>\r
+#include <linux/i2c.h>\r
+#include <linux/interrupt.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+\r
+\r
+\r
+#include "anx7150.h"\r
+#include "anx7150_hw.h"\r
+int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ client->addr = ANX7150_I2C_ADDR0;\r
+ return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
+}\r
+int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ client->addr = ANX7150_I2C_ADDR0;\r
+ return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
+}\r
+int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ client->addr = ANX7150_I2C_ADDR1;\r
+ return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
+}\r
+int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ client->addr = ANX7150_I2C_ADDR1;\r
+ return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;\r
+}\r
+\r
+static int anx7150_precent(struct hdmi *hdmi)\r
+{\r
+ struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
+\r
+ return gpio_get_value(anx->client->irq)?0:1;\r
+}\r
+static int anx7150_param_chg(struct anx7150_pdata *anx)\r
+{\r
+ int resolution_real;\r
+\r
+ hdmi_switch_fb(anx->hdmi, HDMI_ENABLE);\r
+ resolution_real = ANX7150_Get_Optimal_resolution(anx->hdmi->resolution);\r
+ HDMI_Set_Video_Format(resolution_real);\r
+ HDMI_Set_Audio_Fs(anx->hdmi->audio_fs);\r
+ ANX7150_API_HDCP_ONorOFF(anx->hdmi->hdcp_on);\r
+ ANX7150_API_System_Config();\r
+ ANX7150_Config_Video(anx->client);\r
+\r
+ ANX7150_Config_Audio(anx->client);\r
+ ANX7150_Config_Packet(anx->client);\r
+ ANX7150_HDCP_Process(anx->client, anx->hdmi->display_on);\r
+ ANX7150_PLAYBACK_Process();\r
+\r
+ return 0;\r
+}\r
+\r
+static int anx7150_insert(struct hdmi *hdmi)\r
+{\r
+ int tmo = 10;\r
+ struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
+\r
+ if(anx->init == 1)\r
+ return -1;\r
+\r
+ anx7150_plug(anx->client);\r
+ hdmi_dbg(&anx->client->dev, "parse edid\n");\r
+ if(ANX7150_Parse_EDID(anx->client,&anx->dev) < 0)\r
+ {\r
+ dev_info(hdmi->dev, "parse EDID error\n");\r
+ anx7150_unplug(anx->client);\r
+ return -1;\r
+ }\r
+ \r
+ while(--tmo && ANX7150_GET_SENSE_STATE(anx->client) != 1)\r
+ mdelay(10);\r
+ if(tmo <= 0)\r
+ {\r
+ anx7150_unplug(anx->client);\r
+ dev_dbg(hdmi->dev, "get sense_state error\n");\r
+ return -1;\r
+ }\r
+ hdmi_set_spk(HDMI_DISABLE);\r
+ hdmi_set_backlight(HDMI_DISABLE);\r
+ hdmi->scale = hdmi->scale_set;\r
+ anx7150_param_chg(anx);\r
+ return 0;\r
+}\r
+static int anx7150_remove(struct hdmi *hdmi)\r
+{\r
+ struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
+\r
+ if(anx->init == 1)\r
+ return -1;\r
+\r
+ anx7150_unplug(anx->client);\r
+ hdmi->scale = 100;\r
+ hdmi_set_spk(HDMI_ENABLE);\r
+ hdmi_switch_fb(hdmi, HDMI_DISABLE);\r
+ hdmi_set_backlight(HDMI_ENABLE);\r
+\r
+ return 0;\r
+}\r
+\r
+static int anx7150_set_param(struct hdmi *hdmi)\r
+{\r
+ struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
+ if(anx->init == 1)\r
+ return 0;\r
+\r
+ anx7150_param_chg(anx);\r
+ return 0;\r
+}\r
+\r
+static int anx7150_init(struct hdmi *hdmi)\r
+{\r
+ struct anx7150_pdata *anx = hdmi_priv(hdmi);\r
+#ifdef CONFIG_HDMI_SAVE_DATA\r
+ int hdmi_data = hdmi_get_data();\r
+ if(hdmi_data<0){\r
+ hdmi_set_data((hdmi->resolution&0x7)|((hdmi->scale&0x1f)<<3));\r
+ }\r
+ else{\r
+ hdmi->resolution = hdmi_data&0x7;\r
+ hdmi->scale_set= ((hdmi_data>>3)&0x1f) + MIN_SCALE;\r
+ hdmi->scale = hdmi->scale_set;\r
+ }\r
+#endif\r
+ anx->init = 0;\r
+ hdmi_changed(hdmi,1);\r
+\r
+ return 0;\r
+}\r
+static void anx7150_init_work_func(struct work_struct *work)\r
+{\r
+ struct anx7150_pdata *anx = container_of(work, struct anx7150_pdata, work.work);\r
+\r
+ if(anx!=NULL)\r
+ anx7150_init(anx->hdmi);\r
+ else\r
+ printk("anx7150_init_work_func err\n");\r
+}\r
+static struct hdmi_ops anx7150_ops = {\r
+ .set_param = anx7150_set_param,\r
+ .hdmi_precent = anx7150_precent,\r
+ .insert = anx7150_insert,\r
+ .remove = anx7150_remove,\r
+ .init = anx7150_init,\r
+};\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+static void anx7150_early_suspend(struct early_suspend *h)\r
+{\r
+ struct anx7150_pdata *anx = container_of(h,\r
+ struct anx7150_pdata,\r
+ early_suspend);\r
+ dev_info(&anx->client->dev, "anx7150 enter early suspend\n");\r
+ hdmi_suspend(anx->hdmi);\r
+ return;\r
+}\r
+\r
+static void anx7150_early_resume(struct early_suspend *h)\r
+{\r
+ struct anx7150_pdata *anx = container_of(h,\r
+ struct anx7150_pdata,\r
+ early_suspend);\r
+ dev_info(&anx->client->dev, "anx7150 exit early suspend\n");\r
+ hdmi_resume(anx->hdmi);\r
+ return;\r
+}\r
+#endif\r
+\r
+static int anx7150_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)\r
+{\r
+ int ret = 0;\r
+ struct hdmi *hdmi = NULL;\r
+ struct anx7150_pdata *anx = NULL;\r
+\r
+ struct hdmi_platform_data *pdata = client->dev.platform_data;\r
+\r
+ if(pdata && pdata->io_init)\r
+ pdata->io_init();\r
+\r
+ hdmi = hdmi_register(sizeof(struct anx7150_pdata), &client->dev);\r
+ if (!hdmi)\r
+ {\r
+ dev_err(&client->dev, "fail to register hdmi\n");\r
+ return -ENOMEM;\r
+ }\r
+ hdmi->ops = &anx7150_ops;\r
+ hdmi->display_on = HDMI_DEFAULT_MODE;\r
+ hdmi->hdcp_on = HDMI_DISABLE;\r
+ hdmi->audio_fs = HDMI_I2S_DEFAULT_Fs;\r
+ hdmi->resolution = HDMI_DEFAULT_RESOLUTION;\r
+ hdmi->dual_disp = DUAL_DISP_CAP;\r
+ hdmi->mode = DISP_ON_LCD;\r
+ hdmi->scale = 100;\r
+ hdmi->scale_set = 100;\r
+ \r
+ anx = hdmi_priv(hdmi);\r
+ anx->init = 1;\r
+ anx->hdmi = hdmi;\r
+ i2c_set_clientdata(client, anx);\r
+ anx->client = client;\r
+\r
+ if((ret = gpio_request(client->irq, "hdmi gpio")) < 0)\r
+ {\r
+ dev_err(&client->dev, "fail to request gpio %d\n", client->irq);\r
+ goto err_hdmi_unregister;\r
+ }\r
+ //gpio_pull_updown(client->irq,0);\r
+ gpio_direction_input(client->irq);\r
+\r
+ if(anx7150_detect_device(anx) < 0)\r
+ {\r
+ dev_err(&client->dev, "anx7150 is not exist\n");\r
+ ret = -EIO;\r
+ goto err_gpio_free;\r
+ }\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ anx->early_suspend.suspend = anx7150_early_suspend;\r
+ anx->early_suspend.resume = anx7150_early_resume;\r
+ anx->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;\r
+ register_early_suspend(&anx->early_suspend);\r
+#endif\r
+ anx7150_unplug(anx->client);\r
+ INIT_DELAYED_WORK(&anx->work,anx7150_init_work_func);\r
+ schedule_delayed_work(&anx->work, msecs_to_jiffies(2000));\r
+ dev_info(&client->dev, "anx7150 i2c probe ok\n");\r
+ return 0;\r
+err_gpio_free:\r
+ gpio_free(client->irq);\r
+err_hdmi_unregister:\r
+ hdmi_unregister(hdmi);\r
+ anx = NULL;\r
+ return ret;\r
+}\r
+\r
+static int __devexit anx7150_i2c_remove(struct i2c_client *client)\r
+{\r
+ struct anx7150_pdata *anx = (struct anx7150_pdata *)i2c_get_clientdata(client);\r
+ struct hdmi *hdmi = anx->hdmi;\r
+\r
+ gpio_free(client->irq);\r
+ hdmi_unregister(hdmi);\r
+ anx = NULL;\r
+ return 0;\r
+}\r
+static const struct i2c_device_id anx7150_id[] = {\r
+ { "anx7150", 0 },\r
+ { }\r
+};\r
+\r
+static struct i2c_driver anx7150_i2c_driver = {\r
+ .driver = {\r
+ .name = "anx7150",\r
+ .owner = THIS_MODULE,\r
+ },\r
+ .probe = &anx7150_i2c_probe,\r
+ .remove = &anx7150_i2c_remove,\r
+ .id_table = anx7150_id,\r
+};\r
+\r
+\r
+static int __init anx7150_module_init(void)\r
+{\r
+ return i2c_add_driver(&anx7150_i2c_driver);\r
+}\r
+\r
+static void __exit anx7150_module_exit(void)\r
+{\r
+ i2c_del_driver(&anx7150_i2c_driver);\r
+}\r
+\r
+module_init(anx7150_module_init);\r
+//fs_initcall(anx7150_module_init);\r
+module_exit(anx7150_module_exit);\r
+\r
+\r
--- /dev/null
+#ifndef _ANX7150_H\r
+#define _ANX7150_H\r
+\r
+#include <linux/hdmi.h>\r
+#include <linux/earlysuspend.h>\r
+\r
+\r
+#define ANX7150_I2C_ADDR0 0X39\r
+#define ANX7150_I2C_ADDR1 0X3d\r
+\r
+#define ANX7150_SCL_RATE 100 * 1000\r
+\r
+\r
+/* HDMI auto switch */\r
+#define HDMI_AUTO_SWITCH HDMI_ENABLE\r
+\r
+/* HDMI reciver status */\r
+#define HDMI_RECIVER_INACTIVE 0\r
+#define HDMI_RECIVER_ACTIVE 1\r
+\r
+/* ANX7150 reciver HPD Status */\r
+#define HDMI_RECIVER_UNPLUG 0\r
+#define HDMI_RECIVER_PLUG 1\r
+\r
+#define LCD 0\r
+#define HDMI 1\r
+\r
+#define RK29_OUTPUT_STATUS_LCD LCD\r
+#define RK29_OUTPUT_STATUS_HDMI HDMI\r
+\r
+/* HDMI HDCP ENABLE */\r
+#define ANX7150_HDCP_EN HDMI_DISABLE\r
+\r
+/* ANX7150 state machine */\r
+enum{\r
+ HDMI_INITIAL = 1,\r
+ WAIT_HOTPLUG,\r
+ READ_PARSE_EDID,\r
+ WAIT_RX_SENSE,\r
+ WAIT_HDMI_ENABLE,\r
+ SYSTEM_CONFIG,\r
+ CONFIG_VIDEO,\r
+ CONFIG_AUDIO,\r
+ CONFIG_PACKETS,\r
+ HDCP_AUTHENTICATION,\r
+ PLAY_BACK,\r
+ RESET_LINK,\r
+ UNKNOWN,\r
+};\r
+\r
+\r
+struct anx7150_dev_s{\r
+ struct i2c_driver *i2c_driver;\r
+ struct fasync_struct *async_queue;\r
+ struct workqueue_struct *workqueue;\r
+ struct delayed_work delay_work;\r
+ struct miscdevice *mdev;\r
+ void (*notifier_callback)(struct anx7150_dev_s *);\r
+ int anx7150_detect;\r
+ int resolution_set;\r
+ int resolution_real;\r
+ int i2s_Fs;\r
+ int hdmi_enable;\r
+ int hdmi_auto_switch;\r
+ int reciver_status;\r
+ int HPD_change_cnt;\r
+ int HPD_status;\r
+ int rk29_output_status;\r
+ int hdcp_enable;\r
+ int parameter_config;\r
+ int rate;\r
+ int fb_switch_state;\r
+\r
+ struct hdmi *hdmi;\r
+};\r
+\r
+struct anx7150_pdata {\r
+ int irq;\r
+ int gpio;\r
+ int init;\r
+ int is_early_suspend;\r
+ int is_changed;\r
+ struct delayed_work work;\r
+ struct hdmi *hdmi;\r
+ struct i2c_client *client;\r
+ struct anx7150_dev_s dev;\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ struct early_suspend early_suspend;
+#endif\r
+};\r
+\r
+\r
+\r
+int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val);\r
+int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val);\r
+int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val);\r
+int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val);\r
+\r
+#endif\r
--- /dev/null
+#include <linux/delay.h>\r
+#include <linux/i2c.h>\r
+#include <linux/hdmi.h>\r
+#include <linux/slab.h>\r
+\r
+#include "anx7150.h"\r
+#include "anx7150_hw.h"\r
+//#ifdef ITU656\r
+struct ANX7150_video_timingtype ANX7150_video_timingtype_table =\r
+{\r
+ //640x480p-60hz\r
+ {0x20/*H_RES_LOW*/, 0x03/*H_RES_HIGH*/,0x80 /*ACT_PIX_LOW*/,0x02 /*ACT_PIX_HIGH*/,\r
+ 0x60/*HSYNC_WIDTH_LOW*/,0x00 /*HSYNC_WIDTH_HIGH*/,0x30 /*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
+ 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/,0x02 /*VSYNC_WIDTH*/, 0x21/*V_BP_LINE*/,\r
+ 0x0a/*V_FP_LINE*/,0x10 /*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
+ //720x480p-60hz\r
+ {0x5a/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0/*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
+ 0x3e/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x3c/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/, 0x06/*VSYNC_WIDTH*/, 0x1e/*V_BP_LINE*/,\r
+ 0x09/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
+ //720p-60hz\r
+ {0x72/*H_RES_LOW*/, 0x06/*H_RES_HIGH*/, 0x00/*ACT_PIX_LOW*/, 0x05/*ACT_PIX_HIGH*/,\r
+ 0x28/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0xdc/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0xd0/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x14/*V_BP_LINE*/,\r
+ 0x05/*V_FP_LINE*/, 0x6e/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Progressive, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+ //1080i-60hz\r
+ {0x98/*H_RES_LOW*/, 0x08/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
+ 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
+ 0x02/*V_FP_LINE*/, 0x58/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+ //720x480i-60hz\r
+ {0x5a/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0/*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
+ 0x3e/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x39/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/, 0x03/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
+ 0x04/*V_FP_LINE*/, 0x13/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol}, //update\r
+ //1080p-60hz\r
+ {0x98/*H_RES_LOW*/, 0x08/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
+ 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x24/*V_BP_LINE*/,\r
+ 0x04/*V_FP_LINE*/, 0x58/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+ //576p-50hz\r
+ {0x60/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0 /*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
+ 0x40/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x44/*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
+ 0x40/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x27/*V_BP_LINE*/,\r
+ 0x05/*V_FP_LINE*/, 0x0c/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
+ //720p-50hz\r
+ {0xbc/*H_RES_LOW*/, 0x07/*H_RES_HIGH*/, 0x00/*ACT_PIX_LOW*/, 0x05/*ACT_PIX_HIGH*/,\r
+ 0x28/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0xdc/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0xd0/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x14/*V_BP_LINE*/,\r
+ 0x05/*V_FP_LINE*/, 0xb8/*H_FP_LOW*/, 0x01/*H_FP_HIGH*/,\r
+ ANX7150_Progressive, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+ //1080i-50hz\r
+ {0x50/*H_RES_LOW*/, 0x0a/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
+ 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
+ 0x02/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x02/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+ //576i-50hz\r
+ {0x60/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0 /*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
+ 0x3f/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x45/*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
+ 0x40/*ACT_LINE_LOW*/,0x02 /*ACT_LINE_HIGH*/, 0x03/*VSYNC_WIDTH*/, 0x13/*V_BP_LINE*/,\r
+ 0x02/*V_FP_LINE*/, 0x0c/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
+ \r
+ //1080p-50hz\r
+ {0x50/*H_RES_LOW*/, 0x0a/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
+ 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
+ 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x24/*V_BP_LINE*/,\r
+ 0x04/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x02/*H_FP_HIGH*/,\r
+ ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
+};\r
+//#endif\r
+int anx7150_mass_read_need_delay = 0;\r
+\r
+u8 g_video_format = 0x00;\r
+u8 g_audio_format = 0x00;\r
+\r
+\r
+u8 timer_slot = 0;\r
+u8 *ANX7150_EDID_Buf = NULL;\r
+u8 ANX7150_avi_data[19];//, ANX7150_avi_checksum;\r
+u8 ANX7150_system_state = HDMI_INITIAL;\r
+u8 spdif_error_cnt = 0x00;\r
+u8 misc_reset_needed;\r
+u8 ANX7150_stdaddr,ANX7150_stdreg,ANX7150_ext_block_num;\r
+u8 ANX7150_svd_length,ANX7150_sau_length;\r
+u8 ANX7150_edid_dtd[18];\r
+u32 ANX7150_edid_length;\r
+ANX7150_edid_result_4_system ANX7150_edid_result;\r
+\r
+u8 ANX7150_ddc_fifo_full;\r
+u8 ANX7150_ddc_progress;\r
+u8 ANX7150_hdcp_auth_en;\r
+//u8 ANX7150_bksv_ready; //replace by srm_checked xy 01.09\r
+u8 ANX7150_HDCP_enable;\r
+u8 ANX7150_ksv_srm_pass;\r
+u8 ANX7150_hdcp_bcaps;\r
+u8 ANX7150_hdcp_bstatus[2];\r
+u8 ANX7150_srm_checked;\r
+u8 ANX7150_hdcp_auth_pass;\r
+u8 ANX7150_avmute_enable;\r
+u8 ANX7150_send_blue_screen;\r
+u8 ANX7150_hdcp_encryption;\r
+u8 ANX7150_hdcp_init_done;\r
+u8 ANX7150_hdcp_wait_100ms_needed;\r
+u8 ANX7150_auth_fully_pass;\r
+u8 ANX7150_parse_edid_done;//060714 XY\r
+//u8 testen;\r
+//u8 ANX7150_avi_data[19], ANX7150_avi_checksum;\r
+u8 ANX7150_hdcp_auth_fail_counter ;\r
+\r
+u8 ANX7150_video_format_config;\r
+u8 ANX7150_emb_sync_mode,ANX7150_de_gen_en,ANX7150_demux_yc_en,ANX7150_ddr_bus_mode;\r
+u8 ANX7150_ddr_edge,ANX7150_ycmux_u8_sel;\r
+u8 ANX7150_system_config_done;\r
+u8 ANX7150_RGBorYCbCr; //modified by zy 060814\r
+u8 ANX7150_in_pix_rpt,ANX7150_tx_pix_rpt;\r
+u8 ANX7150_in_pix_rpt_bkp,ANX7150_tx_pix_rpt_bkp;\r
+u8 ANX7150_video_timing_id;\r
+u8 ANX7150_pix_rpt_set_by_sys;\r
+u8 ANX7150_video_timing_parameter[18];\r
+u8 switch_value_sw_backup,switch_value_pc_backup;\r
+u8 switch_value,bist_switch_value_pc;\r
+u8 ANX7150_new_csc,ANX7150_new_vid_id,ANX7150_new_HW_interface;\r
+u8 ANX7150_INT_Done;\r
+\r
+audio_config_struct s_ANX7150_audio_config;\r
+config_packets s_ANX7150_packet_config;\r
+\r
+u8 FREQ_MCLK; //0X72:0X50 u82:0\r
+//000b:Fm = 128*Fs\r
+//001b:Fm = 256*Fs\r
+//010b:Fm = 384*Fs\r
+//011b:Fm = 512*Fs\r
+u8 ANX7150_audio_clock_edge;\r
+int ANX7150_DDC_Mass_Read(struct i2c_client *client, u8 *buf, u16 len);\r
+\r
+int anx7150_detect_device(struct anx7150_pdata *anx)\r
+{\r
+ int i, rc = 0; \r
+ char d1, d2;\r
+ \r
+ for (i=0; i<10; i++) \r
+ { \r
+ if((rc = anx7150_i2c_read_p0_reg(anx->client, ANX7150_DEV_IDL_REG, &d1)) < 0) \r
+ continue;\r
+ if((rc = anx7150_i2c_read_p0_reg(anx->client, ANX7150_DEV_IDH_REG, &d2)) < 0) \r
+ continue;\r
+ if (d1 == 0x50 && d2 == 0x71)\r
+ { \r
+ hdmi_dbg(&anx->client->dev, "anx7150 detected!\n");\r
+ return 0;\r
+ } \r
+ } \r
+ \r
+ hdmi_dbg(&anx->client->dev, "anx7150 not detected");\r
+ return -1;\r
+}\r
+u8 ANX7150_Get_System_State(void)\r
+{\r
+ return ANX7150_system_state;\r
+}\r
+void ANX7150_Set_System_State(struct i2c_client *client, u8 new_state)\r
+{\r
+ ANX7150_system_state = new_state;\r
+ switch (ANX7150_system_state)\r
+ {\r
+ case HDMI_INITIAL:\r
+ hdmi_dbg(&client->dev, "INITIAL\n");\r
+ break;\r
+ case WAIT_HOTPLUG:\r
+ hdmi_dbg(&client->dev, "WAIT_HOTPLUG\n");\r
+ break;\r
+ case READ_PARSE_EDID:\r
+ hdmi_dbg(&client->dev, "READ_PARSE_EDID\n");\r
+ break;\r
+ case WAIT_RX_SENSE:\r
+ hdmi_dbg(&client->dev, "WAIT_RX_SENSE\n");\r
+ break;\r
+ case WAIT_HDMI_ENABLE:\r
+ hdmi_dbg(&client->dev, "WAIT_HDMI_ENABLE\n");\r
+ break;\r
+ case SYSTEM_CONFIG:\r
+ hdmi_dbg(&client->dev, "SYSTEM_CONFIG\n");\r
+ break;\r
+ case CONFIG_VIDEO:\r
+ dev_info(&client->dev, "CONFIG_VIDEO\n");\r
+ break;\r
+ case CONFIG_AUDIO:\r
+ hdmi_dbg(&client->dev, "CONFIG_AUDIO\n");\r
+ break;\r
+ case CONFIG_PACKETS:\r
+ hdmi_dbg(&client->dev, "CONFIG_PACKETS\n");\r
+ break;\r
+ case HDCP_AUTHENTICATION:\r
+ hdmi_dbg(&client->dev, "HDCP_AUTHENTICATION\n");\r
+ break;\r
+ ////////////////////////////////////////////////\r
+ // System ANX7150_RESET_LINK is kept for RX clock recovery error case, not used in normal case.\r
+ case RESET_LINK:\r
+ hdmi_dbg(&client->dev, "RESET_LINK\n");\r
+ break;\r
+ ////////////////////////////////////////////////\r
+ case PLAY_BACK:\r
+ dev_info(&client->dev, "PLAY_BACK\n");\r
+ break;\r
+ default:\r
+ hdmi_dbg(&client->dev, "unknown state\n");\r
+ break;\r
+ }\r
+}\r
+\r
+int anx7150_get_hpd(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char sys_ctl3, intr_state, sys_state, hpd_state;\r
+ \r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &sys_ctl3)) < 0)\r
+ return rc;\r
+ if(sys_ctl3 & ANX7150_SYS_CTRL3_PWON_ALL)\r
+ {\r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &sys_state)) < 0)\r
+ return rc;\r
+ hpd_state = (sys_state & ANX7150_SYS_STATE_HP)? 1:0;\r
+ }\r
+ else\r
+ {\r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR_STATE_REG, &intr_state)) < 0)\r
+ return rc;\r
+ hpd_state = (intr_state)? 1:0;\r
+ }\r
+ return hpd_state;\r
+}\r
+static int anx7150_get_interrupt_status(struct i2c_client *client, struct anx7150_interrupt_s *interrupt_staus)\r
+{\r
+ int rc = 0;\r
+ u8 int_s1;\r
+ u8 int_s2;\r
+ u8 int_s3;\r
+ \r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_STATUS_REG, &int_s1);//jack wen, for spdif input from SD0.\r
+ rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_STATUS_REG, &int_s1);//power down all, 090630\r
+ rc |= anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_STATUS_REG, &int_s2);//jack wen, for spdif input from SD0.\r
+ rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_STATUS_REG, &int_s2);//power down all, 090630\r
+ rc |= anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_STATUS_REG, &int_s3);//jack wen, for spdif input from SD0.\r
+ rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_STATUS_REG, &int_s3);//power down all, 090630\r
+\r
+ interrupt_staus->hotplug_change = (int_s1 & ANX7150_INTR1_STATUS_HP_CHG) ? 1 : 0;\r
+ interrupt_staus->video_format_change = (int_s3 & ANX7150_INTR3_STATUS_VIDF_CHG) ? 1 : 0;\r
+ interrupt_staus->auth_done = (int_s2 & ANX7150_INTR2_STATUS_AUTH_DONE) ? 1 : 0;\r
+ interrupt_staus->auth_state_change = (int_s2 & ANX7150_INTR2_STATUS_AUTH_CHG) ? 1 : 0;\r
+ interrupt_staus->pll_lock_change = (int_s2 & ANX7150_INTR2_STATUS_PLLLOCK_CHG) ? 1 : 0;\r
+ interrupt_staus->rx_sense_change = (int_s3 & ANX7150_INTR3_STATUS_RXSEN_CHG) ? 1 : 0;\r
+ interrupt_staus->HDCP_link_change = (int_s2 & ANX7150_INTR2_STATUS_HDCPLINK_CHK) ? 1 : 0;\r
+ interrupt_staus->audio_clk_change = (int_s3 & ANX7150_INTR3_STATUS_AUDCLK_CHG) ? 1 : 0;\r
+ interrupt_staus->audio_FIFO_overrun = (int_s1 & ANX7150_INTR1_STATUS_AFIFO_OVER) ? 1 : 0;\r
+ interrupt_staus->SPDIF_error = (int_s1 & ANX7150_INTR1_STATUS_SPDIF_ERR) ? 1 : 0;\r
+ interrupt_staus->SPDIF_bi_phase_error = ((int_s3 & ANX7150_INTR3_STATUS_SPDIFBI_ERR) ? 1 : 0) \r
+ || ((int_s3 & ANX7150_INTR3_STATUS_SPDIF_UNSTBL) ? 1 : 0);\r
+ return 0;\r
+}\r
+static void ANX7150_Variable_Initial(void)\r
+{\r
+ u8 i;\r
+\r
+ ANX7150_hdcp_auth_en = 0;\r
+ ANX7150_ksv_srm_pass =0;\r
+ ANX7150_srm_checked = 0;\r
+ ANX7150_hdcp_auth_pass = 0;\r
+ ANX7150_avmute_enable = 1;\r
+ ANX7150_hdcp_auth_fail_counter =0;\r
+ ANX7150_hdcp_encryption = 0;\r
+ ANX7150_send_blue_screen = 0;\r
+ ANX7150_hdcp_init_done = 0;\r
+ ANX7150_hdcp_wait_100ms_needed = 1;\r
+ ANX7150_auth_fully_pass = 0;\r
+ timer_slot = 0;\r
+ //********************for video config**************\r
+ ANX7150_video_timing_id = 0;\r
+ ANX7150_in_pix_rpt = 0;\r
+ ANX7150_tx_pix_rpt = 0;\r
+ ANX7150_new_csc = 0;\r
+ ANX7150_new_vid_id = 0;\r
+ ANX7150_new_HW_interface = 0;\r
+ //********************end of video config*********\r
+\r
+ //********************for edid parse***********\r
+ ANX7150_edid_result.is_HDMI = 1;\r
+ ANX7150_edid_result.ycbcr422_supported = 0;\r
+ ANX7150_edid_result.ycbcr444_supported = 0;\r
+ ANX7150_edid_result.supported_720p_60Hz = 0;\r
+ ANX7150_edid_result.supported_720p_50Hz = 0;\r
+ ANX7150_edid_result.supported_576p_50Hz = 0;\r
+ ANX7150_edid_result.supported_576i_50Hz = 0;\r
+ ANX7150_edid_result.supported_1080i_60Hz = 0;\r
+ ANX7150_edid_result.supported_1080i_50Hz = 0;\r
+ ANX7150_edid_result.supported_640x480p_60Hz = 0;\r
+ ANX7150_edid_result.supported_720x480p_60Hz = 0;\r
+ ANX7150_edid_result.supported_720x480i_60Hz = 0;\r
+ ANX7150_edid_result.edid_errcode = 0;\r
+ ANX7150_edid_result.SpeakerFormat = 0;\r
+ for (i = 0; i < 8; i ++)\r
+ {\r
+ ANX7150_edid_result.AudioChannel[i] = 0;\r
+ ANX7150_edid_result.AudioFormat[i] = 0;\r
+ ANX7150_edid_result.AudioFs[i] = 0;\r
+ ANX7150_edid_result.AudioLength[i] = 0;\r
+ }\r
+ //********************end of edid**************\r
+\r
+ s_ANX7150_packet_config.packets_need_config = 0x03; //new avi infoframe\r
+ s_ANX7150_packet_config.avi_info.type = 0x82;\r
+ s_ANX7150_packet_config.avi_info.version = 0x02;\r
+ s_ANX7150_packet_config.avi_info.length = 0x0d;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[1] = 0x21;//YCbCr422\r
+ s_ANX7150_packet_config.avi_info.pb_u8[2] = 0x08;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[3] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[4] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[5] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[6] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[7] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[8] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[9] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[10] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[11] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[12] = 0x00;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[13] = 0x00;\r
+\r
+ // audio infoframe\r
+ s_ANX7150_packet_config.audio_info.type = 0x84;\r
+ s_ANX7150_packet_config.audio_info.version = 0x01;\r
+ s_ANX7150_packet_config.audio_info.length = 0x0a;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[1] = 0x00; //zy 061123 for ATC\r
+ s_ANX7150_packet_config.audio_info.pb_u8[2] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[3] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[4] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[5] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[6] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[7] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[8] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[9] = 0x00;\r
+ s_ANX7150_packet_config.audio_info.pb_u8[10] = 0x00;\r
+\r
+ ANX7150_INT_Done = 0;\r
+}\r
+static void ANX7150_HW_Interface_Variable_Initial(void)\r
+{\r
+ u8 c;\r
+\r
+ ANX7150_video_format_config = 0x00;\r
+ ANX7150_RGBorYCbCr = 0x00;\r
+ ANX7150_ddr_edge = ANX7150_IDCK_EDGE_DDR;\r
+\r
+ c = 0;\r
+ c = (ANX7150_I2S_CH0_ENABLE << 2) | (ANX7150_I2S_CH1_ENABLE << 3) |\r
+ (ANX7150_I2S_CH2_ENABLE << 4) | (ANX7150_I2S_CH3_ENABLE << 5);\r
+ s_ANX7150_audio_config.audio_type = ANX7150_AUD_HW_INTERFACE; // input I2S\r
+ s_ANX7150_audio_config.down_sample = 0x00;\r
+ s_ANX7150_audio_config.i2s_config.audio_channel = c;//0x04;\r
+ s_ANX7150_audio_config.i2s_config.Channel_status1 =0x00;\r
+ s_ANX7150_audio_config.i2s_config.Channel_status1 = 0x00;\r
+ s_ANX7150_audio_config.i2s_config.Channel_status2 = 0x00;\r
+ s_ANX7150_audio_config.i2s_config.Channel_status3 = 0x00;\r
+ s_ANX7150_audio_config.i2s_config.Channel_status4 = 0x00;//0x02;//48k\r
+ s_ANX7150_audio_config.i2s_config.Channel_status5 = ANX7150_I2S_WORD_LENGTH;//0x0b;\r
+ s_ANX7150_audio_config.audio_layout = 0x00;\r
+\r
+ c = (ANX7150_I2S_SHIFT_CTRL << 3) | (ANX7150_I2S_DIR_CTRL << 2) |\r
+ (ANX7150_I2S_WS_POL << 1) | ANX7150_I2S_JUST_CTRL;\r
+ s_ANX7150_audio_config.i2s_config.i2s_format = c;//0x00;\r
+\r
+ FREQ_MCLK = ANX7150_MCLK_Fs_RELATION;//set the relation of MCLK and WS\r
+ ANX7150_audio_clock_edge = ANX7150_AUD_CLK_EDGE;\r
+\r
+\r
+}\r
+static int anx7150_hardware_initial(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c = 0;\r
+ \r
+ //clear HDCP_HPD_RST\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+ c |= (0x01);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+\r
+ mdelay(10);\r
+\r
+ c &= (~0x01);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+ \r
+ //Power on I2C\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
+ c |= (ANX7150_SYS_CTRL3_I2C_PWON);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+ c= 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
+\r
+ //clear HDCP_HPD_RST\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c &= (0xbf);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+\r
+ //Power on Audio capture and Video capture module clock\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_PD_REG, &c);\r
+ c |= (0x06);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_PD_REG, &c);\r
+\r
+ //Enable auto set clock range for video PLL\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_CTRL_REG, &c);\r
+ c &= (0x00);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_CHIP_CTRL_REG, &c);\r
+\r
+ //Set registers value of Blue Screen when HDCP authentication failed--RGB mode,green field\r
+ c = 0x10;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
+ c = 0xeb;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
+ c = 0x10;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
+\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, (c | 0x80));\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_PLL_CTRL0_REG, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_CTRL0_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);\r
+ c |= (0x08);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_PLL_TX_AMP, &c);//jack wen\r
+ c |= (0x01);\r
+\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_TX_AMP, &c); //TMDS swing\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_CTRL1_REG, &c); //Added for PLL unlock issue in high temperature - Feiw\r
+ //if (ANX7150_AUD_HW_INTERFACE == 0x02) //jack wen, spdif\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);//jack wen, for spdif input from SD0.\r
+ c &= (0xef);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);\r
+\r
+ c = 0xc7;\r
+ rc = anx7150_i2c_write_p0_reg(client, 0xE1, &c);\r
+\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);//power down HDCP, 090630\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//jack wen, for spdif input from SD0.\r
+ c &= (0xfe);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//power down all, 090630\r
+\r
+ return rc;\r
+}\r
+\r
+int anx7150_rst_ddcchannel(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ //Reset the DDC channel\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+\r
+ c |= (ANX7150_SYS_CTRL2_DDC_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+\r
+ c &= (~ANX7150_SYS_CTRL2_DDC_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//abort current operation\r
+\r
+ c = 0x06;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//reset I2C command\r
+\r
+ //Clear FIFO\r
+ c = 0x05;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//reset I2C command\r
+\r
+ return rc;\r
+}\r
+\r
+int anx7150_initial(struct i2c_client *client)
+{
+ ANX7150_Variable_Initial(); //simon\r
+ ANX7150_HW_Interface_Variable_Initial(); //simon\r
+ \r
+ anx7150_hardware_initial(client); //simon\r
+ return 0;
+}
+int anx7150_unplug(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ dev_info(&client->dev, "anx7150 unplug\n");\r
+ \r
+ //wen HDCP CTS\r
+ ANX7150_Variable_Initial(); //simon\r
+ ANX7150_HW_Interface_Variable_Initial(); //simon\r
+ \r
+ rc = anx7150_hardware_initial(client); //simon\r
+ if(rc < 0)\r
+ dev_err(&client->dev, "%s>> i2c transfer err\n", __func__);\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c); //simon\r
+ if(rc < 0)\r
+ dev_err(&client->dev, "%s>> i2c transfer err\n", __func__);\r
+ //wen HDCP CTS\r
+ ANX7150_hdcp_wait_100ms_needed = 1;\r
+ ANX7150_auth_fully_pass = 0;\r
+\r
+ // clear ANX7150_parse_edid_done & ANX7150_system_config_done\r
+ ANX7150_parse_edid_done = 0;\r
+// ANX7150_system_config_done = 0;\r
+ ANX7150_srm_checked = 0;\r
+\r
+ return rc;\r
+}\r
+int anx7150_plug(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ dev_info(&client->dev, "anx7150 plug\n");\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
+ c |= (0x01);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//power up all, 090630\r
+\r
+ //disable audio & video & hdcp & TMDS and init begin\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c &= (~ANX7150_VID_CTRL_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ c &= (~ANX7150_TMDS_CLKCH_MUTE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+\r
+ ANX7150_Variable_Initial();\r
+ //disable video & audio & hdcp & TMDS and init end\r
+\r
+ \r
+ //Power on chip and select DVI mode\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c |= (0x05);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);// cwz change 0x01 -> 0x05\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c &= (0xfd);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+\r
+ //D("ANX7150 is set to DVI mode\n");\r
+ rc = anx7150_rst_ddcchannel(client);\r
+ //Initial Interrupt\r
+ // disable video/audio CLK,Format change and before config video. 060713 xy\r
+\r
+ c = 0x04;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_STATUS_REG, &c);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_STATUS_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_STATUS_REG, &c);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_STATUS_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_STATUS_REG, &c);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_STATUS_REG, &c);\r
+\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR_CTRL_REG, &c);\r
+\r
+ // clear ANX7150_parse_edid_done & ANX7150_system_config_done\r
+ ANX7150_parse_edid_done = 0;\r
+// ANX7150_system_config_done = 0;\r
+ ANX7150_srm_checked = 0;\r
+\r
+ return rc;\r
+}\r
+\r
+int anx7150_set_avmute(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ c = 0x01;\r
+ if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_GNRL_CTRL_PKT_REG, &c)) < 0)\r
+ return rc;\r
+ \r
+ if((rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ c |= (0x0c);\r
+ if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ ANX7150_avmute_enable = 1;\r
+\r
+ return rc;\r
+}\r
+int anx7150_clear_avmute(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ c = 0x02;\r
+ if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_GNRL_CTRL_PKT_REG, &c)) < 0)\r
+ return rc;\r
+ \r
+ if((rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ c |= (0x0c);\r
+ if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ ANX7150_avmute_enable = 0;\r
+// D("@@@@@@@@@@@@@@@@@@@@ANX7150_Clear_AVMute\n");\r
+ return rc;\r
+\r
+}\r
+\r
+static int anx7150_video_format_change(struct i2c_client *client)\r
+{\r
+ int rc;\r
+ char c;\r
+ \r
+ hdmi_dbg(&client->dev, "after video format change int \n");\r
+ \r
+ rc = anx7150_set_avmute(client);//wen\r
+ //stop HDCP and reset DDC\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ \r
+ rc = anx7150_rst_ddcchannel(client);\r
+ \r
+ //when format change, clear this reg to avoid error in package config\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ //xy 11.06 when format change, need system config again\r
+ // ANX7150_system_config_done = 0;\r
+ return rc;\r
+}\r
+static int anx7150_blue_screen_disable(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ c &= (0xfb);\r
+ if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
+ return rc;\r
+\r
+ ANX7150_send_blue_screen = 0;\r
+ \r
+ return rc;\r
+}\r
+static int anx7150_blue_screen_enable(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ \r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ c |= (ANX7150_HDCP_CTRL1_BLUE_SCREEN_EN);\r
+ if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
+ return rc;\r
+ ANX7150_send_blue_screen = 1;\r
+\r
+ return rc;\r
+}\r
+static int anx7150_hdcp_encryption_enable(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 c;\r
+ \r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
+ return rc;\r
+ c |= (ANX7150_HDCP_CTRL0_ENC_EN);\r
+ if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
+ return rc;\r
+ ANX7150_hdcp_encryption = 1;\r
+\r
+ return rc;\r
+}\r
+\r
+static int anx7150_hdcp_encryption_disable(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 c;\r
+ \r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
+ return rc;\r
+ c &= (0xfb);\r
+ if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
+ return rc;\r
+\r
+ ANX7150_hdcp_encryption = 0;\r
+\r
+ return rc;\r
+}\r
+\r
+static int anx7150_auth_done(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ hdmi_dbg(&client->dev, "anx7150 auth done\n");\r
+ \r
+ if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c)) < 0)\r
+ return rc;\r
+ \r
+ if (c & ANX7150_HDCP_STATUS_AUTH_PASS)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_Authentication pass in Auth_Done\n");\r
+ anx7150_blue_screen_disable(client);\r
+ ANX7150_hdcp_auth_pass = 1;\r
+ ANX7150_hdcp_auth_fail_counter = 0;\r
+ }\r
+ else\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_Authentication failed\n");\r
+ ANX7150_hdcp_wait_100ms_needed = 1;\r
+ ANX7150_auth_fully_pass = 0;\r
+ ANX7150_hdcp_auth_pass = 0;\r
+ ANX7150_hdcp_auth_fail_counter ++;\r
+ if (ANX7150_hdcp_auth_fail_counter >= ANX7150_HDCP_FAIL_THRESHOLD)\r
+ {\r
+ ANX7150_hdcp_auth_fail_counter = 0;\r
+ //ANX7150_bksv_ready = 0;\r
+ // TODO: Reset link;\r
+ rc = anx7150_blue_screen_enable(client);\r
+ rc = anx7150_hdcp_encryption_disable(client);\r
+ //disable audio\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+ }\r
+ return rc;\r
+}\r
+\r
+static int anx7150_clean_hdcp(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ //mute TMDS link\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, &c);//jack wen\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, c & (~ANX7150_TMDS_CLKCH_MUTE));\r
+\r
+ //Disable hardware HDCP\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ \r
+ //Reset HDCP logic\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SRST_REG, &c);\r
+ c |= (ANX7150_SRST_HDCP_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
+ c &= (~ANX7150_SRST_HDCP_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
+\r
+ //Set ReAuth\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c |= (ANX7150_HDCP_CTRL0_RE_AUTH);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_RE_AUTH);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ ANX7150_hdcp_auth_en = 0;\r
+ //ANX7150_bksv_ready = 0;\r
+ ANX7150_hdcp_auth_pass = 0;\r
+ ANX7150_hdcp_auth_fail_counter =0 ;\r
+ ANX7150_hdcp_encryption = 0;\r
+ ANX7150_send_blue_screen = 0;\r
+ ANX7150_hdcp_init_done = 0;\r
+ ANX7150_hdcp_wait_100ms_needed = 1;\r
+ ANX7150_auth_fully_pass = 0;\r
+ ANX7150_srm_checked = 0;\r
+ rc = anx7150_rst_ddcchannel(client);\r
+\r
+ return rc;\r
+}\r
+static int anx7150_auth_change(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ \r
+ int state = ANX7150_Get_System_State();\r
+ \r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
+ if (c & ANX7150_HDCP_STATUS_AUTH_PASS)\r
+ {\r
+ ANX7150_hdcp_auth_pass = 1;\r
+ hdmi_dbg(&client->dev, "ANX7150_Authentication pass in Auth_Change\n");\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_set_avmute(client); //wen\r
+ hdmi_dbg(&client->dev, "ANX7150_Authentication failed_by_Auth_change\n");\r
+ ANX7150_hdcp_auth_pass = 0;\r
+ ANX7150_hdcp_wait_100ms_needed = 1;\r
+ ANX7150_auth_fully_pass = 0;\r
+ ANX7150_hdcp_init_done=0; //wen HDCP CTS\r
+ ANX7150_hdcp_auth_en=0; //wen HDCP CTS\r
+ rc = anx7150_hdcp_encryption_disable(client);\r
+ if (state == PLAY_BACK)\r
+ {\r
+ ANX7150_auth_fully_pass = 0;\r
+ //disable audio\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ rc = anx7150_clean_hdcp(client); //wen updated for Changhong TV\r
+ }\r
+ }\r
+ return rc;\r
+}\r
+int ANX7150_GET_RECIVER_TYPE(void)\r
+{
+ return ANX7150_edid_result.is_HDMI;
+}\r
+static int anx7150_audio_clk_change(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ hdmi_dbg(&client->dev, "ANX7150: audio clock changed interrupt,disable audio.\n");\r
+ // disable audio\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ //xy 11.06 when format change, need system config again\r
+// ANX7150_system_config_done = 0;\r
+ return rc;\r
+}\r
+\r
+static int anx7150_afifo_overrun(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ hdmi_dbg(&client->dev, "ANX7150: AFIFO overrun interrupt,disable audio.\n");\r
+ // disable audio\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ return rc;\r
+}\r
+static int anx7150_spdif_error(struct i2c_client *client, int cur_state, int SPDIF_bi_phase_err, int SPDIF_error)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ int state = cur_state;\r
+\r
+ if(SPDIF_bi_phase_err || SPDIF_error)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ if( c & ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN) \r
+ {\r
+ \r
+ if ((state == CONFIG_AUDIO \r
+ || state == CONFIG_PACKETS \r
+ || state == HDCP_AUTHENTICATION \r
+ || state == PLAY_BACK ))\r
+ {\r
+ if(SPDIF_bi_phase_err){\r
+ hdmi_dbg(&client->dev, "SPDIF BI Phase or Unstable error.\n");\r
+ spdif_error_cnt += 0x03;\r
+ }\r
+\r
+ if(SPDIF_error){\r
+ hdmi_dbg(&client->dev, "SPDIF Parity error.\n");\r
+ spdif_error_cnt += 0x01;\r
+ }\r
+\r
+ }\r
+\r
+ // adjust spdif phase\r
+ if (spdif_error_cnt >= spdif_error_th)\r
+ {\r
+ char freq_mclk,c1,c2;\r
+ spdif_error_cnt = 0x00;\r
+ hdmi_dbg(&client->dev, "adjust mclk phase!\n");\r
+ \r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c2);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
+\r
+ freq_mclk = c2 & 0x07;\r
+ switch (freq_mclk)\r
+ {\r
+ case ANX7150_mclk_128_Fs: //invert 0x50[3]\r
+ hdmi_dbg(&client->dev, "adjust mclk phase when 128*Fs!\n");\r
+ if ( c2 & 0x08 ) c2 &= 0xf7;\r
+ else c2 |= 0x08;\r
+\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c2);\r
+ break;\r
+\r
+ case ANX7150_mclk_256_Fs:\r
+ case ANX7150_mclk_384_Fs:\r
+ hdmi_dbg(&client->dev, "adjust mclk phase when 256*Fs or 384*Fs!\n");\r
+ if ( c1 & 0x60 ) c1 &= 0x9f;\r
+ else c1 |= 0x20;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
+ break;\r
+\r
+ case ANX7150_mclk_512_Fs:\r
+ hdmi_dbg(&client->dev, "adjust mclk phase when 512*Fs!\n");\r
+ if ( c1 & 0x60 ) c1 &= 0x9f;\r
+ else c1 |= 0x40;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
+ break;\r
+ default:\r
+ break;\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else{\r
+ if(spdif_error_cnt > 0 && state == PLAY_BACK) spdif_error_cnt --;\r
+ if(spdif_error_cnt > 0 && state < CONFIG_AUDIO) spdif_error_cnt = 0x00;\r
+\r
+ }\r
+\r
+ return rc;\r
+}\r
+static int anx7150_plllock(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ \r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_STATUS_REG, &c);\r
+ if((c&0x01) == 0)\r
+ {\r
+ rc = anx7150_set_avmute(client);//wen\r
+ hdmi_dbg(&client->dev, "ANX7150: PLL unlock interrupt,disable audio.\n");\r
+ // disable audio & video\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c &= (~ANX7150_VID_CTRL_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+\r
+ //when pll change, clear this reg to avoid error in package config\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);//wen\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+\r
+// ANX7150_system_config_done = 0;//jack wen\r
+ }\r
+ return rc;\r
+}\r
+static int anx7150_rx_sense_change(struct i2c_client *client, int cur_state)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ int state = cur_state;\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
+ hdmi_dbg(&client->dev, "ANX7150_Rx_Sense_Interrupt, ANX7150_SYS_STATE_REG = %.2x\n", (unsigned int)c); //wen\r
+\r
+ if ( c & ANX7150_SYS_STATE_RSV_DET)\r
+ {\r
+ //xy 11.06 Power on chip\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c |= (0x01);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+\r
+ s_ANX7150_packet_config.packets_need_config = 0x03; //new avi infoframe wen\r
+ }\r
+ else\r
+ {\r
+ // Rx is not active\r
+ if (state > WAIT_HOTPLUG)\r
+ {\r
+ //stop HDCP and reset DDC when lost Rx sense\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_REG);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ \r
+ rc = anx7150_rst_ddcchannel(client);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c &= (0xfd);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ \r
+ // mute TMDS link\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ c &= (~ANX7150_TMDS_CLKCH_MUTE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ }\r
+ //Power down chip\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c &= (0xfe);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ }\r
+ //xy 11.06 when format change, need system config again\r
+// ANX7150_system_config_done = 0;//wen HDCP CTS\r
+\r
+ return rc;\r
+}\r
+int ANX7150_Interrupt_Process(struct anx7150_pdata *anx, int cur_state)\r
+{\r
+ struct anx7150_interrupt_s interrupt_staus;\r
+\r
+ int state;\r
+ int hot_plug;\r
+ int rc;\r
+\r
+ state = cur_state;\r
+\r
+ hot_plug = anx7150_get_hpd(anx->client);\r
+\r
+ rc = anx7150_get_interrupt_status(anx->client, &interrupt_staus);\r
+ if(rc < 0){\r
+ goto out;\r
+ } \r
+\r
+ if(anx->dev.HPD_status != hot_plug){\r
+ anx->dev.HPD_change_cnt++;\r
+ }\r
+ else{\r
+ anx->dev.HPD_change_cnt = 0;\r
+ }\r
+\r
+ if(anx->dev.HPD_change_cnt > 1){\r
+ hdmi_dbg(&anx->client->dev, "hotplug_change\n");\r
+\r
+ if(hot_plug == HDMI_RECIVER_UNPLUG){\r
+ anx7150_unplug(anx->client);\r
+ state = HDMI_INITIAL;\r
+ anx->dev.reciver_status = HDMI_RECIVER_INACTIVE;\r
+ }\r
+\r
+ anx->dev.HPD_change_cnt = 0;\r
+ anx->dev.HPD_status = hot_plug;\r
+ }\r
+ return state;\r
+ if(state != HDMI_INITIAL && state != WAIT_HOTPLUG){\r
+ if(interrupt_staus.video_format_change){\r
+ if(state > SYSTEM_CONFIG){\r
+ rc = anx7150_video_format_change(anx->client);\r
+ state = CONFIG_VIDEO;\r
+ }\r
+ }\r
+\r
+ if(interrupt_staus.auth_done){\r
+ rc = anx7150_auth_done(anx->client);\r
+ state = CONFIG_AUDIO;\r
+ }\r
+\r
+ if(interrupt_staus.auth_state_change){\r
+ rc = anx7150_auth_change(anx->client);\r
+ if(state == PLAY_BACK){\r
+ state = HDCP_AUTHENTICATION;\r
+ }\r
+ }\r
+\r
+ if(ANX7150_GET_RECIVER_TYPE() == 1){\r
+ /*\r
+ if(interrupt_staus.audio_clk_change){\r
+ if(state > CONFIG_VIDEO){\r
+ rc = anx7150_audio_clk_change(anx->client);\r
+ state = SYSTEM_CONFIG;\r
+ }\r
+ }\r
+ \r
+ if(interrupt_staus.audio_FIFO_overrun){\r
+ if(state > CONFIG_VIDEO){\r
+ rc = anx7150_afifo_overrun(anx->client);\r
+ state = CONFIG_AUDIO;\r
+ }\r
+ }\r
+\r
+*/\r
+ rc = anx7150_spdif_error(anx->client, state, interrupt_staus.SPDIF_bi_phase_error, interrupt_staus.SPDIF_error);\r
+ }\r
+\r
+ if(interrupt_staus.pll_lock_change){\r
+ if(state > SYSTEM_CONFIG){\r
+ rc = anx7150_plllock(anx->client);\r
+ state = SYSTEM_CONFIG;\r
+ }\r
+ }\r
+\r
+ if(interrupt_staus.rx_sense_change){\r
+ anx7150_rx_sense_change(anx->client, state);\r
+ if(state > WAIT_RX_SENSE) \r
+ state = WAIT_RX_SENSE;\r
+ }\r
+ }\r
+\r
+out:\r
+ return state;\r
+}\r
+\r
+int ANX7150_API_Initial(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ hdmi_dbg(&client->dev, "%s\n", __func__);\r
+\r
+ ANX7150_Variable_Initial();\r
+ ANX7150_HW_Interface_Variable_Initial();\r
+ rc = anx7150_hardware_initial(client);\r
+\r
+ return rc;\r
+}\r
+\r
+void ANX7150_Shutdown(struct i2c_client *client)\r
+{\r
+ hdmi_dbg(&client->dev, "%s\n", __func__);\r
+ ANX7150_API_Initial(client);\r
+ ANX7150_Set_System_State(client, HDMI_INITIAL);\r
+}\r
+\r
+static int anx7150_initddc_read(struct i2c_client *client, \r
+ u8 devaddr, u8 segmentpointer,\r
+ u8 offset, u8 access_num_Low,u8 access_num_high)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ //Write slave device address\r
+ c = devaddr;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_ADDR_REG, &c);\r
+ // Write segment address\r
+ c = segmentpointer;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_SEGADDR_REG, &c);\r
+ //Write offset\r
+ c = offset;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_OFFADDR_REG, &c);\r
+ //Write number for access\r
+ c = access_num_Low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACCNUM0_REG, &c);\r
+ c = access_num_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACCNUM1_REG, &c);\r
+ //Clear FIFO\r
+ c = 0x05;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);\r
+ //EDDC sequential Read\r
+ c = 0x04;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);\r
+\r
+ return rc;\r
+}\r
+static int ANX7150_GetEDIDLength(struct i2c_client *client)\r
+{\r
+ u8 edid_data_length;\r
+ int rc = 0;\r
+\r
+ anx7150_rst_ddcchannel(client);\r
+\r
+ rc = anx7150_initddc_read(client, 0xa0, 0x00, 0x7e, 0x01, 0x00);\r
+\r
+ mdelay(10);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &edid_data_length);\r
+\r
+ ANX7150_edid_length = edid_data_length * 128 + 128;\r
+\r
+ return rc;\r
+\r
+}\r
+/*** DDC fetch and block validation ***/\r
+\r
+static const u8 edid_header[] = {\r
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00\r
+};\r
+\r
+\r
+/*\r
+ * Sanity check the EDID block (base or extension). Return 0 if the block\r
+ * doesn't check out, or 1 if it's valid.\r
+ */\r
+ \r
+int anx7150_edid_block_valid(struct i2c_client *client, u8 *raw_edid)\r
+{\r
+ int i;\r
+ u8 csum = 0;\r
+ struct edid *edid = (struct edid *)raw_edid;\r
+\r
+ if (raw_edid[0] == 0x00) {\r
+ int score = 0;\r
+\r
+ for (i = 0; i < sizeof(edid_header); i++)\r
+ if (raw_edid[i] == edid_header[i])\r
+ score++;\r
+\r
+ if (score == 8) ;\r
+ else if (score >= 6) {\r
+ hdmi_dbg(&client->dev, "Fixing EDID header, your hardware may be failing\n");\r
+ memcpy(raw_edid, edid_header, sizeof(edid_header));\r
+ } else {\r
+ goto bad;\r
+ }\r
+ }\r
+\r
+#if 0\r
+ for (i = 0; i < EDID_LENGTH; i++)\r
+ csum += raw_edid[i];\r
+ if (csum) {\r
+ hdmi_dbg(&client->dev, "EDID checksum is invalid, remainder is %d\n", csum);\r
+\r
+ /* allow CEA to slide through, switches mangle this */\r
+ if (raw_edid[0] != 0x02)\r
+ goto bad;\r
+ }\r
+#endif\r
+\r
+ /* per-block-type checks */\r
+ switch (raw_edid[0]) {\r
+ case 0: /* base */\r
+ if (edid->version != 1) {\r
+ dev_err(&client->dev, "EDID has major version %d, instead of 1\n", edid->version);\r
+ goto bad;\r
+ }\r
+\r
+ if (edid->revision > 4)\r
+ dev_err(&client->dev,"EDID minor > 4, assuming backward compatibility\n");\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return 1;\r
+\r
+bad:\r
+ if (raw_edid) {\r
+ dev_err(&client->dev, "Raw EDID:\n");\r
+ print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);\r
+ printk("\n");\r
+ }\r
+ return 0;\r
+}\r
+int ANX7150_DDC_EDID(struct i2c_client *client, u8 *buf, u8 block, u16 len)\r
+{\r
+ u8 offset;\r
+ u8 segment;\r
+ u8 len_low;\r
+ u8 len_high;\r
+ \r
+ offset = EDID_LENGTH * (block & 0x01);\r
+ segment = block >> 1;\r
+ len_low = len & 0xFF;\r
+ len_high = (len >> 8) & 0xFF;\r
+\r
+ anx7150_initddc_read(client, 0xa0, segment, offset, len_low, len_high);\r
+ if(ANX7150_DDC_Mass_Read(client, buf, len) == len)\r
+ return 0;\r
+ else\r
+ return -1;\r
+}\r
+u8 *ANX7150_Read_EDID(struct i2c_client *client)\r
+{\r
+ u8 *block = NULL;\r
+ u8 *raw_edid = NULL;\r
+ u8 extend_block_num;\r
+ int i = 0;\r
+ int j = 0;\r
+\r
+ anx7150_rst_ddcchannel(client);\r
+\r
+ if ((block = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)\r
+ return NULL;\r
+\r
+ /* base block fetch */\r
+ hdmi_dbg(&client->dev, "Read base block\n");\r
+ for (i = 0; i < 4; i++) {\r
+ if(ANX7150_DDC_EDID(client, block, 0, EDID_LENGTH))\r
+ goto out;\r
+ if(anx7150_edid_block_valid(client, block))\r
+ break;\r
+ else\r
+ dev_err(&client->dev, "Read base block err, retry...\n");\r
+ \r
+ mdelay(10);\r
+ }\r
+\r
+ if(i == 4){\r
+ dev_err(&client->dev, "Read base block failed\n");\r
+ goto out;\r
+ }\r
+\r
+ /* if there's no extensions, we're done */\r
+ extend_block_num = block[0x7e];\r
+ if(extend_block_num == 0)\r
+ goto out;\r
+ \r
+ dev_err(&client->dev, "extend_block_num = %d\n", extend_block_num);\r
+\r
+ raw_edid = krealloc(block, (extend_block_num + 1) * EDID_LENGTH, GFP_KERNEL);\r
+ if(!raw_edid)\r
+ goto out;\r
+\r
+ block = raw_edid;\r
+\r
+ hdmi_dbg(&client->dev, "Read extend block\n");\r
+ for(j=1; j<=extend_block_num; j++){\r
+ for(i=0; i<4; i++){\r
+ if(ANX7150_DDC_EDID(client, raw_edid + j * EDID_LENGTH, j, EDID_LENGTH))\r
+ goto out;\r
+ if(anx7150_edid_block_valid(client, raw_edid + j * EDID_LENGTH))\r
+ break;\r
+ else\r
+ dev_err(&client->dev, "Read extend block %d err, retry...\n", j);\r
+\r
+ mdelay(10);\r
+ }\r
+\r
+ if(i == 4){\r
+ dev_err(&client->dev, "Read extend block %d failed\n", j);\r
+ goto out;\r
+ }\r
+ }\r
+\r
+ dev_err(&client->dev, "\n\nRaw EDID(extend_block_num = %d, total_len = %d):\n\n", extend_block_num, EDID_LENGTH*(extend_block_num+1));\r
+ print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH*(extend_block_num+1));\r
+ printk("\n\n");\r
+\r
+ return raw_edid;\r
+\r
+out:\r
+ kfree(block);\r
+ return NULL;\r
+}\r
+int ANX7150_DDC_Mass_Read(struct i2c_client *client, u8 *buf, u16 len)\r
+{\r
+ int rc = 0;\r
+ u32 i, j;\r
+ char c, c1,ddc_empty_cnt;\r
+\r
+ i = len;\r
+ while (i > 0)\r
+ {\r
+ //check DDC FIFO statue\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_CHSTATUS_REG, &c);\r
+ if (c & ANX7150_DDC_CHSTATUS_DDC_OCCUPY)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150 DDC channel is accessed by an external device, break!.\n");\r
+ break;\r
+ }\r
+ if (c & ANX7150_DDC_CHSTATUS_FIFO_FULL)\r
+ ANX7150_ddc_fifo_full = 1;\r
+ else\r
+ ANX7150_ddc_fifo_full = 0;\r
+ if (c & ANX7150_DDC_CHSTATUS_INPRO)\r
+ ANX7150_ddc_progress = 1;\r
+ else\r
+ ANX7150_ddc_progress = 0;\r
+ if (ANX7150_ddc_fifo_full)\r
+ {\r
+ hdmi_dbg(&client->dev, "DDC FIFO is full during edid reading");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFOCNT_REG, &c);\r
+ hdmi_dbg(&client->dev, "FIFO counter is %.2x\n", (u32) c);\r
+ for (j=0; j<c; j++)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &c1);\r
+ buf[len - i + j] = c1;\r
+\r
+ ANX7150_ddc_fifo_full = 0;\r
+ if(anx7150_mass_read_need_delay)\r
+ mdelay(1);\r
+ }\r
+ i = i - c;\r
+ //D("\n");\r
+ }\r
+ else if (!ANX7150_ddc_progress)\r
+ {\r
+ //D("ANX7150 DDC FIFO access finished.\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFOCNT_REG, &c);\r
+ //D("FIFO counter is %.2x\n", (u32) c);\r
+ if (!c)\r
+ {\r
+ i =0;\r
+ break;\r
+ }\r
+ for (j=0; j<c; j++)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &c1);\r
+ buf[len - i + j] = c1;\r
+ }\r
+ i = i - c;\r
+ //D("\ni=%d\n", i);\r
+ }\r
+ else\r
+ {\r
+ ddc_empty_cnt = 0x00;\r
+ for (c1=0; c1<0x0a; c1++)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_CHSTATUS_REG, &c);\r
+ //D("DDC FIFO access is progressing.\n");\r
+ //D("DDC Channel status is 0x%.2x\n",(u32)c);\r
+ if (c & ANX7150_DDC_CHSTATUS_FIFO_EMPT)\r
+ ddc_empty_cnt++;\r
+ mdelay(1);\r
+ //D("ddc_empty_cnt = 0x%.2x\n",(u32)ddc_empty_cnt);\r
+ }\r
+ if (ddc_empty_cnt >= 0x0a)\r
+ break;\r
+ }\r
+ }\r
+ return (len - i);\r
+}\r
+\r
+static u8 ANX7150_Read_EDID_u8(u8 segmentpointer,u8 offset)\r
+{
+ /*u8 c;
+ anx7150_initddc_read(0xa0, segmentpointer, offset, 0x01, 0x00);\r
+ ANX7150_i2c_read_p0_reg(ANX7150_DDC_FIFOCNT_REG, &c);
+ while(c==0)
+ ANX7150_i2c_read_p0_reg(ANX7150_DDC_FIFO_ACC_REG, &c);
+ return c;*/
+
+ return ANX7150_EDID_Buf[offset];
+}\r
+static u8 ANX7150_Parse_EDIDHeader(void)\r
+{\r
+ u8 i,temp;\r
+ temp = 0;\r
+ // the EDID header should begin with 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00\r
+ if ((ANX7150_Read_EDID_u8(0, 0) == 0x00) && (ANX7150_Read_EDID_u8(0, 7) == 0x00))\r
+ {\r
+ for (i = 1; i < 7; i++)\r
+ {\r
+ if (ANX7150_Read_EDID_u8(0, i) != 0xff)\r
+ {\r
+ temp = 0x01;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ temp = 0x01;\r
+ }\r
+ if (temp == 0x01)\r
+ {\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ return 1;\r
+ }\r
+}\r
+static u8 ANX7150_Parse_EDIDVersion(void)\r
+{\r
+\r
+ if (!((ANX7150_Read_EDID_u8(0, 0x12) == 1) && (ANX7150_Read_EDID_u8(0, 0x13) >= 3) ))\r
+ {\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ return 1;\r
+ }\r
+}\r
+static void ANX7150_Parse_DTD(void)\r
+{
+ u32 temp;
+ unsigned long temp1,temp2;
+ u32 Hresolution,Vresolution,Hblanking,Vblanking;
+ u32 PixelCLK,Vtotal,H_image_size,V_image_size;
+ u8 Hz;
+ //float Ratio;
+
+ temp = ANX7150_edid_dtd[1];
+ temp = temp << 8;
+ PixelCLK = temp + ANX7150_edid_dtd[0];
+ // D("Pixel clock is 10000 * %u\n", temp);
+
+ temp = ANX7150_edid_dtd[4];
+ temp = (temp << 4) & 0x0f00;
+ Hresolution = temp + ANX7150_edid_dtd[2];
+ //D("Horizontal Active is %u\n", Hresolution);
+
+ temp = ANX7150_edid_dtd[4];
+ temp = (temp << 8) & 0x0f00;
+ Hblanking = temp + ANX7150_edid_dtd[3];
+ //D("Horizontal Blanking is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[7];
+ temp = (temp << 4) & 0x0f00;
+ Vresolution = temp + ANX7150_edid_dtd[5];
+ //D("Vertical Active is %u\n", Vresolution);
+
+ temp = ANX7150_edid_dtd[7];
+ temp = (temp << 8) & 0x0f00;
+ Vblanking = temp + ANX7150_edid_dtd[6];
+ //D("Vertical Blanking is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[11];
+ temp = (temp << 2) & 0x0300;
+ temp = temp + ANX7150_edid_dtd[8];
+ //D("Horizontal Sync Offset is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[11];
+ temp = (temp << 4) & 0x0300;
+ temp = temp + ANX7150_edid_dtd[9];
+ //D("Horizontal Sync Pulse is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[11];
+ temp = (temp << 2) & 0x0030;
+ temp = temp + (ANX7150_edid_dtd[10] >> 4);
+ //D("Vertical Sync Offset is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[11];
+ temp = (temp << 4) & 0x0030;
+ temp = temp + (ANX7150_edid_dtd[8] & 0x0f);
+ //D("Vertical Sync Pulse is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[14];
+ temp = (temp << 4) & 0x0f00;
+ H_image_size = temp + ANX7150_edid_dtd[12];
+ //D("Horizontal Image size is %u\n", temp);
+
+ temp = ANX7150_edid_dtd[14];
+ temp = (temp << 8) & 0x0f00;
+ V_image_size = temp + ANX7150_edid_dtd[13];
+ //D("Vertical Image size is %u\n", temp);
+
+ //D("Horizontal Border is %bu\n", ANX7150_edid_dtd[15]);
+
+ //D("Vertical Border is %bu\n", ANX7150_edid_dtd[16]);
+
+ temp1 = Hresolution + Hblanking;
+ Vtotal = Vresolution + Vblanking;
+ temp1 = temp1 * Vtotal;
+ temp2 = PixelCLK;
+ temp2 = temp2 * 10000;
+ if (temp1 == 0) //update
+ Hz=0;
+ else
+ Hz = temp2 / temp1;
+ //Hz = temp2 / temp1;
+ if ((Hz == 59) || (Hz == 60))
+ {
+ Hz = 60;
+ //D("_______________Vertical Active is %u\n", Vresolution);
+ if (Vresolution == 540)
+ ANX7150_edid_result.supported_1080i_60Hz = 1;
+ if (Vresolution == 1080)
+ ANX7150_edid_result.supported_1080p_60Hz = 1;
+ if (Vresolution == 720)
+ ANX7150_edid_result.supported_720p_60Hz = 1;
+ if ((Hresolution == 640) && (Vresolution == 480))
+ ANX7150_edid_result.supported_640x480p_60Hz = 1;
+ if ((Hresolution == 720) && (Vresolution == 480))
+ ANX7150_edid_result.supported_720x480p_60Hz = 1;
+ if ((Hresolution == 720) && (Vresolution == 240))
+ ANX7150_edid_result.supported_720x480i_60Hz = 1;
+ }
+ if (Hz == 50)
+ {
+ //D("+++++++++++++++Vertical Active is %u\n", Vresolution);
+ if (Vresolution == 540)
+ ANX7150_edid_result.supported_1080i_50Hz = 1;
+ if (Vresolution == 1080)
+ ANX7150_edid_result.supported_1080p_50Hz = 1;
+ if (Vresolution == 720)
+ ANX7150_edid_result.supported_720p_50Hz = 1;
+ if (Vresolution == 576)
+ ANX7150_edid_result.supported_576p_50Hz = 1;
+ if (Vresolution == 288)
+ ANX7150_edid_result.supported_576i_50Hz = 1;
+ }
+ //D("Fresh rate :% bu Hz\n", Hz);
+ //Ratio = H_image_size;
+ //Ratio = Ratio / V_image_size;
+ //D("Picture ratio : %f \n", Ratio);
+}\r
+static void ANX7150_Parse_DTDinBlockONE(void)\r
+{
+ u8 i;
+ for (i = 0; i < 18; i++)
+ {
+ ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x36));
+ }
+ //D("Parse the first DTD in Block one:\n");
+ ANX7150_Parse_DTD();
+
+ if ((ANX7150_Read_EDID_u8(0, 0x48) == 0)
+ && (ANX7150_Read_EDID_u8(0, 0x49) == 0)
+ && (ANX7150_Read_EDID_u8(0, 0x4a) == 0))
+ {
+ ;//D("the second DTD in Block one is not used to descript video timing.\n");
+ }
+ else
+ {
+ for (i = 0; i < 18; i++)
+ {
+ ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x48));
+ }
+ ANX7150_Parse_DTD();
+ }
+
+ if ((ANX7150_Read_EDID_u8(0,0x5a) == 0)
+ && (ANX7150_Read_EDID_u8(0,0x5b) == 0)
+ && (ANX7150_Read_EDID_u8(0,0x5c) == 0))
+ {
+ ;//D("the third DTD in Block one is not used to descript video timing.\n");
+ }
+ else
+ {
+ for (i = 0; i < 18; i++)
+ {
+ ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x5a));
+ }
+ ANX7150_Parse_DTD();
+ }
+
+ if ((ANX7150_Read_EDID_u8(0,0x6c) == 0)
+ && (ANX7150_Read_EDID_u8(0,0x6d) == 0)
+ && (ANX7150_Read_EDID_u8(0,0x6e) == 0))
+ {
+ ;//D("the fourth DTD in Block one is not used to descript video timing.\n");
+ }
+ else
+ {
+ for (i = 0; i < 18; i++)
+ {
+ ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0,(i + 0x6c));
+ }
+ ANX7150_Parse_DTD();
+ }
+}\r
+static void ANX7150_Parse_NativeFormat(void)\r
+{
+ u8 temp;
+ temp = ANX7150_Read_EDID_u8(0,0x83) & 0xf0;
+ /*if(temp & 0x80)
+ ;//D("DTV supports underscan.\n");
+ if(temp & 0x40)
+ ;//D("DTV supports BasicAudio.\n");*/
+ if (temp & 0x20)
+ {
+ //D("DTV supports YCbCr 4:4:4.\n");
+ ANX7150_edid_result.ycbcr444_supported= 1;
+ }
+ if (temp & 0x10)
+ {
+ //D("DTV supports YCbCr 4:2:2.\n");
+ ANX7150_edid_result.ycbcr422_supported= 1;
+ }
+}\r
+static void ANX7150_Parse_DTDinExtBlock(void)\r
+{
+ u8 i,DTDbeginAddr;
+ DTDbeginAddr = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2, 0x82)
+ + 0x80;
+ while (DTDbeginAddr < (0x6c + 0x80))
+ {
+ if ((ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,DTDbeginAddr) == 0)
+ && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(DTDbeginAddr + 1)) == 0)
+ && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(DTDbeginAddr + 2)) == 0))
+ {
+ ;//D("this DTD in Extension Block is not used to descript video timing.\n");
+ }
+ else
+ {
+ for (i = 0; i < 18; i++)
+ {
+ ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(i + DTDbeginAddr));
+ }
+ //D("Parse the DTD in Extension Block :\n");
+ ANX7150_Parse_DTD();
+ }
+ DTDbeginAddr = DTDbeginAddr + 18;
+ }
+}\r
+static void ANX7150_Parse_AudioSTD(void)\r
+{
+ u8 i,AudioFormat,STDReg_tmp,STDAddr_tmp;
+ STDReg_tmp = ANX7150_stdreg & 0x1f;
+ STDAddr_tmp = ANX7150_stdaddr + 1;
+ i = 0;
+ while (i < STDReg_tmp)
+ {
+ AudioFormat = (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp ) & 0xF8) >> 3;
+ ANX7150_edid_result.AudioChannel[i/3] = (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x07) + 1;
+ ANX7150_edid_result.AudioFormat[i/3] = AudioFormat;
+ ANX7150_edid_result.AudioFs[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 1)) & 0x7f;
+
+ if (AudioFormat == 1)
+ ANX7150_edid_result.AudioLength[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 2)) & 0x07;
+ else
+ ANX7150_edid_result.AudioLength[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 2)) << 3;
+
+ i = i + 3;
+ STDAddr_tmp = STDAddr_tmp + 3;
+ }
+}\r
+static void ANX7150_Parse_VideoSTD(void)\r
+{
+ u8 i,STDReg_tmp,STDAddr_tmp;
+ u8 SVD_ID[34];
+ STDReg_tmp = ANX7150_stdreg & 0x1f;
+ STDAddr_tmp = ANX7150_stdaddr + 1;
+ i = 0;
+ while (i < STDReg_tmp)
+ {
+ SVD_ID[i] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x7F;
+ //D("ANX7150_edid_result.SVD_ID[%.2x]=0x%.2x\n",(u32)i,(u32)ANX7150_edid_result.SVD_ID[i]);
+ //if(ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x80)
+ // D(" Native mode");
+ if (SVD_ID[i] == 1)
+ ANX7150_edid_result.supported_640x480p_60Hz = 1;
+ else if (SVD_ID[i] == 4)
+ ANX7150_edid_result.supported_720p_60Hz = 1;
+ else if (SVD_ID[i] == 19)
+ ANX7150_edid_result.supported_720p_50Hz = 1;
+ else if (SVD_ID[i] == 16)
+ ANX7150_edid_result.supported_1080p_60Hz = 1;
+ else if (SVD_ID[i] == 31)
+ ANX7150_edid_result.supported_1080p_50Hz = 1;
+ else if (SVD_ID[i] == 5)
+ ANX7150_edid_result.supported_1080i_60Hz = 1;
+ else if (SVD_ID[i] == 20)
+ ANX7150_edid_result.supported_1080i_50Hz = 1;
+ else if ((SVD_ID[i] == 2) ||(SVD_ID[i] == 3))
+ ANX7150_edid_result.supported_720x480p_60Hz = 1;
+ else if ((SVD_ID[i] == 6) ||(SVD_ID[i] == 7))
+ ANX7150_edid_result.supported_720x480i_60Hz = 1;
+ else if ((SVD_ID[i] == 17) ||(SVD_ID[i] == 18))
+ ANX7150_edid_result.supported_576p_50Hz = 1;
+ else if ((SVD_ID[i] == 21) ||(SVD_ID[i] == 22))
+ ANX7150_edid_result.supported_576i_50Hz = 1;
+
+ i = i + 1;
+ STDAddr_tmp = STDAddr_tmp + 1;
+ }
+}\r
+static void ANX7150_Parse_SpeakerSTD(void)\r
+{
+ ANX7150_edid_result.SpeakerFormat = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 1)) ;
+}\r
+static void ANX7150_Parse_VendorSTD(void)\r
+{\r
+ //u8 c;\r
+ if ((ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 1)) == 0x03)\r
+ && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 2)) == 0x0c)\r
+ && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 3)) == 0x00))\r
+ {\r
+ ANX7150_edid_result.is_HDMI = 1;\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c |ANX7150_SYS_CTRL1_HDMI);\r
+ }\r
+ else\r
+ {\r
+ ANX7150_edid_result.is_HDMI = 0;\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c & (~ANX7150_SYS_CTRL1_HDMI));\r
+ }\r
+}\r
+\r
+static void ANX7150_Parse_STD(void)\r
+{
+ u8 DTDbeginAddr;
+ ANX7150_stdaddr = 0x84;
+ DTDbeginAddr = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,0x82) + 0x80;
+ // D("Video DTDbeginAddr Register :%.2x\n", (u32) DTDbeginAddr);
+ while (ANX7150_stdaddr < DTDbeginAddr)
+ {
+ ANX7150_stdreg = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,ANX7150_stdaddr);
+ switch (ANX7150_stdreg & 0xe0)
+ {
+ case 0x20:
+ ANX7150_Parse_AudioSTD();
+ ANX7150_sau_length = ANX7150_stdreg & 0x1f;
+ break;
+ case 0x40:
+ ANX7150_Parse_VideoSTD();
+ ANX7150_svd_length = ANX7150_stdreg & 0x1f;
+ break;
+ case 0x80:
+ ANX7150_Parse_SpeakerSTD();
+ break;
+ case 0x60:
+ ANX7150_Parse_VendorSTD();
+ break;
+ default:
+ break;
+ }
+ ANX7150_stdaddr = ANX7150_stdaddr + (ANX7150_stdreg & 0x1f) + 0x01;
+ }
+}\r
+static u8 ANX7150_EDID_Checksum(u8 block_number)\r
+{
+ u8 i, real_checksum;
+ u8 edid_block_checksum;
+
+ edid_block_checksum = 0;
+ for (i = 0; i < 127; i ++)
+ {
+ if ((block_number / 2) * 2 == block_number)
+ edid_block_checksum = edid_block_checksum + ANX7150_Read_EDID_u8(block_number/2, i);
+ else
+ edid_block_checksum = edid_block_checksum + ANX7150_Read_EDID_u8(block_number/2, i + 0x80);
+ }
+ edid_block_checksum = (~edid_block_checksum) + 1;
+ // D("edid_block_checksum = 0x%.2x\n",(u32)edid_block_checksum);
+ if ((block_number / 2) * 2 == block_number)
+ real_checksum = ANX7150_Read_EDID_u8(block_number/2, 0x7f);
+ else
+ real_checksum = ANX7150_Read_EDID_u8(block_number/2, 0xff);
+ if (real_checksum == edid_block_checksum)
+ return 1;
+ else
+ return 0;
+}\r
+static u8 ANX7150_Parse_ExtBlock(void)\r
+{
+ u8 i,c;
+
+ for (i = 0; i < ANX7150_Read_EDID_u8(0, 0x7e); i++) //read in blocks
+ {
+ c = ANX7150_Read_EDID_u8(i/2, 0x80);
+ if ( c == 0x02)
+ {
+ ANX7150_ext_block_num = i + 1;
+ ANX7150_Parse_DTDinExtBlock();
+ ANX7150_Parse_STD();
+ if (!(ANX7150_EDID_Checksum(ANX7150_ext_block_num)))
+ {
+ ANX7150_edid_result.edid_errcode = ANX7150_EDID_CheckSum_ERR;
+ return ANX7150_edid_result.edid_errcode;
+ }
+ }
+ else
+ {
+ ANX7150_edid_result.edid_errcode = ANX7150_EDID_ExtBlock_NotFor_861B;
+ return ANX7150_edid_result.edid_errcode;
+ }
+ }
+
+ return 0;
+}\r
+int ANX7150_Parse_EDID(struct i2c_client *client, struct anx7150_dev_s *dev)\r
+{\r
+ int rc = 0, i;\r
+ char c;\r
+\r
+ if(dev->rk29_output_status == RK29_OUTPUT_STATUS_LCD)\r
+ anx7150_mass_read_need_delay = 1;\r
+ else\r
+ anx7150_mass_read_need_delay = 0;\r
+\r
+ /* Clear HDCP Authentication indicator */\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ ANX7150_hdcp_auth_en = 0;\r
+\r
+\r
+ ANX7150_EDID_Buf = ANX7150_Read_EDID(client);\r
+ \r
+ if(!ANX7150_EDID_Buf){\r
+ ANX7150_edid_result.edid_errcode = ANX7150_EDID_BadHeader;\r
+ dev_err(&client->dev, "READ EDID ERROR\n");\r
+ goto err;\r
+ }\r
+\r
+/*\r
+ if(ANX7150_EDID_Checksum(0) == 0)\r
+ {\r
+ D("EDID Block one check sum error, Stop parsing\n");\r
+ ANX7150_edid_result.edid_errcode = ANX7150_EDID_CheckSum_ERR;\r
+ return ANX7150_edid_result.edid_errcode;\r
+ }\r
+*/\r
+\r
+ //ANX7150_Parse_BasicDis();\r
+ ANX7150_Parse_DTDinBlockONE();\r
+\r
+ if(ANX7150_EDID_Buf[0x7e] == 0)\r
+ {\r
+ hdmi_dbg(&client->dev, "No EDID extension blocks.\n");\r
+ ANX7150_edid_result.edid_errcode = ANX7150_EDID_No_ExtBlock;\r
+ return ANX7150_edid_result.edid_errcode;\r
+ }\r
+ \r
+ ANX7150_Parse_NativeFormat();\r
+ ANX7150_Parse_ExtBlock();\r
+\r
+ if (ANX7150_edid_result.edid_errcode == ANX7150_EDID_ExtBlock_NotFor_861B){\r
+ dev_err(&client->dev,"EDID ExtBlock not support for 861B, Stop parsing\n");\r
+ goto err;\r
+ }\r
+\r
+ if (ANX7150_edid_result.edid_errcode == ANX7150_EDID_CheckSum_ERR){\r
+ dev_err(&client->dev,"EDID Block check sum error, Stop parsing\n");\r
+ goto err;\r
+ }\r
+\r
+ hdmi_dbg(&client->dev,"EDID parsing finished!\n");\r
+\r
+ {\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.edid_errcode = 0x%.2x\n",(u32)ANX7150_edid_result.edid_errcode);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.is_HDMI = 0x%.2x\n",(u32)ANX7150_edid_result.is_HDMI);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.ycbcr422_supported = 0x%.2x\n",(u32)ANX7150_edid_result.ycbcr422_supported);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.ycbcr444_supported = 0x%.2x\n",(u32)ANX7150_edid_result.ycbcr444_supported);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080i_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080i_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080i_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080i_50Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080p_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080p_50Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720p_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720p_50Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_640x480p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_640x480p_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720x480p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720x480p_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720x480i_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720x480i_60Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_576p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_576p_50Hz);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_576i_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_576i_50Hz);\r
+ if (!ANX7150_edid_result.edid_errcode)\r
+ {\r
+ for (i = 0; i < ANX7150_sau_length/3; i++)\r
+ {\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioChannel = 0x%.2x\n",(u32)ANX7150_edid_result.AudioChannel[i]);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioFormat = 0x%.2x\n",(u32)ANX7150_edid_result.AudioFormat[i]);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioFs = 0x%.2x\n",(u32)ANX7150_edid_result.AudioFs[i]);\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioLength = 0x%.2x\n",(u32)ANX7150_edid_result.AudioLength[i]);\r
+ }\r
+ hdmi_dbg(&client->dev,"ANX7150_edid_result.SpeakerFormat = 0x%.2x\n",(u32)ANX7150_edid_result.SpeakerFormat);\r
+ }\r
+ }\r
+ \r
+ ANX7150_parse_edid_done = 1;\r
+ kfree(ANX7150_EDID_Buf);\r
+ ANX7150_EDID_Buf = NULL;\r
+ return 0;\r
+ \r
+err:\r
+ if(ANX7150_EDID_Buf){\r
+ kfree(ANX7150_EDID_Buf);\r
+ ANX7150_EDID_Buf = NULL;\r
+ }\r
+ return ANX7150_edid_result.edid_errcode;\r
+}\r
+int ANX7150_GET_SENSE_STATE(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+\r
+ hdmi_dbg(&client->dev, "enter\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
+\r
+ return (c & ANX7150_SYS_STATE_RSV_DET) ? 1 : 0;\r
+}\r
+int ANX7150_Get_Optimal_resolution(int resolution_set)\r
+{\r
+ int resolution_real;\r
+ int find_resolution = 0;\r
+\r
+ switch(resolution_set){\r
+ case HDMI_1280x720p_50Hz:\r
+ if(ANX7150_edid_result.supported_720p_50Hz){\r
+ resolution_real = HDMI_1280x720p_50Hz;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ if(ANX7150_edid_result.supported_720p_60Hz){\r
+ resolution_real = HDMI_1280x720p_60Hz;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ if(ANX7150_edid_result.supported_576p_50Hz){\r
+ resolution_real = HDMI_720x576p_50Hz_4x3;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ if(ANX7150_edid_result.supported_576p_50Hz){\r
+ resolution_real = HDMI_720x576p_50Hz_16x9;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ if(ANX7150_edid_result.supported_720x480p_60Hz){\r
+ resolution_real = HDMI_720x480p_60Hz_4x3;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ if(ANX7150_edid_result.supported_720x480p_60Hz){\r
+ resolution_real = HDMI_720x480p_60Hz_16x9;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_1920x1080p_50Hz:\r
+ if(ANX7150_edid_result.supported_1080p_50Hz){\r
+ resolution_real = HDMI_1920x1080p_50Hz;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ case HDMI_1920x1080p_60Hz:\r
+ if(ANX7150_edid_result.supported_1080p_60Hz){\r
+ resolution_real = HDMI_1920x1080p_60Hz;\r
+ find_resolution = 1;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if(find_resolution == 0){\r
+\r
+ if(ANX7150_edid_result.supported_720p_50Hz)\r
+ resolution_real = HDMI_1280x720p_50Hz;\r
+ else if(ANX7150_edid_result.supported_720p_60Hz)\r
+ resolution_real = HDMI_1280x720p_60Hz;\r
+ else if(ANX7150_edid_result.supported_576p_50Hz)\r
+ resolution_real = HDMI_720x576p_50Hz_4x3;\r
+ else if(ANX7150_edid_result.supported_720x480p_60Hz)\r
+ resolution_real = HDMI_720x480p_60Hz_4x3;\r
+ else if(ANX7150_edid_result.supported_1080p_50Hz)\r
+ resolution_real = HDMI_1920x1080p_50Hz;\r
+ else if(ANX7150_edid_result.supported_1080p_60Hz)\r
+ resolution_real = HDMI_1920x1080p_60Hz;\r
+ else\r
+ resolution_real = HDMI_1280x720p_50Hz;\r
+ }\r
+\r
+ return resolution_real;\r
+}\r
+void ANX7150_API_HDCP_ONorOFF(u8 HDCP_ONorOFF)\r
+{ \r
+ ANX7150_HDCP_enable = HDCP_ONorOFF;// 1: on; 0:off\r
+}\r
+static void ANX7150_API_Video_Config(u8 video_id,u8 input_pixel_rpt_time)\r
+{
+ ANX7150_video_timing_id = video_id;
+ ANX7150_in_pix_rpt = input_pixel_rpt_time;
+}\r
+static void ANX7150_API_Packets_Config(u8 pkt_sel)\r
+{
+ s_ANX7150_packet_config.packets_need_config = pkt_sel;
+}\r
+static void ANX7150_API_AVI_Config(u8 pb1,u8 pb2,u8 pb3,u8 pb4,u8 pb5,\r
+ u8 pb6,u8 pb7,u8 pb8,u8 pb9,u8 pb10,u8 pb11,u8 pb12,u8 pb13)
+{
+ s_ANX7150_packet_config.avi_info.pb_u8[1] = pb1;
+ s_ANX7150_packet_config.avi_info.pb_u8[2] = pb2;
+ s_ANX7150_packet_config.avi_info.pb_u8[3] = pb3;
+ s_ANX7150_packet_config.avi_info.pb_u8[4] = pb4;
+ s_ANX7150_packet_config.avi_info.pb_u8[5] = pb5;
+ s_ANX7150_packet_config.avi_info.pb_u8[6] = pb6;
+ s_ANX7150_packet_config.avi_info.pb_u8[7] = pb7;
+ s_ANX7150_packet_config.avi_info.pb_u8[8] = pb8;
+ s_ANX7150_packet_config.avi_info.pb_u8[9] = pb9;
+ s_ANX7150_packet_config.avi_info.pb_u8[10] = pb10;
+ s_ANX7150_packet_config.avi_info.pb_u8[11] = pb11;
+ s_ANX7150_packet_config.avi_info.pb_u8[12] = pb12;
+ s_ANX7150_packet_config.avi_info.pb_u8[13] = pb13;
+}\r
+static void ANX7150_API_AUD_INFO_Config(u8 pb1,u8 pb2,u8 pb3,u8 pb4,u8 pb5,\r
+ u8 pb6,u8 pb7,u8 pb8,u8 pb9,u8 pb10)
+{
+ s_ANX7150_packet_config.audio_info.pb_u8[1] = pb1;
+ s_ANX7150_packet_config.audio_info.pb_u8[2] = pb2;
+ s_ANX7150_packet_config.audio_info.pb_u8[3] = pb3;
+ s_ANX7150_packet_config.audio_info.pb_u8[4] = pb4;
+ s_ANX7150_packet_config.audio_info.pb_u8[5] = pb5;
+ s_ANX7150_packet_config.audio_info.pb_u8[6] = pb6;
+ s_ANX7150_packet_config.audio_info.pb_u8[7] = pb7;
+ s_ANX7150_packet_config.audio_info.pb_u8[8] = pb8;
+ s_ANX7150_packet_config.audio_info.pb_u8[9] = pb9;
+ s_ANX7150_packet_config.audio_info.pb_u8[10] = pb10;
+}\r
+static void ANX7150_API_AUD_CHStatus_Config(u8 MODE,u8 PCM_MODE,u8 SW_CPRGT,u8 NON_PCM,\r
+ u8 PROF_APP,u8 CAT_CODE,u8 CH_NUM,u8 SOURCE_NUM,u8 CLK_ACCUR,u8 Fs)
+{
+ //MODE: 0x00 = PCM Audio
+ //PCM_MODE: 0x00 = 2 audio channels without pre-emphasis;
+ //0x01 = 2 audio channels with 50/15 usec pre-emphasis;
+ //SW_CPRGT: 0x00 = copyright is asserted;
+ // 0x01 = copyright is not asserted;
+ //NON_PCM: 0x00 = Represents linear PCM
+ //0x01 = For other purposes
+ //PROF_APP: 0x00 = consumer applications;
+ // 0x01 = professional applications;
+
+ //CAT_CODE: Category code
+ //CH_NUM: 0x00 = Do not take into account
+ // 0x01 = left channel for stereo channel format
+ // 0x02 = right channel for stereo channel format
+ //SOURCE_NUM: source number
+ // 0x00 = Do not take into account
+ // 0x01 = 1; 0x02 = 2; 0x03 = 3
+ //CLK_ACCUR: 0x00 = level II
+ // 0x01 = level I
+ // 0x02 = level III
+ // else reserved;
+
+ s_ANX7150_audio_config.i2s_config.Channel_status1 = (MODE << 7) | (PCM_MODE << 5) |
+ (SW_CPRGT << 2) | (NON_PCM << 1) | PROF_APP;
+ s_ANX7150_audio_config.i2s_config.Channel_status2 = CAT_CODE;
+ s_ANX7150_audio_config.i2s_config.Channel_status3 = (CH_NUM << 7) | SOURCE_NUM;
+ s_ANX7150_audio_config.i2s_config.Channel_status4 = (CLK_ACCUR << 5) | Fs;\r
+}\r
+void ANX7150_API_System_Config(void)\r
+{\r
+ ANX7150_API_Video_Config(g_video_format,input_pixel_clk_1x_repeatition);\r
+ ANX7150_API_Packets_Config(ANX7150_avi_sel | ANX7150_audio_sel);\r
+ if (s_ANX7150_packet_config.packets_need_config & ANX7150_avi_sel)\r
+ ANX7150_API_AVI_Config( 0x00,source_ratio,null,null,null,null,null,null,null,null,null,null,null);\r
+ if (s_ANX7150_packet_config.packets_need_config & ANX7150_audio_sel)\r
+ ANX7150_API_AUD_INFO_Config(null,null,null,null,null,null,null,null,null,null);\r
+ ANX7150_API_AUD_CHStatus_Config(null,null,null,null,null,null,null,null,null,g_audio_format);\r
+\r
+// ANX7150_system_config_done = 1;\r
+}\r
+\r
+static int anx7150_blue_screen_format_config(struct i2c_client *client)\r
+{\r
+ int rc = 0 ;\r
+ char c;\r
+ \r
+ // TODO:Add ITU 601 format.(Now only ITU 709 format added)\r
+ switch (ANX7150_RGBorYCbCr)\r
+ {\r
+ case ANX7150_RGB: //select RGB mode\r
+ c = 0x10;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
+ c = 0xeb;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
+ c = 0x10;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
+ break;\r
+ case ANX7150_YCbCr422: //select YCbCr4:2:2 mode\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
+ c = 0xad;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
+ c = 0x2a;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
+ break;\r
+ case ANX7150_YCbCr444: //select YCbCr4:4:4 mode\r
+ c = 0x1a;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
+ c = 0xad;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
+ c = 0x2a;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ return rc;\r
+}\r
+static void ANX7150_Get_Video_Timing(void)\r
+{\r
+ u8 i;\r
+ \r
+//#ifdef ITU656\r
+ for (i = 0; i < 18; i++)\r
+ {\r
+ switch (ANX7150_video_timing_id)\r
+ {\r
+ case ANX7150_V640x480p_60Hz:\r
+ //D("640x480p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_640x480p_60Hz[i];\r
+ break;\r
+ case ANX7150_V720x480p_60Hz_4x3:\r
+ case ANX7150_V720x480p_60Hz_16x9:\r
+ //D("720x480p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x480p_60Hz[i];\r
+ break;\r
+ case ANX7150_V1280x720p_60Hz:\r
+ //D("1280x720p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1280x720p_60Hz[i];\r
+ break;\r
+ case ANX7150_V1920x1080i_60Hz:\r
+ //D("1920x1080i_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1920x1080i_60Hz[i];\r
+ break;\r
+ case ANX7150_V720x480i_60Hz_4x3:\r
+ case ANX7150_V720x480i_60Hz_16x9:\r
+ //D("720x480i_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x480i_60Hz[i];\r
+ break;\r
+ case ANX7150_V720x576p_50Hz_4x3:\r
+ case ANX7150_V720x576p_50Hz_16x9:\r
+ //D("720x576p_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x576p_50Hz[i];\r
+ break;\r
+ case ANX7150_V1280x720p_50Hz:\r
+ //D("1280x720p_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1280x720p_50Hz[i];\r
+ break;\r
+ case ANX7150_V1920x1080i_50Hz:\r
+ //D("1920x1080i_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1920x1080i_50Hz[i];\r
+ break;\r
+ case ANX7150_V720x576i_50Hz_4x3:\r
+ case ANX7150_V720x576i_50Hz_16x9:\r
+ //D("720x576i_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x576i_50Hz[i];\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ //D("Video_Timing_Parameter[%.2x]=%.2x\n", (u32)i, (u32) ANX7150_video_timing_parameter[i]);\r
+ }\r
+ /*#else\r
+ for(i = 0; i < 18; i++)\r
+ {\r
+ switch(ANX7150_video_timing_id)\r
+ {\r
+ case ANX7150_V640x480p_60Hz:\r
+ //D("640x480p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V720x480p_60Hz_4x3:\r
+ case ANX7150_V720x480p_60Hz_16x9:\r
+ //D("720x480p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 18 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V1280x720p_60Hz:\r
+ //D("1280x720p_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 36 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V1920x1080i_60Hz:\r
+ //D("1920x1080i_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 54 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V720x480i_60Hz_4x3:\r
+ case ANX7150_V720x480i_60Hz_16x9:\r
+ //D("720x480i_60Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 72 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V720x576p_50Hz_4x3:\r
+ case ANX7150_V720x576p_50Hz_16x9:\r
+ //D("720x576p_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 90 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V1280x720p_50Hz:\r
+ //D("1280x720p_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 108 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V1920x1080i_50Hz:\r
+ //D("1920x1080i_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 126 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+ case ANX7150_V720x576i_50Hz_4x3:\r
+ case ANX7150_V720x576i_50Hz_16x9:\r
+ //D("720x576i_50Hz!\n");\r
+ ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 144 + i);\r
+ DRVDelayMs(3);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ //D("Video_Timing_Parameter[%.2x]=%.2x\n", (u32)i, (u32) ANX7150_video_timing_parameter[i]);\r
+ }\r
+ #endif*/\r
+}\r
+static void ANX7150_Parse_Video_Format(void)\r
+{\r
+ switch (ANX7150_video_format_config)\r
+ {\r
+ case ANX7150_RGB_YCrCb444_SepSync:\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ //D("RGB_YCrCb444_SepSync mode!\n");\r
+ break;\r
+ case ANX7150_YCrCb422_SepSync:\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ //D("YCrCb422_SepSync mode!\n");\r
+ break;\r
+ case ANX7150_YCrCb422_EmbSync:\r
+ //D("YCrCb422_EmbSync mode!\n");\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_emb_sync_mode = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ case ANX7150_YCMux422_SepSync_Mode1:\r
+ //D("YCMux422_SepSync_Mode1 mode!\n");\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_ycmux_u8_sel = 0;\r
+ ANX7150_demux_yc_en = 1;\r
+ break;\r
+ case ANX7150_YCMux422_SepSync_Mode2:\r
+ //D("YCMux422_SepSync_Mode2 mode!\n");\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_ycmux_u8_sel = 1;\r
+ ANX7150_demux_yc_en = 1;\r
+ break;\r
+ case ANX7150_YCMux422_EmbSync_Mode1:\r
+ //D("YCMux422_EmbSync_Mode1 mode!\n");\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_emb_sync_mode = 1;\r
+ ANX7150_ycmux_u8_sel = 0;\r
+ ANX7150_demux_yc_en = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ case ANX7150_YCMux422_EmbSync_Mode2:\r
+ //D("YCMux422_EmbSync_Mode2 mode!\n");\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_emb_sync_mode = 1;\r
+ ANX7150_ycmux_u8_sel = 1;\r
+ ANX7150_demux_yc_en = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ case ANX7150_RGB_YCrCb444_DDR_SepSync:\r
+ //D("RGB_YCrCb444_DDR_SepSync mode!\n");\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_ddr_bus_mode = 1;\r
+ break;\r
+ case ANX7150_RGB_YCrCb444_DDR_EmbSync:\r
+ //D("RGB_YCrCb444_DDR_EmbSync mode!\n");\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_de_gen_en = 0;\r
+ ANX7150_emb_sync_mode = 1;\r
+ ANX7150_ddr_bus_mode = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ case ANX7150_RGB_YCrCb444_SepSync_No_DE:\r
+ //D("RGB_YCrCb444_SepSync_No_DE mode!\n");\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ case ANX7150_YCrCb422_SepSync_No_DE:\r
+ //D("YCrCb422_SepSync_No_DE mode!\n");\r
+ ANX7150_emb_sync_mode = 0;\r
+ ANX7150_demux_yc_en = 0;\r
+ ANX7150_ddr_bus_mode = 0;\r
+ ANX7150_de_gen_en = 1;\r
+ ANX7150_Get_Video_Timing();\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+static int anx7150_de_generator(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ u8 video_type,hsync_pol,vsync_pol,v_fp,v_bp,vsync_width;\r
+ u8 hsync_width_low,hsync_width_high,v_active_low,v_active_high;\r
+ u8 h_active_low,h_active_high,h_res_low,h_res_high,h_bp_low,h_bp_high;\r
+ u32 hsync_width,h_active,h_res,h_bp;\r
+\r
+ video_type = ANX7150_video_timing_parameter[15];\r
+ hsync_pol = ANX7150_video_timing_parameter[16];\r
+ vsync_pol = ANX7150_video_timing_parameter[17];\r
+ v_fp = ANX7150_video_timing_parameter[12];\r
+ v_bp = ANX7150_video_timing_parameter[11];\r
+ vsync_width = ANX7150_video_timing_parameter[10];\r
+ hsync_width = ANX7150_video_timing_parameter[5];\r
+ hsync_width = (hsync_width << 8) + ANX7150_video_timing_parameter[4];\r
+ v_active_high = ANX7150_video_timing_parameter[9];\r
+ v_active_low = ANX7150_video_timing_parameter[8];\r
+ h_active = ANX7150_video_timing_parameter[3];\r
+ h_active = (h_active << 8) + ANX7150_video_timing_parameter[2];\r
+ h_res = ANX7150_video_timing_parameter[1];\r
+ h_res = (h_res << 8) + ANX7150_video_timing_parameter[0];\r
+ h_bp = ANX7150_video_timing_parameter[7];\r
+ h_bp = (h_bp << 8) + ANX7150_video_timing_parameter[6];\r
+ if (ANX7150_demux_yc_en)\r
+ {\r
+ hsync_width = 2* hsync_width;\r
+ h_active = 2 * h_active;\r
+ h_res = 2 * h_res;\r
+ h_bp = 2 * h_bp;\r
+ }\r
+ hsync_width_low = hsync_width & 0xff;\r
+ hsync_width_high = (hsync_width >> 8) & 0xff;\r
+ h_active_low = h_active & 0xff;\r
+ h_active_high = (h_active >> 8) & 0xff;\r
+ h_res_low = h_res & 0xff;\r
+ h_res_high = (h_res >> 8) & 0xff;\r
+ h_bp_low = h_bp & 0xff;\r
+ h_bp_high = (h_bp >> 8) & 0xff;\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xf7) | video_type;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xdf) | hsync_pol;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xbf) | vsync_pol;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = v_active_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINEL_REG, &c);\r
+ c = v_active_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINEH_REG, &c);\r
+ c = vsync_width;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_WID_REG, &c);\r
+ c = v_bp;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_TAIL2VIDLINE_REG, &c);\r
+ c = h_active_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_PIXL_REG, &c);\r
+ c = h_active_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_PIXH_REG, &c);\r
+ c = h_res_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_RESL_REG, &c);\r
+ c = h_res_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_RESH_REG, &c);\r
+ c = hsync_width_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHL_REG, &c);\r
+ c = hsync_width_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHH_REG, &c);\r
+ c = h_bp_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_BACKPORCHL_REG, &c);\r
+ c = h_bp_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_BACKPORCHH_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c |= ANX7150_VID_CAPCTRL0_DEGEN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+\r
+ return rc;\r
+}\r
+static int anx7150_embed_sync_decode(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ char c;\r
+ u8 video_type,hsync_pol,vsync_pol,v_fp,vsync_width;\r
+ u8 h_fp_low,h_fp_high,hsync_width_low,hsync_width_high;\r
+ u32 h_fp,hsync_width;\r
+ \r
+ video_type = ANX7150_video_timing_parameter[15];\r
+ hsync_pol = ANX7150_video_timing_parameter[16];\r
+ vsync_pol = ANX7150_video_timing_parameter[17];\r
+ v_fp = ANX7150_video_timing_parameter[12];\r
+ vsync_width = ANX7150_video_timing_parameter[10];\r
+ h_fp = ANX7150_video_timing_parameter[14];\r
+ h_fp = (h_fp << 8) + ANX7150_video_timing_parameter[13];\r
+ hsync_width = ANX7150_video_timing_parameter[5];\r
+ hsync_width = (hsync_width << 8) + ANX7150_video_timing_parameter[4];\r
+ if (ANX7150_demux_yc_en)\r
+ {\r
+ h_fp = 2 * h_fp;\r
+ hsync_width = 2* hsync_width;\r
+ }\r
+ h_fp_low = h_fp & 0xff;\r
+ h_fp_high = (h_fp >> 8) & 0xff;\r
+ hsync_width_low = hsync_width & 0xff;\r
+ hsync_width_high = (hsync_width >> 8) & 0xff;\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xf7) | video_type;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xdf) | hsync_pol;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ c = (c & 0xbf) | vsync_pol;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c = c | ANX7150_VID_CAPCTRL0_EMSYNC_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+\r
+ c = v_fp;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINE2VSYNC_REG, &c);\r
+ c = vsync_width;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_WID_REG, &c);\r
+ c = h_fp_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_FRONTPORCHL_REG, &c);\r
+ c = h_fp_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_FRONTPORCHH_REG, &c);\r
+ c = hsync_width_low;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHL_REG, &c);\r
+ c = hsync_width_high;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHH_REG, &c);\r
+ return rc;\r
+}\r
+int ANX7150_Blue_Screen(struct anx7150_pdata *anx)\r
+{\r
+ return anx7150_blue_screen_format_config(anx->client);\r
+}\r
+//******************************Video Config***************************************\r
+int ANX7150_Config_Video(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ int retry = 0;\r
+ char c,TX_is_HDMI;\r
+ char cspace_y2r, y2r_sel, up_sample,range_y2r;\r
+\r
+ cspace_y2r = 0;\r
+ y2r_sel = 0;\r
+ up_sample = 0;\r
+ range_y2r = 0;\r
+\r
+ //ANX7150_RGBorYCbCr = 0x00; //RGB\r
+ //ANX7150_RGBorYCbCr = ANX7150_INPUT_COLORSPACE; //update\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c &= (~ANX7150_VID_CTRL_u8CTRL_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+/*\r
+ if (!ANX7150_system_config_done)\r
+ {\r
+ D("System has not finished config!\n");\r
+ return;\r
+ }\r
+*/\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
+ if (!(c & 0x02))\r
+ {\r
+ hdmi_dbg(&client->dev, "No clock detected !\n");\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL2_REG, 0x02);\r
+ return -1;\r
+ }\r
+\r
+ rc = anx7150_clean_hdcp(client);\r
+\r
+ //color space issue\r
+ switch (ANX7150_video_timing_id)\r
+ {\r
+ case ANX7150_V1280x720p_50Hz:\r
+ case ANX7150_V1280x720p_60Hz:\r
+ case ANX7150_V1920x1080i_60Hz:\r
+ case ANX7150_V1920x1080i_50Hz:\r
+ case ANX7150_V1920x1080p_60Hz:\r
+ case ANX7150_V1920x1080p_50Hz:\r
+ y2r_sel = ANX7150_CSC_BT709;\r
+ break;\r
+ default:\r
+ y2r_sel = ANX7150_CSC_BT601;\r
+ break;\r
+ }\r
+ //rang[0~255]/[16~235] select\r
+ if (ANX7150_video_timing_id == ANX7150_V640x480p_60Hz)\r
+ range_y2r = 1;//rang[0~255]\r
+ else\r
+ range_y2r = 0;//rang[16~235]\r
+ if ((ANX7150_RGBorYCbCr == ANX7150_YCbCr422) && (!ANX7150_edid_result.ycbcr422_supported))\r
+ {\r
+ up_sample = 1;\r
+ if (ANX7150_edid_result.ycbcr444_supported)\r
+ cspace_y2r = 0;\r
+ else\r
+ cspace_y2r = 1;\r
+ }\r
+ if ((ANX7150_RGBorYCbCr == ANX7150_YCbCr444) && (!ANX7150_edid_result.ycbcr444_supported))\r
+ {\r
+ cspace_y2r = 1;\r
+ }\r
+ //Config the embeded blue screen format according to output video format.\r
+ rc = anx7150_blue_screen_format_config(client);\r
+\r
+ ANX7150_Parse_Video_Format();\r
+\r
+ if (ANX7150_de_gen_en)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_de_gen_en!\n");\r
+ rc = anx7150_de_generator(client);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_DEGEN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ }\r
+ if (ANX7150_emb_sync_mode)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_Embed_Sync_Decode!\n");\r
+ rc = anx7150_embed_sync_decode(client);\r
+ \r
+ if (ANX7150_ddr_bus_mode) //jack wen; for DDR embeded sync\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ c |= (0x04);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ c &= (0xfb);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_EMSYNC_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ }\r
+ if (ANX7150_demux_yc_en)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c |= (ANX7150_VID_CAPCTRL0_DEMUX_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ \r
+ if (ANX7150_ycmux_u8_sel)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_YCu8_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ //jack wen, u8 mapping for yc mux, D3-8,1-0 -->D1-4\r
+ hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!####D1-4\n");\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+\r
+ c = 0x0d;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
+ c = 0x0c;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
+ c = 0x0b;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
+ c = 0x0a;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
+ c = 0x09;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL7, &c);\r
+ c = 0x08;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL6, &c);\r
+ c = 0x01;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL5, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL4, &c);\r
+ //\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c &= (~ANX7150_VID_CTRL_YCu8_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ //jack wen, u8 mapping for yc mux, D3-8,1-0 -->D5-8,\r
+ hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!####D5-8\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ \r
+ c = 0x0d;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL15, &c);\r
+ c = 0x0c;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL14, &c);\r
+ c = 0x0b;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL3, &c);\r
+ c = 0x0a;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL12, &c);\r
+ c = 0x09;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
+ c = 0x08;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
+ c = 0x01;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
+ //\r
+ }\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_DEMUX_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ //jack wen\r
+\r
+ //\r
+\r
+ }\r
+ if (ANX7150_ddr_bus_mode)\r
+ {\r
+ //D("ANX7150_ddr_bus_mode!\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c |= (ANX7150_VID_CAPCTRL0_DV_BUSMODE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ //jack wen\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ c = (c & 0xfc) | 0x02;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_YCu8_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ \r
+ //jack wen\r
+\r
+ if (ANX7150_ddr_edge)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c |= (ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ }\r
+\r
+ //jack wen for DDR+seperate maping\r
+ if (ANX7150_video_format_config == 0x07)//jack wen, DDR yc422, 601,\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_DDR_601_Maping!\n");\r
+ \r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+\r
+ c = 0x0b;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL23, &c);\r
+ c = 0x0a;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL22, &c);\r
+ c = 0x09;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL21, &c);\r
+ c = 0x08;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL20, &c);\r
+ c = 0x07;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL19, &c);\r
+ c = 0x06;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL18, &c);\r
+ c = 0x05;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL17, &c);\r
+ c = 0x04;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL16, &c);\r
+\r
+ c = 0x17;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL15, &c);\r
+ c = 0x16;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL14, &c);\r
+ c = 0x15;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL13, &c);\r
+ c = 0x14;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL12, &c);\r
+ c = 0x13;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
+ c = 0x12;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
+ c = 0x11;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
+ c = 0x10;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
+\r
+ c = 0x03;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL7, &c);\r
+ c = 0x02;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL6, &c);\r
+ c = 0x01;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL5, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL4, &c);\r
+ c = 0x0f;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL3, &c);\r
+ c = 0x0e;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL2, &c);\r
+ c = 0x0d;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL1, &c);\r
+ c = 0x0c;\r
+ rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL0, &c);\r
+\r
+ }\r
+ else if (ANX7150_video_format_config == 0x08)//jack wen, DDR yc422, 656,\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150_DDR_656_Maping!\n");\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c &= (~ANX7150_VID_CTRL_u8CTRL_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_DV_BUSMODE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+ c &= (~ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ c &= (0xfc);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
+ }\r
+\r
+ if (cspace_y2r)\r
+ {\r
+ hdmi_dbg(&client->dev, "Color space Y2R enabled********\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c |= (ANX7150_VID_MODE_CSPACE_Y2R);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ if (y2r_sel)\r
+ {\r
+ hdmi_dbg(&client->dev, "Y2R_SEL!\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c |= (ANX7150_VID_MODE_Y2R_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c &= (~ANX7150_VID_MODE_Y2R_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c); \r
+ }\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c &= (~ANX7150_VID_MODE_CSPACE_Y2R);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+\r
+ if (up_sample)\r
+ {\r
+ hdmi_dbg(&client->dev, "UP_SAMPLE!\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c |= (ANX7150_VID_MODE_UPSAMPLE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c &= (~ANX7150_VID_MODE_UPSAMPLE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+\r
+ if (range_y2r)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c |= (ANX7150_VID_MODE_RANGE_Y2R);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c &= (~ANX7150_VID_MODE_RANGE_Y2R);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ }\r
+\r
+ if (!ANX7150_pix_rpt_set_by_sys)\r
+ {\r
+ if ((ANX7150_video_timing_id == ANX7150_V720x480i_60Hz_16x9)\r
+ || (ANX7150_video_timing_id == ANX7150_V720x576i_50Hz_16x9)\r
+ || (ANX7150_video_timing_id == ANX7150_V720x480i_60Hz_4x3)\r
+ || (ANX7150_video_timing_id == ANX7150_V720x576i_50Hz_4x3))\r
+ ANX7150_tx_pix_rpt = 1;\r
+ else\r
+ ANX7150_tx_pix_rpt = 0;\r
+ }\r
+ //set input pixel repeat times\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ c = ((c & 0xfc) |ANX7150_in_pix_rpt);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
+ //set link pixel repeat times\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c = ((c & 0xfc) |ANX7150_tx_pix_rpt);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+\r
+ if ((ANX7150_in_pix_rpt != ANX7150_in_pix_rpt_bkp)\r
+ ||(ANX7150_tx_pix_rpt != ANX7150_tx_pix_rpt_bkp) )\r
+ {\r
+ c = 0x02;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
+ hdmi_dbg(&client->dev, "MISC_Reset!\n");\r
+ ANX7150_in_pix_rpt_bkp = ANX7150_in_pix_rpt;\r
+ ANX7150_tx_pix_rpt_bkp = ANX7150_tx_pix_rpt;\r
+ }\r
+ //enable video input\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ c |= (ANX7150_VID_CTRL_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
+ //D("Video configure OK!\n");\r
+\r
+ retry = 0;\r
+ do{\r
+ mdelay(60);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_STATUS_REG, &c);\r
+ if (c & ANX7150_VID_STATUS_VID_STABLE){\r
+ hdmi_dbg(&client->dev, "Video stable, continue!\n");\r
+ break;\r
+ }\r
+ else{\r
+ hdmi_dbg(&client->dev,"Video not stable!, retry = %d\n", retry);\r
+ }\r
+ }while(retry++ < 5);\r
+\r
+ if (cspace_y2r)\r
+ ANX7150_RGBorYCbCr = ANX7150_RGB;\r
+ //Enable video CLK,Format change after config video.\r
+ // ANX7150_i2c_read_p0_reg(ANX7150_INTR1_MASK_REG, &c);\r
+ // ANX7150_i2c_write_p0_reg(ANX7150_INTR1_MASK_REG, c |0x01);//3\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
+ c |= (0x48);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
+ c |= (0x40);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
+ \r
+ if (ANX7150_edid_result.is_HDMI)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c |= (0x02);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ hdmi_dbg(&client->dev,"ANX7150 is set to HDMI mode\n");\r
+ }\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ TX_is_HDMI = c & 0x02;\r
+\r
+ if (TX_is_HDMI == 0x02)\r
+ {\r
+ anx7150_set_avmute(client);//wen\r
+ }\r
+\r
+ //reset TMDS link to align 4 channels xy 061120\r
+ hdmi_dbg(&client->dev,"reset TMDS link to align 4 channels\n");\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SRST_REG, &c);\r
+ c |= (ANX7150_TX_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
+ c &= (~ANX7150_TX_RST);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
+ \r
+ //Enable TMDS clock output // just enable u87, and let the other u8s along to avoid overwriting.\r
+ hdmi_dbg(&client->dev,"Enable TMDS clock output\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ c |= (ANX7150_TMDS_CLKCH_MUTE);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
+ if(ANX7150_HDCP_enable)\r
+ mdelay(100); //400ms only for HDCP CTS\r
+\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_VID_MODE_REG, &c); //zy 061110\r
+ return 0;\r
+}\r
+static u8 anx7150_config_i2s(struct i2c_client *client)\r
+{\r
+ int rc;\r
+ char c = 0x00;\r
+ u8 exe_result = 0x00;\r
+ char c1 = 0x00;\r
+\r
+ hdmi_dbg(&client->dev,"ANX7150: config i2s audio.\n");\r
+\r
+ //select SCK as source\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= ~ANX7150_HDMI_AUDCTRL1_CLK_SEL;\r
+ hdmi_dbg(&client->dev,"select SCK as source, c = 0x%.2x\n",(u32)c);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+\r
+ //config i2s channel\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c1 = s_ANX7150_audio_config.i2s_config.audio_channel; // need u8[5:2]\r
+ c1 &= 0x3c;\r
+ c &= ~0x3c;\r
+ c |= c1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ hdmi_dbg(&client->dev,"config i2s channel, c = 0x%.2x\n",(u32)c);\r
+ \r
+ //config i2s format\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_I2S_CTRL_REG, &c);\r
+ c = s_ANX7150_audio_config.i2s_config.i2s_format;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);\r
+ hdmi_dbg(&client->dev,"config i2s format, c = 0x%.2x\n",(u32)c);\r
+\r
+ //map i2s fifo\r
+\r
+ //TODO: config I2S channel map register according to system\r
+\r
+\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_I2SCH_CTRL_REG, c);\r
+\r
+ //swap right/left channel\r
+ /*ANX7150_i2c_read_p0_reg(ANX7150_I2SCH_SWCTRL_REG, &c);\r
+ c1 = 0x00;\r
+ c1 &= 0xf0;\r
+ c &= ~0xf0;\r
+ c |= c1;\r
+ ANX7150_i2c_write_p0_reg(ANX7150_I2SCH_SWCTRL_REG, c);\r
+ D("map i2s ffio, c = 0x%.2x\n",(u32)c);*/\r
+\r
+ //down sample\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c1 = s_ANX7150_audio_config.down_sample;\r
+ c1 &= 0x60;\r
+ c &= ~0x60;\r
+ c |= c1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ hdmi_dbg(&client->dev,"down sample, c = 0x%.2x\n",(u32)c);\r
+\r
+ //config i2s channel status(5 regs)\r
+ c = s_ANX7150_audio_config.i2s_config.Channel_status1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS1_REG, &c);\r
+ c = s_ANX7150_audio_config.i2s_config.Channel_status2;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS2_REG, &c);\r
+ c = s_ANX7150_audio_config.i2s_config.Channel_status3;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS3_REG, &c);\r
+ c = s_ANX7150_audio_config.i2s_config.Channel_status4;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ hdmi_dbg(&client->dev,"@@@@@@@@config i2s channel status4, c = 0x%.2x\n",(unsigned int)c);//jack wen\r
+\r
+ c = s_ANX7150_audio_config.i2s_config.Channel_status5;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS5_REG, &c);\r
+ hdmi_dbg(&client->dev,"config i2s channel status, c = 0x%.2x\n",(u32)c);\r
+\r
+ exe_result = ANX7150_i2s_input;\r
+ //D("return = 0x%.2x\n",(u32)exe_result);\r
+\r
+ // open corresponding interrupt\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_INTR1_MASK_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_INTR1_MASK_REG, (c | 0x22) );\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_INTR3_MASK_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_INTR3_MASK_REG, (c | 0x20) );\r
+\r
+\r
+ return exe_result;\r
+}\r
+\r
+static u8 anx7150_config_spdif(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 exe_result = 0x00;\r
+ char c = 0x00;\r
+ char c1 = 0x00;\r
+ // u8 c2 = 0x00;\r
+ // u8 freq_mclk = 0x00;\r
+\r
+ hdmi_dbg(&client->dev, "ANX7150: config SPDIF audio.\n");\r
+\r
+\r
+ //Select MCLK\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= (ANX7150_HDMI_AUDCTRL1_CLK_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ //D("ANX7150: enable SPDIF audio.\n");\r
+ //Enable SPDIF\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= (ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ //adjust MCLK phase in interrupt routine\r
+\r
+ // adjust FS_FREQ //FS_FREQ\r
+ c1 = s_ANX7150_audio_config.i2s_config.Channel_status4 & 0x0f;\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SPDIFCH_STATUS_REG, &c);\r
+ c &= ANX7150_SPDIFCH_STATUS_FS_FREG;\r
+ c = c >> 4;\r
+\r
+ if ( c != c1)\r
+ {\r
+ //D("adjust FS_FREQ by system!\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ c &= 0xf0;\r
+ c |= c1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+\r
+ //enable using FS_FREQ from 0x59\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= (0x02);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+\r
+ // down sample\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c1 = s_ANX7150_audio_config.down_sample;\r
+ c1 &= 0x60;\r
+ c &= ~0x60;\r
+ c |= c1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+\r
+ if (s_ANX7150_audio_config.down_sample) //zy 060816\r
+ {\r
+ // adjust FS_FREQ by system because down sample\r
+ //D("adjust FS_FREQ by system because down sample!\n");\r
+\r
+ c1 = s_ANX7150_audio_config.i2s_config.Channel_status4 & 0x0f;\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ \r
+ c &= 0xf0;\r
+ c |= c1;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ }\r
+\r
+\r
+ // spdif is stable\r
+ hdmi_dbg(&client->dev, "config SPDIF audio done");\r
+ exe_result = ANX7150_spdif_input;\r
+\r
+ // open corresponding interrupt\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
+ c |= (0x32);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_INTR3_MASK_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_INTR3_MASK_REG, (c | 0xa1) );\r
+ return exe_result;\r
+}\r
+\r
+static u8 anx7150_config_super_audio(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 exe_result = 0x00;\r
+ u8 c = 0x00;\r
+\r
+\r
+ //D("ANX7150: config one u8 audio.\n");\r
+\r
+ // select sck as source\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= (~ANX7150_HDMI_AUDCTRL1_CLK_SEL);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+\r
+ // Enable stream 0x60\r
+ c = s_ANX7150_audio_config.super_audio_config.one_u8_ctrl;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
+\r
+\r
+ // Map stream 0x61\r
+ // TODO: config super audio map register according to system\r
+\r
+ exe_result = ANX7150_super_audio_input;\r
+ return exe_result;\r
+\r
+}\r
+\r
+u8 ANX7150_Config_Audio(struct i2c_client *client)\r
+{\r
+ int rc;\r
+ char c = 0x00;\r
+ u8 exe_result = 0x00;\r
+ u8 audio_layout = 0x00;\r
+ u8 fs = 0x00;\r
+ u32 ACR_N = 0x0000;\r
+\r
+ //set audio clock edge\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c = ((c & 0xf7) | ANX7150_audio_clock_edge);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ \r
+ //cts get select from SCK\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c = (c & 0xef);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ hdmi_dbg(&client->dev, "audio_type = 0x%.2x\n",(u32)s_ANX7150_audio_config.audio_type);\r
+ if (s_ANX7150_audio_config.audio_type & ANX7150_i2s_input)\r
+ {\r
+ hdmi_dbg(&client->dev, "Config I2s.\n");\r
+ exe_result |= anx7150_config_i2s(client);\r
+ }\r
+ else\r
+ {\r
+ //disable I2S audio input\r
+ hdmi_dbg(&client->dev, "Disable I2S audio input.\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= 0xc3;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+\r
+ if (s_ANX7150_audio_config.audio_type & ANX7150_spdif_input)\r
+ {\r
+ exe_result |= anx7150_config_spdif(client);\r
+ }\r
+ else\r
+ {\r
+ //disable SPDIF audio input\r
+ hdmi_dbg(&client->dev, "Disable SPDIF audio input.\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= ~ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+\r
+ if (s_ANX7150_audio_config.audio_type & ANX7150_super_audio_input)\r
+ {\r
+ exe_result |= anx7150_config_super_audio(client);\r
+ }\r
+ else\r
+ {\r
+ //disable super audio output\r
+ hdmi_dbg(&client->dev, "ANX7150: disable super audio output.\n");\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
+ }\r
+\r
+ if ((s_ANX7150_audio_config.audio_type & 0x07) == 0x00)\r
+ {\r
+ hdmi_dbg(&client->dev, "ANX7150 input no audio type.\n");\r
+ }\r
+\r
+ //audio layout\r
+ if (s_ANX7150_audio_config.audio_type & ANX7150_i2s_input)\r
+ {\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ audio_layout = s_ANX7150_audio_config.audio_layout;\r
+\r
+ //HDMI_RX_ReadI2C_RX0(0x15, &c);\r
+#if 0\r
+ if ((c & 0x08) ==0x08 ) //u8[5:3]\r
+ {\r
+ audio_layout = 0x80;\r
+ }\r
+ else\r
+ {\r
+ audio_layout = 0x00;\r
+ }\r
+#endif\r
+ }\r
+ if (s_ANX7150_audio_config.audio_type & ANX7150_super_audio_input)\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
+ if ( c & 0xfc) //u8[5:3]\r
+ {\r
+ audio_layout = 0x80;\r
+ }\r
+ }\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c &= ~0x80;\r
+ c |= audio_layout;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+\r
+ if ( (s_ANX7150_audio_config.audio_type & 0x07) == exe_result )\r
+ {\r
+ //Initial N value\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ fs = c & 0x0f;\r
+ // set default value to N\r
+ ACR_N = ANX7150_N_48k;\r
+ switch (fs)\r
+ {\r
+ case(0x00)://44.1k\r
+ ACR_N = ANX7150_N_44k;\r
+ break;\r
+ case(0x02)://48k\r
+ ACR_N = ANX7150_N_48k;\r
+ break;\r
+ case(0x03)://32k\r
+ ACR_N = ANX7150_N_32k;\r
+ break;\r
+ case(0x08)://88k\r
+ ACR_N = ANX7150_N_88k;\r
+ break;\r
+ case(0x0a)://96k\r
+ ACR_N = ANX7150_N_96k;\r
+ break;\r
+ case(0x0c)://176k\r
+ ACR_N = ANX7150_N_176k;\r
+ break;\r
+ case(0x0e)://192k\r
+ ACR_N = ANX7150_N_192k;\r
+ break;\r
+ default:\r
+ dev_err(&client->dev, "note wrong fs.\n");\r
+ break;\r
+ }\r
+ // write N(ACR) to corresponding regs\r
+ c = ACR_N;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N1_SW_REG, &c);\r
+ c = ACR_N>>8;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N2_SW_REG, &c);\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N3_SW_REG, &c);\r
+ \r
+ // set the relation of MCLK and Fs xy 070117\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c = (c & 0xf8) | FREQ_MCLK;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ hdmi_dbg(&client->dev, "Audio MCLK input mode is: %.2x\n",(u32)FREQ_MCLK);\r
+\r
+ //Enable control of ACR\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c |= (ANX7150_INFO_PKTCTRL1_ACR_EN);\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ //audio enable:\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= (ANX7150_HDMI_AUDCTRL1_IN_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+\r
+ return exe_result;\r
+\r
+}\r
+static u8 ANX7150_Checksum(infoframe_struct *p)\r
+{
+ u8 checksum = 0x00;
+ u8 i;
+
+ checksum = p->type + p->length + p->version;
+ for (i=1; i <= p->length; i++)
+ {
+ checksum += p->pb_u8[i];
+ }
+ checksum = ~checksum;
+ checksum += 0x01;
+
+ return checksum;
+}\r
+static u8 anx7150_load_infoframe(struct i2c_client *client, packet_type member,\r
+ infoframe_struct *p)\r
+{\r
+ int rc = 0;\r
+ u8 exe_result = 0x00;\r
+ u8 address[8] = {0x00,0x20,0x40,0x60,0x80,0x80,0xa0,0xa0};\r
+ u8 i;\r
+ char c;\r
+\r
+ p->pb_u8[0] = ANX7150_Checksum(p);\r
+\r
+ // write infoframe to according regs\r
+ c = p->type;\r
+ rc = anx7150_i2c_write_p1_reg(client, address[member], &c);\r
+ c = p->version;\r
+ rc = anx7150_i2c_write_p1_reg(client, address[member]+1, &c);\r
+ c = p->length;\r
+ rc = anx7150_i2c_write_p1_reg(client, address[member]+2, &c);\r
+\r
+ for (i=0; i <= p->length; i++)\r
+ {\r
+ c = p->pb_u8[i];\r
+ rc = anx7150_i2c_write_p1_reg(client, address[member]+3+i, &c);\r
+ rc = anx7150_i2c_read_p1_reg(client, address[member]+3+i, &c);\r
+ }\r
+ return exe_result;\r
+}\r
+\r
+//*************** Config Packet ****************************\r
+u8 ANX7150_Config_Packet(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 exe_result = 0x00; // There is no use in current solution\r
+ u8 info_packet_sel;\r
+ char c;\r
+\r
+ info_packet_sel = s_ANX7150_packet_config.packets_need_config;\r
+ hdmi_dbg(&client->dev, "info_packet_sel = 0x%.2x\n",(u32) info_packet_sel);\r
+ // New packet?\r
+ if ( info_packet_sel != 0x00)\r
+ {\r
+ // avi infoframe\r
+ if ( info_packet_sel & ANX7150_avi_sel )\r
+ {\r
+ c = s_ANX7150_packet_config.avi_info.pb_u8[1]; //color space\r
+ c &= 0x9f;\r
+ c |= (ANX7150_RGBorYCbCr << 5);\r
+ s_ANX7150_packet_config.avi_info.pb_u8[1] = c | 0x10;\r
+ switch(ANX7150_video_timing_id) \r
+ {\r
+ case ANX7150_V720x480p_60Hz_4x3:\r
+ case ANX7150_V720x480p_60Hz_16x9:\r
+ case ANX7150_V720x576p_50Hz_4x3:\r
+ case ANX7150_V720x576p_50Hz_16x9:\r
+ s_ANX7150_packet_config.avi_info.pb_u8[2] = 0x58;\r
+ break;\r
+ case ANX7150_V1280x720p_50Hz:\r
+ case ANX7150_V1280x720p_60Hz:\r
+ case ANX7150_V1920x1080p_50Hz:\r
+ case ANX7150_V1920x1080p_60Hz:\r
+ s_ANX7150_packet_config.avi_info.pb_u8[2] = 0xa8;\r
+ break;\r
+ default:\r
+ s_ANX7150_packet_config.avi_info.pb_u8[2] = 0xa8;\r
+ break;\r
+ }\r
+\r
+ c = s_ANX7150_packet_config.avi_info.pb_u8[4];// vid ID\r
+ c = c & 0x80;\r
+ s_ANX7150_packet_config.avi_info.pb_u8[4] = c | ANX7150_video_timing_id;\r
+ c = s_ANX7150_packet_config.avi_info.pb_u8[5]; //repeat times\r
+ c = c & 0xf0;\r
+ c |= (ANX7150_tx_pix_rpt & 0x0f);\r
+ s_ANX7150_packet_config.avi_info.pb_u8[5] = c;\r
+ hdmi_dbg(&client->dev, "config avi infoframe packet.\n");\r
+ // Disable repeater\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL1_AVI_RPT;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+\r
+ // Enable?wait:go\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ if (c & ANX7150_INFO_PKTCTRL1_AVI_EN)\r
+ {\r
+ //D("wait disable, config avi infoframe packet.\n");\r
+ return exe_result; //jack wen\r
+ }\r
+\r
+ // load packet data to regs\r
+ rc = anx7150_load_infoframe(client, ANX7150_avi_infoframe,\r
+ &(s_ANX7150_packet_config.avi_info));\r
+ // Enable and repeater\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c |= 0x30;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
+\r
+ // complete avi packet\r
+ hdmi_dbg(&client->dev, "config avi infoframe packet done.\n");\r
+ s_ANX7150_packet_config.packets_need_config &= ~ANX7150_avi_sel;\r
+\r
+ }\r
+\r
+ // audio infoframe\r
+ if ( info_packet_sel & ANX7150_audio_sel )\r
+ {\r
+ hdmi_dbg(&client->dev, "config audio infoframe packet.\n");\r
+\r
+ // Disable repeater\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_AIF_RPT;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+\r
+ // Enable?wait:go\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if (c & ANX7150_INFO_PKTCTRL2_AIF_EN)\r
+ {\r
+ //D("wait disable, config audio infoframe packet.\n");\r
+ //return exe_result;//jack wen\r
+ }\r
+ // config packet\r
+\r
+ // load packet data to regs\r
+ \r
+ anx7150_load_infoframe( client, ANX7150_audio_infoframe,\r
+ &(s_ANX7150_packet_config.audio_info));\r
+ // Enable and repeater\r
+ rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0x03;\r
+ rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
+\r
+ // complete avi packet\r
+\r
+ hdmi_dbg(&client->dev, "config audio infoframe packet done.\n");\r
+ s_ANX7150_packet_config.packets_need_config &= ~ANX7150_audio_sel;\r
+\r
+ }\r
+\r
+ // config other 4 packets\r
+ /*\r
+\r
+ if( info_packet_sel & 0xfc )\r
+ {\r
+ D("other packets.\n");\r
+\r
+ //find the current type need config\r
+ if(info_packet_sel & ANX7150_spd_sel) type_sel = ANX7150_spd_sel;\r
+ else if(info_packet_sel & ANX7150_mpeg_sel) type_sel = ANX7150_mpeg_sel;\r
+ else if(info_packet_sel & ANX7150_acp_sel) type_sel = ANX7150_acp_sel;\r
+ else if(info_packet_sel & ANX7150_isrc1_sel) type_sel = ANX7150_isrc1_sel;\r
+ else if(info_packet_sel & ANX7150_isrc2_sel) type_sel = ANX7150_isrc2_sel;\r
+ else type_sel = ANX7150_vendor_sel;\r
+\r
+\r
+ // Disable repeater\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_AIF_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+\r
+ switch(type_sel)\r
+ {\r
+ case ANX7150_spd_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL1_SPD_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL1_REG, c);\r
+\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL1_SPD_EN)\r
+ {\r
+ D("wait disable, config spd infoframe packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ case ANX7150_mpeg_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_MPEG_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL2_MPEG_EN)\r
+ {\r
+ D("wait disable, config mpeg infoframe packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ case ANX7150_acp_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_UD0_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL2_UD0_EN)\r
+ {\r
+ D("wait disable, config mpeg infoframe packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ case ANX7150_isrc1_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_UD0_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL2_UD0_EN)\r
+ {\r
+ D("wait disable, config isrc1 packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ case ANX7150_isrc2_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_UD_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL2_UD_EN)\r
+ {\r
+ D("wait disable, config isrc2 packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ case ANX7150_vendor_sel:\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c &= ~ANX7150_INFO_PKTCTRL2_UD_RPT;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ if(c & ANX7150_INFO_PKTCTRL2_UD_EN)\r
+ {\r
+ D("wait disable, config vendor packet.\n");\r
+ return exe_result;\r
+ }\r
+ break;\r
+\r
+ default : break;\r
+ }\r
+\r
+\r
+ // config packet\r
+ // TODO: config packet in top level\r
+\r
+ // load packet data to regs\r
+ switch(type_sel)\r
+ {\r
+ case ANX7150_spd_sel:\r
+ ANX7150_Load_Infoframe( ANX7150_spd_infoframe,\r
+ &(s_ANX7150_packet_config.spd_info));\r
+ D("config spd done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
+ c |= 0xc0;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL1_REG, c);\r
+ break;\r
+\r
+ case ANX7150_mpeg_sel:\r
+ ANX7150_Load_Infoframe( ANX7150_mpeg_infoframe,\r
+ &(s_ANX7150_packet_config.mpeg_info));\r
+ D("config mpeg done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0x0c;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ break;\r
+\r
+ case ANX7150_acp_sel:\r
+ ANX7150_Load_Packet( ANX7150_acp_packet,\r
+ &(s_ANX7150_packet_config.acp_pkt));\r
+ D("config acp done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0x30;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ break;\r
+\r
+ case ANX7150_isrc1_sel:\r
+ ANX7150_Load_Packet( ANX7150_isrc1_packet,\r
+ &(s_ANX7150_packet_config.acp_pkt));\r
+ D("config isrc1 done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0x30;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ break;\r
+\r
+ case ANX7150_isrc2_sel:\r
+ ANX7150_Load_Packet( ANX7150_isrc2_packet,\r
+ &(s_ANX7150_packet_config.acp_pkt));\r
+ D("config isrc2 done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0xc0;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ break;\r
+\r
+ case ANX7150_vendor_sel:\r
+ ANX7150_Load_Infoframe( ANX7150_vendor_infoframe,\r
+ &(s_ANX7150_packet_config.vendor_info));\r
+ D("config vendor done.\n");\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0xc0;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+ break;\r
+\r
+ default : break;\r
+ }\r
+\r
+ // Enable and repeater\r
+ ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
+ c |= 0x03;\r
+ ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
+\r
+ // complete config packet\r
+ D("config other packets done.\n");\r
+ s_ANX7150_packet_config.packets_need_config &= ~type_sel;\r
+\r
+ }\r
+ */\r
+ }\r
+\r
+\r
+ if ( s_ANX7150_packet_config.packets_need_config == 0x00)\r
+ {\r
+ hdmi_dbg(&client->dev, "config packets done\n");\r
+ //ANX7150_Set_System_State(ANX7150_HDCP_AUTHENTICATION);\r
+ }\r
+\r
+\r
+ return exe_result;\r
+}\r
+//******************** HDCP process ********************************\r
+static int anx7150_hardware_hdcp_auth_init(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ u8 c;\r
+\r
+// ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c); //72:07.2 hdcp on\r
+// ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, (c | ANX7150_SYS_CTRL1_HDCPMODE));\r
+ // disable hw hdcp\r
+// ANX7150_i2c_read_p0_reg(ANX7150_HDCP_CTRL0_REG, &c);\r
+// ANX7150_i2c_write_p0_reg(ANX7150_HDCP_CTRL0_REG, (c & (~ANX7150_HDCP_CTRL0_HW_AUTHEN)));\r
+\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_HDCP_CTRL0_REG, 0x03); //h/w auth off, jh simplay/hdcp\r
+ c = 0x00;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c); //bit 0/1 off, as from start, we don't know if Bksv/srm/KSVList valid or not. SY.\r
+\r
+ // DDC reset\r
+ rc = anx7150_rst_ddcchannel(client);\r
+\r
+ anx7150_initddc_read(client, 0x74, 0x00, 0x40, 0x01, 0x00);\r
+ mdelay(5);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bcaps);\r
+ hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): ANX7150_hdcp_bcaps = 0x%.2x\n", (u32)ANX7150_hdcp_bcaps);\r
+\r
+ if (ANX7150_hdcp_bcaps & 0x02)\r
+ { //enable 1.1 feature\r
+ hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps supports 1.1\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ c |= ANX7150_HDCP_CTRL1_HDCP11_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ }\r
+ else\r
+ { //disable 1.1 feature and enable HDCP two special point check\r
+ hdmi_dbg(&client->dev, "bcaps don't support 1.1\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ c = ((c & (~ANX7150_HDCP_CTRL1_HDCP11_EN)) | ANX7150_LINK_CHK_12_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ }\r
+ //handle repeater bit. SY.\r
+ if (ANX7150_hdcp_bcaps & 0x40)\r
+ {\r
+ //repeater\r
+ hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps shows Sink is a repeater\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c |= ANX7150_HDCP_CTRL0_RX_REP;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ }\r
+ else\r
+ {\r
+ //receiver\r
+ hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps shows Sink is a receiver\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= ~ANX7150_HDCP_CTRL0_RX_REP;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ }\r
+ anx7150_rst_ddcchannel(client);\r
+ ANX7150_hdcp_auth_en = 0;\r
+\r
+ return rc;\r
+}\r
+static u8 anx7150_bksv_srm(struct i2c_client *client)\r
+{
+ int rc = 0;\r
+#if 1
+ u8 bksv[5],i,bksv_one,c1;
+ anx7150_initddc_read(client, 0x74, 0x00, 0x00, 0x05, 0x00);\r
+ mdelay(15);\r
+ for (i = 0; i < 5; i ++)
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &bksv[i]);\r
+ }
+
+ bksv_one = 0;
+ for (i = 0; i < 8; i++)
+ {
+ c1 = 0x01 << i;
+ if (bksv[0] & c1)
+ bksv_one ++;
+ if (bksv[1] & c1)
+ bksv_one ++;
+ if (bksv[2] & c1)
+ bksv_one ++;
+ if (bksv[3] & c1)
+ bksv_one ++;
+ if (bksv[4] & c1)
+ bksv_one ++;
+ }
+ //wen HDCP CTS
+ if (bksv_one != 20)
+ {
+ hdmi_dbg(&client->dev, "BKSV check fail\n");\r
+ return 0;
+ }
+ else
+ {
+ hdmi_dbg(&client->dev, "BKSV check OK\n");\r
+ return 1;
+ }
+#endif
+
+#if 0 //wen HDCP CTS
+ /*address by gerard.zhu*/
+ u8 i,j,bksv_ones_count,bksv_data[Bksv_Data_Nums] = {0};
+ ANX7150_DDC_Addr bksv_ddc_addr;
+ u32 bksv_length;
+ ANX7150_DDC_Type ddc_type;
+
+ i = 0;
+ j = 0;
+ bksv_ones_count = 0;
+ bksv_ddc_addr.dev_addr = HDCP_Dev_Addr;
+ bksv_ddc_addr.sgmt_addr = 0;
+ bksv_ddc_addr.offset_addr = HDCP_Bksv_Offset;
+ bksv_length = Bksv_Data_Nums;
+ ddc_type = DDC_Hdcp;
+
+ if (!ANX7150_DDC_Read(bksv_ddc_addr, bksv_data, bksv_length, ddc_type))
+ {
+ /*Judge validity for Bksv*/
+ while (i < Bksv_Data_Nums)
+ {
+ while (j < 8)
+ {
+ if (((bksv_data[i] >> j) & 0x01) == 1)
+ {
+ bksv_ones_count++;
+ }
+ j++;
+ }
+ i++;
+ j = 0;
+ }
+ if (bksv_ones_count != 20)
+ {
+ rk29printk ("!!!!BKSV 1s ¡Ù20\n"); //update rk29printk ("!!!!BKSV 1s ¡Ù20\n");
+ return 0;
+ }
+ }
+ /*end*/
+
+ D("bksv is ready.\n");
+ // TODO: Compare the bskv[] value to the revocation list to decide if this value is a illegal BKSV. This is system depended.
+ //If illegal, return 0; legal, return 1. Now just return 1
+ return 1;
+#endif
+}\r
+\r
+static u8 anx7150_is_ksvlist_vld(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+//wen HDCP CTS\r
+#if 1\r
+ hdmi_dbg(&client->dev, "ANX7150_IS_KSVList_VLD() is called.\n");\r
+ anx7150_initddc_read(client, 0x74, 0x00, 0x41, 0x02, 0x00); //Bstatus, two u8s\r
+ mdelay(5);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bstatus[0]);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bstatus[1]);\r
+\r
+ if ((ANX7150_hdcp_bstatus[0] & 0x80) | (ANX7150_hdcp_bstatus[1] & 0x08))\r
+ {\r
+ hdmi_dbg(&client->dev, "Max dev/cascade exceeded: ANX7150_hdcp_bstatus[0]: 0x%x,ANX7150_hdcp_bstatus[1]:0x%x\n", (u32)ANX7150_hdcp_bstatus[0],(u32)ANX7150_hdcp_bstatus[1]);\r
+ return 0;//HDCP topology error. More than 127 RX are attached or more than seven levels of repeater are cascaded.\r
+ }\r
+ return 1;\r
+#endif\r
+//wen HDCP CTS\r
+\r
+}\r
+\r
+static void anx7150_show_video_parameter(struct i2c_client *client)\r
+{\r
+ int rc = 0;\r
+ // int h_res,h_act,v_res,v_act,h_fp,hsync_width,h_bp;\r
+ char c, c1;\r
+\r
+ hdmi_dbg(&client->dev, "\n\n**********************************ANX7150 Info**********************************\n");\r
+\r
+ hdmi_dbg(&client->dev, " ANX7150 mode = Normal mode\n");\r
+ if ((ANX7150_demux_yc_en == 1) && (ANX7150_emb_sync_mode == 0))\r
+ hdmi_dbg(&client->dev, " Input video format = YC_MUX\n");\r
+ if ((ANX7150_demux_yc_en == 0) && (ANX7150_emb_sync_mode == 1))\r
+ hdmi_dbg(&client->dev, " Input video format = 656\n");\r
+ if ((ANX7150_demux_yc_en == 1) && (ANX7150_emb_sync_mode == 1))\r
+ hdmi_dbg(&client->dev, " Input video format = YC_MUX + 656\n");\r
+ if ((ANX7150_demux_yc_en == 0) && (ANX7150_emb_sync_mode == 0))\r
+ hdmi_dbg(&client->dev, " Input video format = Seperate Sync\n");\r
+ if (ANX7150_de_gen_en)\r
+ hdmi_dbg(&client->dev, " DE generator = Enable\n");\r
+ else\r
+ hdmi_dbg(&client->dev, " DE generator = Disable\n");\r
+ if ((ANX7150_ddr_bus_mode == 1)&& (ANX7150_emb_sync_mode == 0))\r
+ hdmi_dbg(&client->dev, " Input video format = DDR mode\n");\r
+ else if ((ANX7150_ddr_bus_mode == 1)&& (ANX7150_emb_sync_mode == 1))\r
+ hdmi_dbg(&client->dev, " Input video format = DDR mode + 656\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c1);\r
+ c1 = (c1 & 0x02);\r
+ if (c1)\r
+ {\r
+ hdmi_dbg(&client->dev, " Output video mode = HDMI\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, 0x04, &c);\r
+ c = (c & 0x60) >> 5;\r
+ switch (c)\r
+ {\r
+ case ANX7150_RGB:\r
+ hdmi_dbg(&client->dev, " Output video color format = RGB\n");\r
+ break;\r
+ case ANX7150_YCbCr422:\r
+ hdmi_dbg(&client->dev, " Output video color format = YCbCr422\n");\r
+ break;\r
+ case ANX7150_YCbCr444:\r
+ hdmi_dbg(&client->dev, " Output video color format = YCbCr444\n");\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ hdmi_dbg(&client->dev, " Output video mode = DVI\n");\r
+ hdmi_dbg(&client->dev, " Output video color format = RGB\n");\r
+ }\r
+\r
+ /*for(i = 0x10; i < 0x25; i ++)\r
+ {\r
+ ANX7150_i2c_read_p0_reg(i, &c );\r
+ D("0x%.2x = 0x%.2x\n",(unsigned int)i,(unsigned int)c);\r
+ }*/\r
+ /* ANX7150_i2c_read_p0_reg(ANX7150_VID_STATUS_REG, &c);\r
+ if((c & ANX7150_VID_STATUS_TYPE) == 0x04)\r
+ D("Video Type = Interlace");\r
+ else\r
+ D("Video Type = Progressive");\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HRESH_REG, &c);\r
+ h_res = c;\r
+ h_res = h_res << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HRESL_REG, &c);\r
+ h_res = h_res + c;\r
+ D("H_resolution = %u\n",h_res);\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_PIXH_REG, &c);\r
+ h_act = c;\r
+ h_act = h_act << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_PIXL_REG, &c);\r
+ h_act = h_act + c;\r
+ D("H_active = %u\n",h_act);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VRESH_REG, &c);\r
+ v_res = c;\r
+ v_res = v_res << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VRESL_REG, &c);\r
+ v_res = v_res + c;\r
+ D("V_resolution = %u\n",v_res);\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTVIDLINEH_REG, &c);\r
+ v_act = c;\r
+ v_act = v_act << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTVIDLINEL_REG, &c);\r
+ v_act = v_act + c;\r
+ D("V_active = %u\n",v_act);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HFORNTPORCHH_REG, &c);\r
+ h_fp = c;\r
+ h_fp = h_fp << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HFORNTPORCHL_REG, &c);\r
+ h_fp = h_fp + c;\r
+ D("H_FP = %u\n",h_fp);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HBACKPORCHH_REG, &c);\r
+ h_bp = c;\r
+ h_bp = h_bp << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HBACKPORCHL_REG, &c);\r
+ h_bp = h_bp + c;\r
+ D("H_BP = %u\n",h_bp);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HSYNCWIDH_REG, &c);\r
+ hsync_width = c;\r
+ hsync_width = hsync_width << 8;\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HSYNCWIDL_REG, &c);\r
+ hsync_width = hsync_width + c;\r
+ D("Hsync_width = %u\n",hsync_width);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTLINE2VSYNC_REG, &c);\r
+ D("Vsync_FP = %bu\n",c);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VSYNCTAIL2VIDLINE_REG, &c);\r
+ D("Vsync_BP = %bu\n",c);\r
+\r
+ ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VSYNCWIDLINE_REG, &c);\r
+ D("Vsync_width = %bu\n",c);*/\r
+ {\r
+ hdmi_dbg(&client->dev, " Normal mode output video format: \n");\r
+ switch (ANX7150_video_timing_id)\r
+ {\r
+ case ANX7150_V720x480p_60Hz_4x3:\r
+ case ANX7150_V720x480p_60Hz_16x9:\r
+ hdmi_dbg(&client->dev, "720x480p@60\n");\r
+ if (ANX7150_edid_result.supported_720x480p_60Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1280x720p_60Hz:\r
+ hdmi_dbg(&client->dev, "1280x720p@60\n");\r
+ if (ANX7150_edid_result.supported_720p_60Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1920x1080i_60Hz:\r
+ hdmi_dbg(&client->dev, "1920x1080i@60\n");\r
+ if (ANX7150_edid_result.supported_1080i_60Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1920x1080p_60Hz:\r
+ hdmi_dbg(&client->dev, "1920x1080p@60\n");\r
+ if (ANX7150_edid_result.supported_1080p_60Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1920x1080p_50Hz:\r
+ hdmi_dbg(&client->dev, "1920x1080p@50\n");\r
+ if (ANX7150_edid_result.supported_1080p_50Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1280x720p_50Hz:\r
+ hdmi_dbg(&client->dev, "1280x720p@50\n");\r
+ if (ANX7150_edid_result.supported_720p_50Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V1920x1080i_50Hz:\r
+ hdmi_dbg(&client->dev, "1920x1080i@50\n");\r
+ if (ANX7150_edid_result.supported_1080i_50Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V720x576p_50Hz_4x3:\r
+ case ANX7150_V720x576p_50Hz_16x9:\r
+ hdmi_dbg(&client->dev, "720x576p@50\n");\r
+ if (ANX7150_edid_result.supported_576p_50Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V720x576i_50Hz_4x3:\r
+ case ANX7150_V720x576i_50Hz_16x9:\r
+ hdmi_dbg(&client->dev, "720x576i@50\n");\r
+ if (ANX7150_edid_result.supported_576i_50Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ case ANX7150_V720x480i_60Hz_4x3:\r
+ case ANX7150_V720x480i_60Hz_16x9:\r
+ hdmi_dbg(&client->dev, "720x480i@60\n");\r
+ if (ANX7150_edid_result.supported_720x480i_60Hz)\r
+ hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
+ break;\r
+ default:\r
+ hdmi_dbg(&client->dev, "unknown(video ID is: %.2x).\n",(u32)ANX7150_video_timing_id);\r
+ break;\r
+ }\r
+ }\r
+ if (c1)//HDMI output\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
+ c = c & 0x03;\r
+ hdmi_dbg(&client->dev, " MCLK Frequence = ");\r
+\r
+ switch (c)\r
+ {\r
+ case 0x00:\r
+ hdmi_dbg(&client->dev, "128 * Fs.\n");\r
+ break;\r
+ case 0x01:\r
+ hdmi_dbg(&client->dev, "256 * Fs.\n");\r
+ break;\r
+ case 0x02:\r
+ hdmi_dbg(&client->dev, "384 * Fs.\n");\r
+ break;\r
+ case 0x03:\r
+ hdmi_dbg(&client->dev, "512 * Fs.\n");\r
+ break;\r
+ default :\r
+ hdmi_dbg(&client->dev, "Wrong MCLK output.\n");\r
+ break;\r
+ }\r
+\r
+ if ( ANX7150_AUD_HW_INTERFACE == 0x01)\r
+ {\r
+ hdmi_dbg(&client->dev, " Input Audio Interface = I2S.\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ }\r
+ else if (ANX7150_AUD_HW_INTERFACE == 0x02)\r
+ {\r
+ hdmi_dbg(&client->dev, " Input Audio Interface = SPDIF.\n");\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SPDIFCH_STATUS_REG, &c);\r
+ c=c>>4;\r
+ }\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
+ hdmi_dbg(&client->dev, " Audio Fs = ");\r
+ c &= 0x0f;\r
+ switch (c)\r
+ {\r
+ case 0x00:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 44.1 KHz.\n");\r
+ break;\r
+ case 0x02:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 48 KHz.\n");\r
+ break;\r
+ case 0x03:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 32 KHz.\n");\r
+ break;\r
+ case 0x08:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 88.2 KHz.\n");\r
+ break;\r
+ case 0x0a:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 96 KHz.\n\n");\r
+ break;\r
+ case 0x0c:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 176.4 KHz.\n");\r
+ break;\r
+ case 0x0e:\r
+ hdmi_dbg(&client->dev, " Audio Fs = 192 KHz.\n");\r
+ hdmi_dbg(&client->dev, "192 KHz.\n");\r
+ break;\r
+ default :\r
+ hdmi_dbg(&client->dev, " Audio Fs = Wrong Fs output.\n");\r
+ hdmi_dbg(&client->dev, "Wrong Fs output.\n");\r
+ break;\r
+ }\r
+\r
+ if (ANX7150_HDCP_enable == 1)\r
+ hdmi_dbg(&client->dev, " ANX7150_HDCP_Enable.\n");\r
+ else\r
+ hdmi_dbg(&client->dev, " ANX7150_HDCP_Disable.\n");\r
+\r
+ }\r
+ hdmi_dbg(&client->dev, "\n********************************************************************************\n\n");\r
+}\r
+void ANX7150_HDCP_Process(struct i2c_client *client, int enable)\r
+{\r
+ int rc = 0;\r
+ char c,i;\r
+ //u8 c1;\r
+ u8 Bksv_valid=0;//wen HDCP CTS\r
+\r
+ if (ANX7150_HDCP_enable)\r
+ { //HDCP_EN =1 means to do HDCP authentication,SWITCH4 = 0 means not to do HDCP authentication.\r
+\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c | 0x04);//power on HDCP, 090630\r
+\r
+ //ANX7150_i2c_read_p0_reg(ANX7150_INTR2_MASK_REG, &c);\r
+ //ANX7150_i2c_write_p0_reg(ANX7150_INTR2_MASK_REG, c |0x03);\r
+ mdelay(10);//let unencrypted video play a while, required by HDCP CTS. SY//wen HDCP CTS\r
+ anx7150_set_avmute(client);//before auth, set_avmute//wen\r
+ mdelay(10);//wen HDCP CTS\r
+\r
+ if ( !ANX7150_hdcp_init_done )\r
+ {\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ c |= ANX7150_SYS_CTRL1_HDCPMODE;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
+ if (ANX7150_edid_result.is_HDMI)\r
+ rc = anx7150_hardware_hdcp_auth_init(client);\r
+ else\r
+ { //DVI, disable 1.1 feature and enable HDCP two special point check\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ c = ((c & (~ANX7150_HDCP_CTRL1_HDCP11_EN)) | ANX7150_LINK_CHK_12_EN);\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
+ }\r
+\r
+ //wen HDCP CTS\r
+ if (!anx7150_bksv_srm(client))\r
+ {\r
+ anx7150_blue_screen_enable(client);\r
+ anx7150_clear_avmute(client);\r
+ Bksv_valid=0;\r
+ return;\r
+ }\r
+ else //SY.\r
+ {\r
+ Bksv_valid=1;\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c |= 0x03;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ }\r
+\r
+ ANX7150_hdcp_init_done = 1;\r
+//wen HDCP CTS\r
+ }\r
+\r
+\r
+//wen HDCP CTS\r
+ if ((Bksv_valid) && (!ANX7150_hdcp_auth_en))\r
+ {\r
+ hdmi_dbg(&client->dev, "enable hw hdcp\n");\r
+ anx7150_rst_ddcchannel(client);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c |= ANX7150_HDCP_CTRL0_HW_AUTHEN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ ANX7150_hdcp_auth_en = 1;\r
+ }\r
+\r
+ if ((Bksv_valid) && (ANX7150_hdcp_wait_100ms_needed))\r
+ {\r
+ ANX7150_hdcp_wait_100ms_needed = 0;\r
+ //disable audio\r
+\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= ~ANX7150_HDMI_AUDCTRL1_IN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ \r
+ hdmi_dbg(&client->dev, "++++++++ANX7150_hdcp_wait_100ms_needed+++++++++\n");\r
+ mdelay(150); // 100 -> 150\r
+ return;\r
+ }\r
+//wen HDCP CTS\r
+\r
+ if (ANX7150_hdcp_auth_pass) //wen HDCP CTS\r
+ {\r
+ //Clear the SRM_Check_Pass u8, then when reauthentication occurs, firmware can catch it.\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= 0xfc;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+\r
+ //Enable HDCP Hardware encryption\r
+ if (!ANX7150_hdcp_encryption)\r
+ {\r
+ anx7150_hdcp_encryption_enable(client);\r
+ }\r
+ if (ANX7150_send_blue_screen)\r
+ {\r
+ anx7150_blue_screen_disable(client);\r
+ }\r
+ if (ANX7150_avmute_enable)\r
+ {\r
+ anx7150_clear_avmute(client);\r
+ }\r
+\r
+ i = 0;\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
+ while((c&0x04)==0x00)//wait for encryption.\r
+ {\r
+ mdelay(2);\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
+ i++;\r
+ if (i > 10)\r
+ break;\r
+ }\r
+\r
+ //enable audio SY.\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= ANX7150_HDMI_AUDCTRL1_IN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ hdmi_dbg(&client->dev, "@@@@@ HDCP Auth PASSED! @@@@@\n");\r
+\r
+ if (ANX7150_hdcp_bcaps & 0x40) //repeater\r
+ {\r
+ hdmi_dbg(&client->dev, "Find a repeater!\n");\r
+ //actually it is KSVList check. we can't do SRM check due to the lack of SRM file. SY.\r
+ if (!ANX7150_srm_checked)\r
+ {\r
+ if (!anx7150_is_ksvlist_vld(client))\r
+ {\r
+ hdmi_dbg(&client->dev, "ksvlist not good. disable encryption");\r
+ anx7150_hdcp_encryption_disable(client);\r
+ anx7150_blue_screen_enable(client);\r
+ anx7150_clear_avmute(client);\r
+ ANX7150_ksv_srm_pass = 0;\r
+ anx7150_clean_hdcp(client);//SY.\r
+ //remove below will pass 1b-05/1b-06\r
+ //ANX7150_Set_System_State(ANX7150_WAIT_HOTPLUG);//SY.\r
+ return;\r
+ }\r
+ ANX7150_srm_checked=1;\r
+ ANX7150_ksv_srm_pass = 1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ hdmi_dbg(&client->dev, "Find a receiver.\n");\r
+ }\r
+ }\r
+ else //wen HDCP CTS\r
+ {\r
+ hdmi_dbg(&client->dev, "##### HDCP Auth FAILED! #####\n");\r
+ //also need to disable HW AUTHEN\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ c &= ~ANX7150_HDCP_CTRL0_HW_AUTHEN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
+ ANX7150_hdcp_auth_en = 0;\r
+ //ANX7150_hdcp_init_done = 0;\r
+ //ANX7150_hdcp_wait_100ms_needed = 1; //wen, update 080703\r
+\r
+ if (ANX7150_hdcp_encryption)\r
+ {\r
+ anx7150_hdcp_encryption_disable(client);\r
+ }\r
+ if (!ANX7150_send_blue_screen)\r
+ {\r
+ anx7150_blue_screen_enable(client);\r
+ }\r
+ if (ANX7150_avmute_enable)\r
+ {\r
+ anx7150_clear_avmute(client);\r
+ }\r
+ //disable audio\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c &= ~ANX7150_HDMI_AUDCTRL1_IN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ \r
+ return;\r
+ }\r
+\r
+ }\r
+ else //wen HDCP CTS\r
+ {\r
+ hdmi_dbg(&client->dev, "hdcp pin is off.\n");\r
+ if (ANX7150_send_blue_screen)\r
+ {\r
+ anx7150_blue_screen_disable(client);\r
+ }\r
+ if (ANX7150_avmute_enable)\r
+ {\r
+ anx7150_clear_avmute(client);\r
+ }\r
+ //enable audio SY.\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ c |= ANX7150_HDMI_AUDCTRL1_IN_EN;\r
+ rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
+ }\r
+\r
+//wen HDCP CTS\r
+ rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c); //72:07.1 hdmi or dvi mode\r
+ c = c & 0x02;\r
+ if (c == 0x02)\r
+ {\r
+ hdmi_dbg(&client->dev, "end of ANX7150_HDCP_Process(): in HDMI mode.\n");\r
+ }\r
+ else\r
+ {\r
+ hdmi_dbg(&client->dev, "!end of ANX7150_HDCP_Process(): in DVI mode.\n");\r
+ //To-Do: Config to DVI mode.\r
+ }\r
+\r
+ anx7150_show_video_parameter(client);\r
+ if(!enable)\r
+ anx7150_set_avmute(client);\r
+}\r
+\r
+void HDMI_Set_Video_Format(u8 video_format) //CPU set the lowpower mode\r
+{ \r
+ switch (video_format)\r
+ {\r
+ case HDMI_1280x720p_50Hz:\r
+ g_video_format = ANX7150_V1280x720p_50Hz;\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ g_video_format = ANX7150_V1280x720p_60Hz;\r
+ break;\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ g_video_format = ANX7150_V720x576p_50Hz_4x3;\r
+ break;\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ g_video_format = ANX7150_V720x576p_50Hz_16x9;\r
+ break;\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ g_video_format = ANX7150_V720x480p_60Hz_4x3;\r
+ break;\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ g_video_format = ANX7150_V720x480p_60Hz_16x9;\r
+ break;\r
+ case HDMI_1920x1080p_50Hz:\r
+ g_video_format = ANX7150_V1920x1080p_50Hz;\r
+ break;\r
+ case HDMI_1920x1080p_60Hz:\r
+ g_video_format = ANX7150_V1920x1080p_60Hz;\r
+ break;\r
+ default:\r
+ g_video_format = ANX7150_V1280x720p_50Hz;\r
+ break;\r
+ }\r
+// ANX7150_system_config_done = 0;\r
+}\r
+void HDMI_Set_Audio_Fs( u8 audio_fs) //ANX7150 call this to check lowpower\r
+{\r
+ g_audio_format = audio_fs;\r
+// ANX7150_system_config_done = 0;\r
+}\r
+int ANX7150_PLAYBACK_Process(void)\r
+{\r
+// D("enter\n");\r
+\r
+ if ((s_ANX7150_packet_config.packets_need_config != 0x00) && (ANX7150_edid_result.is_HDMI == 1))\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
--- /dev/null
+#ifndef _ANX7150_HW_H\r
+#define _ANX7150_HW_H\r
+\r
+#include <linux/hdmi.h>\r
+\r
+#define EDID_LENGTH 128\r
+struct est_timings {\r
+ u8 t1;\r
+ u8 t2;\r
+ u8 mfg_rsvd;\r
+} __attribute__((packed));\r
+\r
+struct std_timing {\r
+ u8 hsize; /* need to multiply by 8 then add 248 */\r
+ u8 vfreq_aspect;\r
+} __attribute__((packed));\r
+\r
+/* If detailed data is pixel timing */\r
+struct detailed_pixel_timing {\r
+ u8 hactive_lo;\r
+ u8 hblank_lo;\r
+ u8 hactive_hblank_hi;\r
+ u8 vactive_lo;\r
+ u8 vblank_lo;\r
+ u8 vactive_vblank_hi;\r
+ u8 hsync_offset_lo;\r
+ u8 hsync_pulse_width_lo;\r
+ u8 vsync_offset_pulse_width_lo;\r
+ u8 hsync_vsync_offset_pulse_width_hi;\r
+ u8 width_mm_lo;\r
+ u8 height_mm_lo;\r
+ u8 width_height_mm_hi;\r
+ u8 hborder;\r
+ u8 vborder;\r
+ u8 misc;\r
+} __attribute__((packed));\r
+\r
+/* If it's not pixel timing, it'll be one of the below */\r
+struct detailed_data_string {\r
+ u8 str[13];\r
+} __attribute__((packed));\r
+\r
+struct detailed_data_monitor_range {\r
+ u8 min_vfreq;\r
+ u8 max_vfreq;\r
+ u8 min_hfreq_khz;\r
+ u8 max_hfreq_khz;\r
+ u8 pixel_clock_mhz; /* need to multiply by 10 */\r
+ __le16 sec_gtf_toggle; /* A000=use above, 20=use below */\r
+ u8 hfreq_start_khz; /* need to multiply by 2 */\r
+ u8 c; /* need to divide by 2 */\r
+ __le16 m;\r
+ u8 k;\r
+ u8 j; /* need to divide by 2 */\r
+} __attribute__((packed));\r
+\r
+struct detailed_data_wpindex {\r
+ u8 white_yx_lo; /* Lower 2 bits each */\r
+ u8 white_x_hi;\r
+ u8 white_y_hi;\r
+ u8 gamma; /* need to divide by 100 then add 1 */\r
+} __attribute__((packed));\r
+\r
+struct detailed_data_color_point {\r
+ u8 windex1;\r
+ u8 wpindex1[3];\r
+ u8 windex2;\r
+ u8 wpindex2[3];\r
+} __attribute__((packed));\r
+\r
+struct cvt_timing {\r
+ u8 code[3];\r
+} __attribute__((packed));\r
+\r
+struct detailed_non_pixel {\r
+ u8 pad1;\r
+ u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name\r
+ fb=color point data, fa=standard timing data,\r
+ f9=undefined, f8=mfg. reserved */\r
+ u8 pad2;\r
+ union {\r
+ struct detailed_data_string str;\r
+ struct detailed_data_monitor_range range;\r
+ struct detailed_data_wpindex color;\r
+ struct std_timing timings[6];\r
+ struct cvt_timing cvt[4];\r
+ } data;\r
+} __attribute__((packed));\r
+\r
+struct detailed_timing {\r
+ __le16 pixel_clock; /* need to multiply by 10 KHz */\r
+ union {\r
+ struct detailed_pixel_timing pixel_data;\r
+ struct detailed_non_pixel other_data;\r
+ } data;\r
+} __attribute__((packed));\r
+\r
+struct edid {\r
+ u8 header[8];\r
+ /* Vendor & product info */\r
+ u8 mfg_id[2];\r
+ u8 prod_code[2];\r
+ u32 serial; /* FIXME: byte order */\r
+ u8 mfg_week;\r
+ u8 mfg_year;\r
+ /* EDID version */\r
+ u8 version;\r
+ u8 revision;\r
+ /* Display info: */\r
+ u8 input;\r
+ u8 width_cm;\r
+ u8 height_cm;\r
+ u8 gamma;\r
+ u8 features;\r
+ /* Color characteristics */\r
+ u8 red_green_lo;\r
+ u8 black_white_lo;\r
+ u8 red_x;\r
+ u8 red_y;\r
+ u8 green_x;\r
+ u8 green_y;\r
+ u8 blue_x;\r
+ u8 blue_y;\r
+ u8 white_x;\r
+ u8 white_y;\r
+ /* Est. timings and mfg rsvd timings*/\r
+ struct est_timings established_timings;\r
+ /* Standard timings 1-8*/\r
+ struct std_timing standard_timings[8];\r
+ /* Detailing timings 1-4 */\r
+ struct detailed_timing detailed_timings[4];\r
+ /* Number of 128 byte ext. blocks */\r
+ u8 extensions;\r
+ /* Checksum */\r
+ u8 checksum;\r
+} __attribute__((packed));\r
+\r
+extern u8 timer_slot,misc_reset_needed;\r
+extern u8 bist_switch_value_pc,switch_value;\r
+extern u8 switch_value_sw_backup,switch_value_pc_backup;\r
+extern u8 ANX7150_system_state;\r
+extern u8 ANX7150_srm_checked;\r
+extern u8 ANX7150_HDCP_enable;\r
+extern u8 ANX7150_INT_Done;\r
+extern u8 FREQ_MCLK;\r
+//extern u8 int_s1, int_s2, int_s3;\r
+extern u8 HDMI_Mode_Auto_Manual,HDMI_Lowpower_Mode;\r
+\r
+struct anx7150_interrupt_s{\r
+ int hotplug_change;\r
+ int video_format_change;\r
+ int auth_done;\r
+ int auth_state_change;\r
+ int pll_lock_change;\r
+ int rx_sense_change;\r
+ int HDCP_link_change;\r
+ int audio_clk_change;\r
+ int audio_FIFO_overrun;\r
+ int SPDIF_bi_phase_error;\r
+ int SPDIF_error;\r
+};\r
+typedef struct\r
+{\r
+ u8 is_HDMI;\r
+ u8 ycbcr444_supported;\r
+ u8 ycbcr422_supported;\r
+ u8 supported_1080p_60Hz;\r
+ u8 supported_1080p_50Hz;\r
+ u8 supported_1080i_60Hz;\r
+ u8 supported_1080i_50Hz;\r
+ u8 supported_720p_60Hz;\r
+ u8 supported_720p_50Hz;\r
+ u8 supported_576p_50Hz;\r
+ u8 supported_576i_50Hz;\r
+ u8 supported_640x480p_60Hz;\r
+ u8 supported_720x480p_60Hz;\r
+ u8 supported_720x480i_60Hz;\r
+ u8 AudioFormat[10];//MAX audio STD block is 10(0x1f / 3)\r
+ u8 AudioChannel[10];\r
+ u8 AudioFs[10];\r
+ u8 AudioLength[10];\r
+ u8 SpeakerFormat;u8 edid_errcode;}ANX7150_edid_result_4_system;\r
+ extern ANX7150_edid_result_4_system ANX7150_edid_result;\r
+//#define ITU656\r
+//#ifdef ITU656\r
+struct ANX7150_video_timingtype{ //CEA-861C format\r
+ u8 ANX7150_640x480p_60Hz[18];//format 1\r
+ u8 ANX7150_720x480p_60Hz[18];//format 2 & 3\r
+ u8 ANX7150_1280x720p_60Hz[18];//format 4\r
+ u8 ANX7150_1920x1080i_60Hz[18];//format 5\r
+ u8 ANX7150_720x480i_60Hz[18];//format 6 & 7\r
+ u8 ANX7150_1920x1080p_60Hz[18];\r
+ //u8 ANX7150_720x240p_60Hz[18];//format 8 & 9\r
+ //u8 ANX7150_2880x480i_60Hz[18];//format 10 & 11\r
+ //u8 ANX7150_2880x240p_60Hz[18];//format 12 & 13\r
+ //u8 ANX7150_1440x480p_60Hz[18];//format 14 & 15\r
+ //u8 ANX7150_1920x1080p_60Hz[18];//format 16\r
+ u8 ANX7150_720x576p_50Hz[18];//format 17 & 18\r
+ u8 ANX7150_1280x720p_50Hz[18];//format 19\r
+ u8 ANX7150_1920x1080i_50Hz[18];//format 20*/\r
+ u8 ANX7150_720x576i_50Hz[18];//format 21 & 22\r
+ u8 ANX7150_1920x1080p_50Hz[18];\r
+ /* u8 ANX7150_720x288p_50Hz[18];//formats 23 & 24\r
+ u8 ANX7150_2880x576i_50Hz[18];//formats 25 & 26\r
+ u8 ANX7150_2880x288p_50Hz[18];//formats 27 & 28\r
+ u8 ANX7150_1440x576p_50Hz[18];//formats 29 & 30\r
+ u8 ANX7150_1920x1080p_50Hz[18];//format 31\r
+ u8 ANX7150_1920x1080p_24Hz[18];//format 32\r
+ u8 ANX7150_1920x1080p_25Hz[18];//format 33\r
+ u8 ANX7150_1920x1080p_30Hz[18];//format 34*/\r
+};\r
+//#endif\r
+// 8 type of packets are legal, It is possible to sent 6 types in the same time;\r
+// So select 6 types below at most;\r
+// avi_infoframe and audio_infoframe have fixxed address;\r
+// config other selected types of packet to the rest 4 address with no limits.\r
+typedef enum\r
+{\r
+ ANX7150_avi_infoframe,\r
+ ANX7150_audio_infoframe,\r
+ /*ANX7150_spd_infoframe,\r
+ ANX7150_mpeg_infoframe,\r
+ ANX7150_acp_packet,\r
+ ANX7150_isrc1_packet,\r
+ ANX7150_isrc2_packet,\r
+ ANX7150_vendor_infoframe,*/\r
+}packet_type;\r
+\r
+typedef struct\r
+{\r
+ u8 type;\r
+ u8 version;\r
+ u8 length;\r
+ u8 pb_u8[28];\r
+}infoframe_struct;\r
+\r
+typedef struct\r
+{\r
+ u8 packets_need_config; //which infoframe packet is need updated\r
+ infoframe_struct avi_info;\r
+ infoframe_struct audio_info;\r
+ /* for the funture use\r
+ infoframe_struct spd_info;\r
+ infoframe_struct mpeg_info;\r
+ infoframe_struct acp_pkt;\r
+ infoframe_struct isrc1_pkt;\r
+ infoframe_struct isrc2_pkt;\r
+ infoframe_struct vendor_info; */\r
+\r
+} config_packets;\r
+/*\r
+ u8 i2s_format;\r
+\r
+ u8(s) Name Type Default Description\r
+ 7 EXT_VUCP R/W 0x0\r
+ Enable indicator of VUCP u8s extraction from input\r
+ I2S audio stream. 0 = disable; 1 = enable.\r
+ 6:5 MCLK_PHS_CTRL R/W 0x0\r
+ MCLK phase control for audio SPDIF input, which value\r
+ is depended on the value of MCLK frequency set and not great than it.\r
+ 4 Reserved\r
+ 3 SHIFT_CTRL R/W 0x0\r
+ WS to SD shift first u8. 0 = fist u8 shift (Philips Spec); 1 = no shift.\r
+ 2 DIR_CTRL R/W 0x0\r
+ SD data Indian (MSB or LSB first) control. 0 = MSB first; 1 = LSB first.\r
+ 1 WS_POL R/W 0x0\r
+ Word select left/right polarity select. 0 = left polarity\r
+ when works select is low; 1 = left polarity when word select is high.\r
+ 0 JUST_CTRL R/W 0x0\r
+ SD Justification control. 1 = data is right justified;\r
+ 0 = data is left justified.\r
+\r
+*/\r
+/*\r
+ u8 audio_channel\r
+u8(s) Name Type Default Description\r
+5 AUD_SD3_IN R/W 0x0 Set I2S input channel #3 enable. 0 = disable; 1 = enable.\r
+4 AUD_SD2_IN R/W 0x0 Set I2S input channel #2 enable. 0 = disable; 1 = enable.\r
+3 AUD_SD1_IN R/W 0x0 Set I2S input channel #1 enable. 0 = disable; 1 = enable.\r
+2 AUD_SD0_IN R/W 0x0 Set I2S input channel #0 enable. 0 = disable; 1 = enable.\r
+\r
+\r
+*/\r
+/*\r
+ u8 i2s_map0\r
+u8(s) Name Type Default Description\r
+7:6 FIFO3_SEL R/W 0x3 I2S Channel data stream select for audio FIFO 3. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
+5:4 FIFO2_SEL R/W 0x2 I2S Channel data stream select for audio FIFO 2. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
+3:2 FIFO1_SEL R/W 0x1 I2S Channel data stream select for audio FIFO 1. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
+1:0 FIFO0_SEL R/W 0x0 I2S Channel data stream select for audio FIFO 0. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
+\r
+ u8 i2s_map1\r
+u8(s) Name Type Default Description\r
+7 SW3 R/W 0x0 Swap left/right channel on I2S channel 3. 1 = swap; 0 = no swap.\r
+6 SW2 R/W 0x0 Swap left/right channel on I2S channel 2. 1 = swap; 0 = no swap.\r
+5 SW1 R/W 0x0 Swap left/right channel on I2S channel 1. 1 = swap; 0 = no swap.\r
+4 SW0 R/W 0x0 Swap left/right channel on I2S channel 0. 1 = swap; 0 = no swap.\r
+3:1 IN_WORD_LEN R/W 0x5 Input I2S audio word length (corresponding to channel status u8s [35:33]). When IN_WORD_MAX = 0, 001 = 16 u8s; 010 = 18 u8s; 100 = 19 u8s; 101 = 20 u8s; 110 = 17 u8s; when IN_WORD_MAX = 1, 001 = 20 u8s; 010 = 22 u8s; 100 = 23 u8s; 101 = 24 u8s; 110 = 21 u8s.\r
+0 IN_WORD_MAX R/W 0x1 Input I2S audio word length Max (corresponding to channel status u8s 32). 0 = maximal word length is 20 u8s; 1 = maximal word length is 24 u8s.\r
+*/\r
+/*\r
+ u8 Channel_status1\r
+u8(s) Name Type Default Description\r
+7:6 MODE R/W 0x0 00 = PCM Audio\r
+5:3 PCM_MODE R/W 0x0 000 = 2 audio channels without pre-emphasis;\r
+ 001 = 2 audio channels with 50/15 usec pre-emphasis\r
+2 SW_CPRGT R/W 0x0 0 = software for which copyright is asserted;\r
+ 1 = software for which no copyright is asserted\r
+1 NON_PCM R/W 0x0 0 = audio sample word represents linear PCM samples;\r
+ 1 = audio sample word used for other purposes.\r
+0 PROF_APP R/W 0x0 0 = consumer applications; 1 = professional applications.\r
+\r
+ u8 Channel_status2\r
+u8(s) Name Type Default Description\r
+7:0 CAT_CODE R/W 0x0 Category code (corresponding to channel status u8s [15:8])\r
+\r
+ u8 Channel_status3\r
+u8(s) Name Type Default Description\r
+7:4 CH_NUM R/W 0x0 Channel number (corresponding to channel status u8s [23:20])\r
+3:0 SOURCE_NUM R/W 0x0 Source number (corresponding to channel status u8s [19:16])\r
+\r
+ u8 Channel_status4\r
+u8(s) Name Type Default Description\r
+7:6 CHNL_u81 R/W 0x0 corresponding to channels status u8s [31:30]\r
+5:4 CLK_ACCUR R/W 0x0 Clock accuracy (corresponding to channels status u8s [29:28]). These two u8s define the sampling frequency tolerance. The u8s are set in the transmitter.\r
+3:0 FS_FREQ R/W 0x0 Sampling clock frequency (corresponding to channel status u8s [27:24]). 0000 = 44.1 KHz; 0010 = 48 KHz; 0011 = 32 KHz; 1000 = 88.2 KHz; 1010 = 96 KHz; 176.4 KHz; 1110 = 192 KHz; others = reserved.\r
+\r
+ u8 Channel_status5\r
+u8(s) Name Type Default Description\r
+7:4 CHNL_u82 R/W 0x0 corresponding to channels status u8s [39:36]\r
+3:1 WORD_LENGTH R/W 0x5 Audio word length (corresponding to channel status u8s [35:33]). When WORD_MAX = 0, 001 = 16 u8s; 010 = 18 u8s; 100 = 19 u8s; 101 = 20 u8s; 110 = 17 u8s; when WORD_MAX = 1, 001 = 20 u8s; 010 = 22 u8s; 100 = 23 u8s; 101 = 24 u8s; 110 = 21 u8s.\r
+0 WORD_MAX R/W 0x1 Audio word length Max (corresponding to channel status u8s 32). 0 = maximal word length is 20 u8s; 1 = maximal word length is 24 u8s.\r
+\r
+*/\r
+typedef struct\r
+{\r
+ u8 audio_channel;\r
+ u8 i2s_format;\r
+ u8 i2s_swap;\r
+ u8 Channel_status1;\r
+ u8 Channel_status2;\r
+ u8 Channel_status3;\r
+ u8 Channel_status4;\r
+ u8 Channel_status5;\r
+} i2s_config_struct;\r
+/*\r
+ u8 FS_FREQ;\r
+\r
+ 7:4 FS_FREQ R 0x0\r
+ Sampling clock frequency (corresponding to channel status u8s [27:24]).\r
+ 0000 = 44.1 KHz; 0010 = 48 KHz; 0011 = 32 KHz; 1000 = 88.2 KHz; 1010 = 96 KHz;\r
+ 176.4 KHz; 1110 = 192 KHz; others = reserved.\r
+*/\r
+\r
+typedef struct\r
+{\r
+ u8 one_u8_ctrl;\r
+\r
+} super_audio_config_struct;\r
+\r
+typedef struct\r
+{\r
+ u8 audio_type; // audio type\r
+ // #define ANX7150_i2s_input 0x01\r
+ // #define ANX7150_spdif_input 0x02\r
+ // #define ANX7150_super_audio_input 0x04\r
+\r
+ u8 down_sample; // 0x72:0x50\r
+ // 0x00: 00 no down sample\r
+ // 0x20: 01 2 to 1 down sample\r
+ // 0x60: 11 4 to 1 down sample\r
+ // 0x40: 10 reserved\r
+ u8 audio_layout;//audio layout;\r
+ //0x00, 2-channel\r
+ //0x80, 8-channel\r
+\r
+ i2s_config_struct i2s_config;\r
+ super_audio_config_struct super_audio_config;\r
+\r
+} audio_config_struct;\r
+\r
+/*added by gerard.zhu*/\r
+/*DDC type*/\r
+typedef enum {\r
+ DDC_Hdcp,\r
+ DDC_Edid,\r
+}ANX7150_DDC_Type;\r
+\r
+/*Read DDC status type*/\r
+typedef enum {\r
+ report,\r
+ Judge,\r
+}ANX7150_DDC_Status_Check_Type;\r
+\r
+/*Define DDC address struction*/\r
+typedef struct {\r
+ u8 dev_addr;\r
+ u8 sgmt_addr;\r
+ u8 offset_addr;\r
+}ANX7150_DDC_Addr;\r
+\r
+/*DDC status u8*/\r
+#define DDC_Error_u8 0x07\r
+#define DDC_Occup_u8 0x06\r
+#define DDC_Fifo_Full_u8 0x05\r
+#define DDC_Fifo_Empt_u8 0x04\r
+#define DDC_No_Ack_u8 0x03\r
+#define DDC_Fifo_Rd_u8 0x02\r
+#define DDC_Fifo_Wr_u8 0x01\r
+#define DDC_Progress_u8 0x00\r
+\r
+#define YCbCr422 0x20\r
+#define null 0\r
+#define source_ratio 0x08\r
+\r
+/*DDC Command*/\r
+#define Abort_Current_Operation 0x00\r
+#define Sequential_u8_Read 0x01\r
+#define Sequential_u8_Write 0x02\r
+#define Implicit_Offset_Address_Read 0x3\r
+#define Enhanced_DDC_Sequenital_Read 0x04\r
+#define Clear_DDC_Fifo 0x05\r
+#define I2c_reset 0x06\r
+\r
+/*DDC result*/\r
+#define DDC_NO_Err 0x00\r
+#define DDC_Status_Err 0x01\r
+#define DDC_Data_Addr_Err 0x02\r
+#define DDC_Length_Err 0x03\r
+\r
+/*checksum result*/\r
+#define Edid_Checksum_No_Err 0x00\r
+#define Edid_Checksum_Err 0x01\r
+\r
+/*HDCP device base address*/\r
+#define HDCP_Dev_Addr 0x74\r
+\r
+/*HDCP Bksv offset*/\r
+#define HDCP_Bksv_Offset 0x00\r
+\r
+/*HDCP Bcaps offset*/\r
+#define HDCP_Bcaps_Offset 0x40\r
+\r
+/*HDCP Bstatus offset*/\r
+#define HDCP_Bstatus_offset 0x41\r
+\r
+/*HDCP KSV Fifo offset */\r
+#define HDCP_Ksv_Fifo_Offset 0x43\r
+\r
+/*HDCP bksv data nums*/\r
+#define Bksv_Data_Nums 5\r
+\r
+/*HDCP ksvs data number by defult*/\r
+#define ksvs_data_nums 50\r
+\r
+/*DDC Max u8s*/\r
+#define DDC_Max_Length 1024\r
+\r
+/*DDC fifo depth*/\r
+#define DDC_Fifo_Depth 16\r
+\r
+/*DDC read delay ms*/\r
+#define DDC_Read_Delay 3\r
+\r
+/*DDC Write delay ms*/\r
+#define DDC_Write_Delay 3\r
+/*end*/\r
+\r
+extern u8 ANX7150_parse_edid_done;\r
+extern u8 ANX7150_system_config_done;\r
+extern u8 ANX7150_video_format_config,ANX7150_video_timing_id;\r
+extern u8 ANX7150_new_csc,ANX7150_new_vid_id,ANX7150_new_HW_interface;\r
+extern u8 ANX7150_ddr_edge;\r
+extern u8 ANX7150_in_pix_rpt_bkp,ANX7150_tx_pix_rpt_bkp;\r
+extern u8 ANX7150_in_pix_rpt,ANX7150_tx_pix_rpt;\r
+extern u8 ANX7150_pix_rpt_set_by_sys;\r
+extern u8 ANX7150_RGBorYCbCr;\r
+extern audio_config_struct s_ANX7150_audio_config;\r
+extern config_packets s_ANX7150_packet_config;\r
+\r
+//********************** BIST Enable***********************************\r
+\r
+\r
+#define ddr_falling_edge 1\r
+#define ddr_rising_edge 0\r
+\r
+#define input_pixel_clk_1x_repeatition 0x00\r
+#define input_pixel_clk_2x_repeatition 0x01\r
+#define input_pixel_clk_4x_repeatition 0x03\r
+\r
+//***********************Video Config***********************************\r
+#define ANX7150_RGB_YCrCb444_SepSync 0\r
+#define ANX7150_YCrCb422_SepSync 1\r
+#define ANX7150_YCrCb422_EmbSync 2\r
+#define ANX7150_YCMux422_SepSync_Mode1 3\r
+#define ANX7150_YCMux422_SepSync_Mode2 4\r
+#define ANX7150_YCMux422_EmbSync_Mode1 5\r
+#define ANX7150_YCMux422_EmbSync_Mode2 6\r
+#define ANX7150_RGB_YCrCb444_DDR_SepSync 7\r
+#define ANX7150_RGB_YCrCb444_DDR_EmbSync 8\r
+\r
+#define ANX7150_RGB_YCrCb444_SepSync_No_DE 9\r
+#define ANX7150_YCrCb422_SepSync_No_DE 10\r
+\r
+#define ANX7150_Progressive 0\r
+#define ANX7150_Interlace 0x08\r
+#define ANX7150_Neg_Hsync_pol 0x20\r
+#define ANX7150_Pos_Hsync_pol 0\r
+#define ANX7150_Neg_Vsync_pol 0x40\r
+#define ANX7150_Pos_Vsync_pol 0\r
+\r
+#define ANX7150_V640x480p_60Hz 1\r
+#define ANX7150_V720x480p_60Hz_4x3 2\r
+#define ANX7150_V720x480p_60Hz_16x9 3\r
+#define ANX7150_V1280x720p_60Hz 4\r
+#define ANX7150_V1280x720p_50Hz 19\r
+#define ANX7150_V1920x1080i_60Hz 5\r
+#define ANX7150_V1920x1080p_60Hz 16\r
+#define ANX7150_V1920x1080p_50Hz 31\r
+#define ANX7150_V1920x1080i_50Hz 20\r
+#define ANX7150_V720x480i_60Hz_4x3 6\r
+#define ANX7150_V720x480i_60Hz_16x9 7\r
+#define ANX7150_V720x576i_50Hz_4x3 21\r
+#define ANX7150_V720x576i_50Hz_16x9 22\r
+#define ANX7150_V720x576p_50Hz_4x3 17\r
+#define ANX7150_V720x576p_50Hz_16x9 18\r
+\r
+#define ANX7150_RGB 0x00\r
+#define ANX7150_YCbCr422 0x01\r
+#define ANX7150_YCbCr444 0x02\r
+#define ANX7150_CSC_BT709 1\r
+#define ANX7150_CSC_BT601 0\r
+\r
+#define ANX7150_EMBEDED_BLUE_SCREEN_ENABLE 1\r
+#define ANX7150_HDCP_FAIL_THRESHOLD 10\r
+\r
+#define ANX7150_avi_sel 0x01\r
+#define ANX7150_audio_sel 0x02\r
+#define ANX7150_spd_sel 0x04\r
+#define ANX7150_mpeg_sel 0x08\r
+#define ANX7150_acp_sel 0x10\r
+#define ANX7150_isrc1_sel 0x20\r
+#define ANX7150_isrc2_sel 0x40\r
+#define ANX7150_vendor_sel 0x80\r
+\r
+// audio type\r
+#define ANX7150_i2s_input 0x01\r
+#define ANX7150_spdif_input 0x02\r
+#define ANX7150_super_audio_input 0x04\r
+// freq_mclk\r
+#define ANX7150_mclk_128_Fs 0x00\r
+#define ANX7150_mclk_256_Fs 0x01\r
+#define ANX7150_mclk_384_Fs 0x02\r
+#define ANX7150_mclk_512_Fs 0x03\r
+// thresholds\r
+#define ANX7150_spdif_stable_th 0x03\r
+// fs -> N(ACR)\r
+#define ANX7150_N_32k 0x1000\r
+#define ANX7150_N_44k 0x1880\r
+#define ANX7150_N_88k 0x3100\r
+#define ANX7150_N_176k 0x6200\r
+#define ANX7150_N_48k 0x1800\r
+#define ANX7150_N_96k 0x3000\r
+#define ANX7150_N_192k 0x6000\r
+\r
+#define spdif_error_th 0x0a\r
+\r
+#define Hresolution_1920 1920\r
+#define Vresolution_540 540\r
+#define Vresolution_1080 1080\r
+#define Hresolution_1280 1280\r
+#define Vresolution_720 720\r
+#define Hresolution_640 640\r
+#define Vresolution_480 480\r
+#define Hresolution_720 720\r
+#define Vresolution_240 240\r
+#define Vresolution_576 576\r
+#define Vresolution_288 288\r
+#define Hz_50 50\r
+#define Hz_60 60\r
+#define Interlace_EDID 0\r
+#define Progressive_EDID 1\r
+#define ratio_16_9 1.777778\r
+#define ratio_4_3 1.333333\r
+\r
+#define ANX7150_EDID_BadHeader 0x01\r
+#define ANX7150_EDID_861B_not_supported 0x02\r
+#define ANX7150_EDID_CheckSum_ERR 0x03\r
+#define ANX7150_EDID_No_ExtBlock 0x04\r
+#define ANX7150_EDID_ExtBlock_NotFor_861B 0x05\r
+\r
+#define ANX7150_VND_IDL_REG 0x00\r
+#define ANX7150_VND_IDH_REG 0x01\r
+#define ANX7150_DEV_IDL_REG 0x02\r
+#define ANX7150_DEV_IDH_REG 0x03\r
+#define ANX7150_DEV_REV_REG 0x04\r
+\r
+#define ANX7150_SRST_REG 0x05\r
+#define ANX7150_TX_RST 0x40\r
+#define ANX7150_SRST_VIDCAP_RST 0x20 // u8 position\r
+#define ANX7150_SRST_AFIFO_RST 0x10 // u8 position\r
+#define ANX7150_SRST_HDCP_RST 0x08 // u8 position\r
+#define ANX7150_SRST_VID_FIFO_RST 0x04 // u8 position\r
+#define ANX7150_SRST_AUD_RST 0x02 // u8 position\r
+#define ANX7150_SRST_SW_RST 0x01 // u8 position\r
+\r
+#define ANX7150_SYS_STATE_REG 0x06\r
+#define ANX7150_SYS_STATE_AUD_CLK_DET 0x20 // u8 position\r
+#define ANX7150_SYS_STATE_AVMUTE 0x10 // u8 position\r
+#define ANX7150_SYS_STATE_HP 0x08 // u8 position\r
+#define ANX7150_SYS_STATE_VSYNC 0x04 // u8 position\r
+#define ANX7150_SYS_STATE_CLK_DET 0x02 // u8 position\r
+#define ANX7150_SYS_STATE_RSV_DET 0x01 // u8 position\r
+\r
+#define ANX7150_SYS_CTRL1_REG 0x07\r
+#define ANX7150_SYS_CTRL1_LINKMUTE_EN 0x80 // u8 position\r
+#define ANX7150_SYS_CTRL1_HDCPHPD_RST 0x40 // u8 position\r
+#define ANX7150_SYS_CTRL1_PDINT_SEL 0x20 // u8 position\r
+#define ANX7150_SYS_CTRL1_DDC_FAST 0x10 // u8 position\r
+#define ANX7150_SYS_CTRL1_DDC_SWCTRL 0x08 // u8 position\r
+#define ANX7150_SYS_CTRL1_HDCPMODE 0x04 // u8 position\r
+#define ANX7150_SYS_CTRL1_HDMI 0x02 // u8 position\r
+#define ANX7150_SYS_CTRL1_PWDN_CTRL 0x01 // u8 position\r
+\r
+#define ANX7150_SYS_CTRL2_REG 0x08\r
+#define ANX7150_SYS_CTRL2_DDC_RST 0x08 // u8 position\r
+#define ANX7150_SYS_CTRL2_TMDSBIST_RST 0x04 // u8 position\r
+#define ANX7150_SYS_CTRL2_MISC_RST 0x02 // u8 position\r
+#define ANX7150_SYS_CTRL2_HW_RST 0x01 // u8 position\r
+\r
+#define ANX7150_SYS_CTRL3_REG 0x09\r
+#define ANX7150_SYS_CTRL3_I2C_PWON 0x02\r
+#define ANX7150_SYS_CTRL3_PWON_ALL 0x01\r
+\r
+#define ANX7150_SYS_CTRL4_REG 0x0b\r
+\r
+#define ANX7150_VID_STATUS_REG 0x10\r
+#define ANX7150_VID_STATUS_VID_STABLE 0x20 // u8 position\r
+#define ANX7150_VID_STATUS_EMSYNC_ERR 0x10 // u8 position\r
+#define ANX7150_VID_STATUS_FLD_POL 0x08 // u8 position\r
+#define ANX7150_VID_STATUS_TYPE 0x04 // u8 position\r
+#define ANX7150_VID_STATUS_VSYNC_POL 0x02 // u8 position\r
+#define ANX7150_VID_STATUS_HSYNC_POL 0x01 // u8 position\r
+\r
+#define ANX7150_VID_MODE_REG 0x11\r
+#define ANX7150_VID_MODE_CHKSHARED_EN 0x80 // u8 position\r
+#define ANX7150_VID_MODE_LINKVID_EN 0x40 // u8 position\r
+#define ANX7150_VID_MODE_RANGE_Y2R 0x20 // u8 position\r
+#define ANX7150_VID_MODE_CSPACE_Y2R 0x10 // u8 position\r
+#define ANX7150_VID_MODE_Y2R_SEL 0x08 // u8 position\r
+#define ANX7150_VID_MODE_UPSAMPLE 0x04 // u8 position\r
+\r
+#define ANX7150_VID_CTRL_REG 0x12\r
+#define ANX7150_VID_CTRL_IN_EN 0x10 // u8 position\r
+#define ANX7150_VID_CTRL_YCu8_SEL 0x08 // u8 position\r
+#define ANX7150_VID_CTRL_u8CTRL_EN 0x04 // u8 position\r
+\r
+#define ANX7150_VID_CAPCTRL0_REG 0x13\r
+#define ANX7150_VID_CAPCTRL0_DEGEN_EN 0x80 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_EMSYNC_EN 0x40 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_DEMUX_EN 0x20 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_INV_IDCK 0x10 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_DV_BUSMODE 0x08 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_DDR_EDGE 0x04 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_VIDu8_SWAP 0x02 // u8 position\r
+#define ANX7150_VID_CAPCTRL0_VIDBIST_EN 0x01 // u8 position\r
+\r
+#define ANX7150_VID_CAPCTRL1_REG 0x14\r
+#define ANX7150_VID_CAPCTRL1_FORMAT_SEL 0x80 // u8 position\r
+#define ANX7150_VID_CAPCTRL1_VSYNC_POL 0x40 // u8 position\r
+#define ANX7150_VID_CAPCTRL1_HSYNC_POL 0x20 // u8 position\r
+#define ANX7150_VID_CAPCTRL1_INV_FLDPOL 0x10 // u8 position\r
+#define ANX7150_VID_CAPCTRL1_VID_TYPE 0x08 // u8 position\r
+\r
+#define ANX7150_H_RESL_REG 0x15\r
+#define ANX7150_H_RESH_REG 0x16\r
+#define ANX7150_VID_PIXL_REG 0x17\r
+#define ANX7150_VID_PIXH_REG 0x18\r
+#define ANX7150_H_FRONTPORCHL_REG 0x19\r
+#define ANX7150_H_FRONTPORCHH_REG 0x1A\r
+#define ANX7150_HSYNC_ACT_WIDTHL_REG 0x1B\r
+#define ANX7150_HSYNC_ACT_WIDTHH_REG 0x1C\r
+#define ANX7150_H_BACKPORCHL_REG 0x1D\r
+#define ANX7150_H_BACKPORCHH_REG 0x1E\r
+#define ANX7150_V_RESL_REG 0x1F\r
+#define ANX7150_V_RESH_REG 0x20\r
+#define ANX7150_ACT_LINEL_REG 0x21\r
+#define ANX7150_ACT_LINEH_REG 0x22\r
+#define ANX7150_ACT_LINE2VSYNC_REG 0x23\r
+#define ANX7150_VSYNC_WID_REG 0x24\r
+#define ANX7150_VSYNC_TAIL2VIDLINE_REG 0x25\r
+#define ANX7150_VIDF_HRESL_REG 0x26\r
+#define ANX7150_VIDF_HRESH_REG 0x27\r
+#define ANX7150_VIDF_PIXL_REG 0x28\r
+#define ANX7150_VIDF_PIXH_REG 0x29\r
+#define ANX7150_VIDF_HFORNTPORCHL_REG 0x2A\r
+#define ANX7150_VIDF_HFORNTPORCHH_REG 0x2B\r
+#define ANX7150_VIDF_HSYNCWIDL_REG 0x2C\r
+#define ANX7150_VIDF_HSYNCWIDH_REG 0x2D\r
+#define ANX7150_VIDF_HBACKPORCHL_REG 0x2E\r
+#define ANX7150_VIDF_HBACKPORCHH_REG 0x2F\r
+#define ANX7150_VIDF_VRESL_REG 0x30\r
+#define ANX7150_VIDF_VRESH_REG 0x31\r
+#define ANX7150_VIDF_ACTVIDLINEL_REG 0x32\r
+#define ANX7150_VIDF_ACTVIDLINEH_REG 0x33\r
+#define ANX7150_VIDF_ACTLINE2VSYNC_REG 0x34\r
+#define ANX7150_VIDF_VSYNCWIDLINE_REG 0x35\r
+#define ANX7150_VIDF_VSYNCTAIL2VIDLINE_REG 0x36\r
+\r
+//Video input data u8 control registers\r
+\r
+#define VID_u8_CTRL0 0x37 //added\r
+#define VID_u8_CTRL1 0x38\r
+#define VID_u8_CTRL2 0x39\r
+#define VID_u8_CTRL3 0x3A\r
+#define VID_u8_CTRL4 0x3B\r
+#define VID_u8_CTRL5 0x3C\r
+#define VID_u8_CTRL6 0x3D\r
+#define VID_u8_CTRL7 0x3E\r
+#define VID_u8_CTRL8 0x3F\r
+#define VID_u8_CTRL9 0x48\r
+#define VID_u8_CTRL10 0x49\r
+#define VID_u8_CTRL11 0x4A\r
+#define VID_u8_CTRL12 0x4B\r
+#define VID_u8_CTRL13 0x4C\r
+#define VID_u8_CTRL14 0x4D\r
+#define VID_u8_CTRL15 0x4E\r
+#define VID_u8_CTRL16 0x4F\r
+#define VID_u8_CTRL17 0x89\r
+#define VID_u8_CTRL18 0x8A\r
+#define VID_u8_CTRL19 0x8B\r
+#define VID_u8_CTRL20 0x8C\r
+#define VID_u8_CTRL21 0x8D\r
+#define VID_u8_CTRL22 0x8E\r
+#define VID_u8_CTRL23 0x8F\r
+\r
+\r
+#define ANX7150_INTR_STATE_REG 0x40\r
+\r
+#define ANX7150_INTR_CTRL_REG 0x41\r
+\r
+#define ANX7150_INTR_CTRL_SOFT_INTR 0x04 // u8 position\r
+#define ANX7150_INTR_CTRL_TYPE 0x02 // u8 position\r
+#define ANX7150_INTR_CTRL_POL 0x01 // u8 position\r
+\r
+#define ANX7150_INTR1_STATUS_REG 0x42\r
+#define ANX7150_INTR1_STATUS_CTS_CHG 0x80 // u8 position\r
+#define ANX7150_INTR1_STATUS_AFIFO_UNDER 0x40 // u8 position\r
+#define ANX7150_INTR1_STATUS_AFIFO_OVER 0x20 // u8 position\r
+#define ANX7150_INTR1_STATUS_SPDIF_ERR 0x10 // u8 position\r
+#define ANX7150_INTR1_STATUS_SW_INT 0x08 // u8 position\r
+#define ANX7150_INTR1_STATUS_HP_CHG 0x04 // u8 position\r
+#define ANX7150_INTR1_STATUS_CTS_OVRWR 0x02 // u8 position\r
+#define ANX7150_INTR1_STATUS_CLK_CHG 0x01 // u8 position\r
+\r
+#define ANX7150_INTR2_STATUS_REG 0x43\r
+#define ANX7150_INTR2_STATUS_ENCEN_CHG 0x80 // u8 position\r
+#define ANX7150_INTR2_STATUS_HDCPLINK_CHK 0x40 // u8 position\r
+#define ANX7150_INTR2_STATUS_HDCPENHC_CHK 0x20 // u8 position\r
+#define ANX7150_INTR2_STATUS_BKSV_RDY 0x10 // u8 position\r
+#define ANX7150_INTR2_STATUS_PLLLOCK_CHG 0x08 // u8 position\r
+#define ANX7150_INTR2_STATUS_SHA_DONE 0x04 // u8 position\r
+#define ANX7150_INTR2_STATUS_AUTH_CHG 0x02 // u8 position\r
+#define ANX7150_INTR2_STATUS_AUTH_DONE 0x01 // u8 position\r
+\r
+#define ANX7150_INTR3_STATUS_REG 0x44\r
+#define ANX7150_INTR3_STATUS_SPDIFBI_ERR 0x80 // u8 position\r
+#define ANX7150_INTR3_STATUS_VIDF_CHG 0x40 // u8 position\r
+#define ANX7150_INTR3_STATUS_AUDCLK_CHG 0x20 // u8 position\r
+#define ANX7150_INTR3_STATUS_DDCACC_ERR 0x10 // u8 position\r
+#define ANX7150_INTR3_STATUS_DDC_NOACK 0x08 // u8 position\r
+#define ANX7150_INTR3_STATUS_VSYNC_DET 0x04 // u8 position\r
+#define ANX7150_INTR3_STATUS_RXSEN_CHG 0x02 // u8 position\r
+#define ANX7150_INTR3_STATUS_SPDIF_UNSTBL 0x01 // u8 position\r
+\r
+#define ANX7150_INTR1_MASK_REG 0x45\r
+#define ANX7150_INTR2_MASK_REG 0x46\r
+#define ANX7150_INTR3_MASK_REG 0x47\r
+\r
+#define ANX7150_HDMI_AUDCTRL0_REG 0x50\r
+#define ANX7150_HDMI_AUDCTRL0_LAYOUT 0x80 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL0_DOWN_SMPL 0x60 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL0_CTSGEN_SC 0x10 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL0_INV_AUDCLK 0x08 // u8 position\r
+\r
+#define ANX7150_HDMI_AUDCTRL1_REG 0x51\r
+#define ANX7150_HDMI_AUDCTRL1_IN_EN 0x80 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN 0x40 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SD3IN_EN 0x20 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SD2IN_EN 0x10 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SD1IN_EN 0x08 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SD0IN_EN 0x04 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_SPDIFFS_OVRWR 0x02 // u8 position\r
+#define ANX7150_HDMI_AUDCTRL1_CLK_SEL 0x01 // u8 position\r
+\r
+#define ANX7150_I2S_CTRL_REG 0x52\r
+#define ANX7150_I2S_CTRL_VUCP 0x80 // u8 position\r
+#define SPDIF_IN_SEL 0x10 //0-spdif, 1-multi with sd0\r
+#define ANX7150_I2S_CTRL_SHIFT_CTRL 0x08 // u8 position\r
+#define ANX7150_I2S_CTRL_DIR_CTRL 0x04 // u8 position\r
+#define ANX7150_I2S_CTRL_WS_POL 0x02 // u8 position\r
+#define ANX7150_I2S_CTRL_JUST_CTRL 0x01 // u8 position\r
+\r
+#define ANX7150_I2SCH_CTRL_REG 0x53\r
+#define ANX7150_I2SCH_FIFO3_SEL 0xC0 // u8 position\r
+#define ANX7150_I2SCH_FIFO2_SEL 0x30 // u8 position\r
+#define ANX7150_I2SCH_FIFO1_SEL 0x0C // u8 position\r
+#define ANX7150_I2SCH_FIFO0_SEL 0x03 // u8 position\r
+\r
+#define ANX7150_I2SCH_SWCTRL_REG 0x54\r
+\r
+#define ANX7150_I2SCH_SWCTRL_SW3 0x80 // u8 position\r
+#define ANX7150_I2SCH_SWCTRL_SW2 0x40 // u8 position\r
+#define ANX7150_I2SCH_SWCTRL_SW1 0x20 // u8 position\r
+#define ANX7150_I2SCH_SWCTRL_SW0 0x10 // u8 position\r
+#define ANX7150_I2SCH_SWCTRL_INWD_LEN 0xE0 // u8 position\r
+#define ANX7150_I2SCH_SWCTRL_INWD_MAX 0x01 // u8 position\r
+\r
+#define ANX7150_SPDIFCH_STATUS_REG 0x55\r
+#define ANX7150_SPDIFCH_STATUS_FS_FREG 0xF0 // u8 position\r
+#define ANX7150_SPDIFCH_STATUS_WD_LEN 0x0E // u8 position\r
+#define ANX7150_SPDIFCH_STATUS_WD_MX 0x01 // u8 position\r
+\r
+#define ANX7150_I2SCH_STATUS1_REG 0x56\r
+#define ANX7150_I2SCH_STATUS1_MODE 0xC0 // u8 position\r
+#define ANX7150_I2SCH_STATUS1_PCM_MODE 0x38 // u8 position\r
+#define ANX7150_I2SCH_STATUS1_SW_CPRGT 0x04 // u8 position\r
+#define ANX7150_I2SCH_STATUS1_NON_PCM 0x02 // u8 position\r
+#define ANX7150_I2SCH_STATUS1_PROF_APP 0x01 // u8 position\r
+\r
+#define ANX7150_I2SCH_STATUS2_REG 0x57\r
+\r
+#define ANX7150_I2SCH_STATUS3_REG 0x58\r
+#define ANX7150_I2SCH_STATUS3_CH_NUM 0xF0 // u8 position\r
+#define ANX7150_I2SCH_STATUS3_SRC_NUM 0x0F // u8 position\r
+\r
+\r
+\r
+#define ANX7150_I2SCH_STATUS4_REG 0x59\r
+\r
+#define ANX7150_I2SCH_STATUS5_REG 0x5A\r
+\r
+#define ANX7150_I2SCH_STATUS5_WORD_MAX 0x01 // u8 position\r
+\r
+#define ANX7150_HDMI_AUDSTATUS_REG 0x5B\r
+\r
+#define ANX7150_HDMI_AUDSTATUS_SPDIF_DET 0x01 // u8 position\r
+\r
+#define ANX7150_HDMI_AUDBIST_CTRL_REG 0x5C\r
+\r
+#define ANX7150_HDMI_AUDBIST_EN3 0x08 // u8 position\r
+#define ANX7150_HDMI_AUDBIST_EN2 0x04 // u8 position\r
+#define ANX7150_HDMI_AUDBIST_EN1 0x02 // u8 position\r
+#define ANX7150_HDMI_AUDBIST_EN0 0x01 // u8 position\r
+\r
+#define ANX7150_AUD_INCLK_CNT_REG 0x5D\r
+#define ANX7150_AUD_DEBUG_STATUS_REG 0x5E\r
+\r
+#define ANX7150_ONEu8_AUD_CTRL_REG 0x60\r
+\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN7 0x80 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN6 0x40 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN5 0x20 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN4 0x10 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN3 0x08 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN2 0x04 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN1 0x02 // u8 position\r
+#define ANX7150_ONEu8_AUD_CTRL_SEN0 0x01 // u8 position\r
+\r
+#define ANX7150_ONEu8_AUD0_CTRL_REG 0x61\r
+#define ANX7150_ONEu8_AUD1_CTRL_REG 0x62\r
+#define ANX7150_ONEu8_AUD2_CTRL_REG 0x63\r
+#define ANX7150_ONEu8_AUD3_CTRL_REG 0x64\r
+\r
+#define ANX7150_ONEu8_AUDCLK_CTRL_REG 0x65\r
+\r
+#define ANX7150_ONEu8_AUDCLK_DET 0x08 // u8 position\r
+\r
+#define ANX7150_SPDIF_ERR_THRSHLD_REG 0x66\r
+#define ANX7150_SPDIF_ERR_CNT_REG 0x67\r
+\r
+#define ANX7150_HDMI_LINK_CTRL_REG 0x70\r
+\r
+#define ANX7150_HDMI_LINK_DATA_MUTEEN1 0x80 // u8 position\r
+#define ANX7150_HDMI_LINK_DATA_MUTEEN0 0x40 // u8 position\r
+#define ANX7150_HDMI_LINK_CLK_MUTEEN2 0x20 // u8 position\r
+#define ANX7150_HDMI_LINK_CLK_MUTEEN1 0x10 // u8 position\r
+#define ANX7150_HDMI_LINK_CLK_MUTEEN0 0x08 // u8 position\r
+#define ANX7150_HDMI_LINK_DEC_DE 0x04 // u8 position\r
+#define ANX7150_HDMI_LINK_PRMB_INC 0x02 // u8 position\r
+#define ANX7150_HDMI_LINK_AUTO_PROG 0x01 // u8 position\r
+\r
+#define ANX7150_VID_CAPCTRL2_REG 0x71\r
+\r
+#define ANX7150_VID_CAPCTRL2_CHK_UPDATEEN 0x10 // u8 position\r
+\r
+#define ANX7150_LINK_MUTEEE_REG 0x72\r
+\r
+#define ANX7150_LINK_MUTEEE_AVMUTE_EN2 0x20 // u8 position\r
+#define ANX7150_LINK_MUTEEE_AVMUTE_EN1 0x10 // u8 position\r
+#define ANX7150_LINK_MUTEEE_AVMUTE_EN0 0x08 // u8 position\r
+#define ANX7150_LINK_MUTEEE_AUDMUTE_EN2 0x04 // u8 position\r
+#define ANX7150_LINK_MUTEEE_AUDMUTE_EN1 0x02 // u8 position\r
+#define ANX7150_LINK_MUTEEE_AUDMUTE_EN0 0x01 // u8 position\r
+\r
+#define ANX7150_SERDES_TEST0_REG 0x73\r
+#define ANX7150_SERDES_TEST1_REG 0x74\r
+#define ANX7150_SERDES_TEST2_REG 0x75\r
+\r
+#define ANX7150_PLL_TX_AMP 0x76\r
+\r
+\r
+#define ANX7150_DDC_SLV_ADDR_REG 0x80\r
+#define ANX7150_DDC_SLV_SEGADDR_REG 0x81\r
+#define ANX7150_DDC_SLV_OFFADDR_REG 0x82\r
+#define ANX7150_DDC_ACC_CMD_REG 0x83\r
+#define ANX7150_DDC_ACCNUM0_REG 0x84\r
+#define ANX7150_DDC_ACCNUM1_REG 0x85\r
+\r
+#define ANX7150_DDC_CHSTATUS_REG 0x86\r
+\r
+#define ANX7150_DDC_CHSTATUS_DDCERR 0x80 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_DDC_OCCUPY 0x40 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_FIFO_FULL 0x20 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_FIFO_EMPT 0x10 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_NOACK 0x08 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_FIFO_RD 0x04 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_FIFO_WR 0x02 // u8 position\r
+#define ANX7150_DDC_CHSTATUS_INPRO 0x01 // u8 position\r
+\r
+#define ANX7150_DDC_FIFO_ACC_REG 0x87\r
+#define ANX7150_DDC_FIFOCNT_REG 0x88\r
+\r
+#define ANX7150_SYS_PD_REG 0x90\r
+#define ANX7150_SYS_PD_PLL 0x80 // u8 position\r
+#define ANX7150_SYS_PD_TMDS 0x40 // u8 position\r
+#define ANX7150_SYS_PD_TMDS_CLK 0x20 // u8 position\r
+#define ANX7150_SYS_PD_MISC 0x10 // u8 position\r
+#define ANX7150_SYS_PD_LINK 0x08 // u8 position\r
+#define ANX7150_SYS_PD_IDCK 0x04 // u8 position\r
+#define ANX7150_SYS_PD_AUD 0x02 // u8 position\r
+#define ANX7150_SYS_PD_MACRO_ALL 0x01 // u8 position\r
+\r
+#define ANX7150_LINKFSM_DEBUG0_REG 0x91\r
+#define ANX7150_LINKFSM_DEBUG1_REG 0x92\r
+\r
+#define ANX7150_PLL_CTRL0_REG 0x93\r
+#define ANX7150_PLL_CTRL0_CPREG_BLEED 0x02 // u8 position\r
+#define ANX7150_PLL_CTRL0_TEST_EN 0x01 // u8 position\r
+\r
+#define ANX7150_PLL_CTRL1_REG 0x94\r
+#define ANX7150_PLL_CTRL1_TESTEN 0x80 // u8 position\r
+\r
+#define ANX7150_OSC_CTRL_REG 0x95\r
+#define ANX7150_OSC_CTRL_TESTEN 0x80 // u8 position\r
+#define ANX7150_OSC_CTRL_SEL_BG 0x40 // u8 position\r
+\r
+#define ANX7150_TMDS_CH0_CONFIG_REG 0x96\r
+#define ANX7150_TMDS_CH0_TESTEN 0x20 // u8 position\r
+#define ANX7150_TMDS_CH0_AMP 0x1C // u8 position\r
+#define ANX7150_TMDS_CHO_EMP 0x03 // u8 position\r
+\r
+#define ANX7150_TMDS_CH1_CONFIG_REG 0x97\r
+#define ANX7150_TMDS_CH1_TESTEN 0x20 // u8 position\r
+#define ANX7150_TMDS_CH1_AMP 0x1C // u8 position\r
+#define ANX7150_TMDS_CH1_EMP 0x03 // u8 position\r
+\r
+#define ANX7150_TMDS_CH2_CONFIG_REG 0x98\r
+#define ANX7150_TMDS_CH2_TESTEN 0x20 // u8 position\r
+#define ANX7150_TMDS_CH2_AMP 0x1C // u8 position\r
+#define ANX7150_TMDS_CH2_EMP 0x03 // u8 position\r
+\r
+#define ANX7150_TMDS_CLKCH_CONFIG_REG 0x99\r
+#define ANX7150_TMDS_CLKCH_MUTE 0x80 // u8 position\r
+#define ANX7150_TMDS_CLKCH_TESTEN 0x08 // u8 position\r
+#define ANX7150_TMDS_CLKCH_AMP 0x07 // u8 position\r
+\r
+#define ANX7150_CHIP_CTRL_REG 0x9A\r
+#define ANX7150_CHIP_CTRL_PRBS_GENEN 0x80 // u8 position\r
+#define ANX7150_CHIP_CTRL_LINK_DBGSEL 0x70 // u8 position\r
+#define ANX7150_CHIP_CTRL_VIDCHK_EN 0x08 // u8 position\r
+#define ANX7150_CHIP_CTRL_MISC_TIMER 0x04 // u8 position\r
+#define ANX7150_CHIP_CTRL_PLL_RNG 0x02 // u8 position\r
+#define ANX7150_CHIP_CTRL_PLL_MAN 0x01 // u8 position\r
+\r
+#define ANX7150_CHIP_STATUS_REG 0x9B\r
+#define ANX7150_CHIP_STATUS_GPIO 0x80 // u8 position\r
+#define ANX7150_CHIP_STATUS_SDA 0x40 // u8 position\r
+#define ANX7150_CHIP_STATUS_SCL 0x20 // u8 position\r
+#define ANX7150_CHIP_STATUS_PLL_HSPO 0x04 // u8 position\r
+#define ANX7150_CHIP_STATUS_PLL_LOCK 0x02 // u8 position\r
+#define ANX7150_CHIP_STATUS_MISC_LOCK 0x01 // u8 position\r
+\r
+#define ANX7150_DBG_PINGPIO_CTRL_REG 0x9C\r
+#define ANX7150_DBG_PINGPIO_VDLOW_SHAREDEN 0x04 // u8 position\r
+#define ANX7150_DBG_PINGPIO_GPIO_ADDREN 0x02 // u8 position\r
+#define ANX7150_DBG_PINGPIO_GPIO_OUT 0x01 // u8 position\r
+\r
+#define ANX7150_CHIP_DEBUG0_CTRL_REG 0x9D\r
+#define ANX7150_CHIP_DEBUG0_PRBS_ERR 0xE0 // u8 position\r
+#define ANX7150_CHIP_DEBUG0_CAPST 0x1F // u8 position\r
+\r
+#define ANX7150_CHIP_DEBUG1_CTRL_REG 0x9E\r
+#define ANX7150_CHIP_DEBUG1_SDA_SW 0x80 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_SCL_SW 0x40 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_SERDES_TESTEN 0x20 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_CLK_BYPASS 0x10 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_FORCE_PLLLOCK 0x08 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_PLLLOCK_BYPASS 0x04 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_FORCE_HP 0x02 // u8 position\r
+#define ANX7150_CHIP_DEBUG1_HP_DEGLITCH 0x01 // u8 position\r
+\r
+#define ANX7150_CHIP_DEBUG2_CTRL_REG 0x9F\r
+#define ANX7150_CHIP_DEBUG2_EXEMB_SYNCEN 0x04 // u8 position\r
+#define ANX7150_CHIP_DEBUG2_VIDBIST 0x02 // u8 position\r
+\r
+#define ANX7150_VID_INCLK_REG 0x5F\r
+\r
+#define ANX7150_HDCP_STATUS_REG 0xA0\r
+#define ANX7150_HDCP_STATUS_ADV_CIPHER 0x80 // u8 position\r
+#define ANX7150_HDCP_STATUS_R0_READY 0x10 // u8 position\r
+#define ANX7150_HDCP_STATUS_AKSV_ACT 0x08 // u8 position\r
+#define ANX7150_HDCP_STATUS_ENCRYPT 0x04 // u8 position\r
+#define ANX7150_HDCP_STATUS_AUTH_PASS 0x02 // u8 position\r
+#define ANX7150_HDCP_STATUS_KEY_DONE 0x01 // u8 position\r
+\r
+#define ANX7150_HDCP_CTRL0_REG 0xA1\r
+#define ANX7150_HDCP_CTRL0_STORE_AN 0x80 // u8 position\r
+#define ANX7150_HDCP_CTRL0_RX_REP 0x40 // u8 position\r
+#define ANX7150_HDCP_CTRL0_RE_AUTH 0x20 // u8 position\r
+#define ANX7150_HDCP_CTRL0_SW_AUTHOK 0x10 // u8 position\r
+#define ANX7150_HDCP_CTRL0_HW_AUTHEN 0x08 // u8 position\r
+#define ANX7150_HDCP_CTRL0_ENC_EN 0x04 // u8 position\r
+#define ANX7150_HDCP_CTRL0_BKSV_SRM 0x02 // u8 position\r
+#define ANX7150_HDCP_CTRL0_KSV_VLD 0x01 // u8 position\r
+\r
+#define ANX7150_HDCP_CTRL1_REG 0xA2\r
+#define ANX7150_LINK_CHK_12_EN 0x40\r
+#define ANX7150_HDCP_CTRL1_DDC_NOSTOP 0x20 // u8 position\r
+#define ANX7150_HDCP_CTRL1_DDC_NOACK 0x10 // u8 position\r
+#define ANX7150_HDCP_CTRL1_EDDC_NOACK 0x08 // u8 position\r
+#define ANX7150_HDCP_CTRL1_BLUE_SCREEN_EN 0x04 // u8 position\r
+#define ANX7150_HDCP_CTRL1_RCV11_EN 0x02 // u8 position\r
+#define ANX7150_HDCP_CTRL1_HDCP11_EN 0x01 // u8 position\r
+\r
+#define ANX7150_HDCP_Link_Check_FRAME_NUM_REG 0xA3\r
+#define ANX7150_HDCP_AKSV1_REG 0xA5\r
+#define ANX7150_HDCP_AKSV2_REG 0xA6\r
+#define ANX7150_HDCP_AKSV3_REG 0xA7\r
+#define ANX7150_HDCP_AKSV4_REG 0xA8\r
+#define ANX7150_HDCP_AKSV5_REG 0xA9\r
+\r
+#define ANX7150_HDCP_AN1_REG 0xAA\r
+#define ANX7150_HDCP_AN2_REG 0xAB\r
+#define ANX7150_HDCP_AN3_REG 0xAC\r
+#define ANX7150_HDCP_AN4_REG 0xAD\r
+#define ANX7150_HDCP_AN5_REG 0xAE\r
+#define ANX7150_HDCP_AN6_REG 0xAF\r
+#define ANX7150_HDCP_AN7_REG 0xB0\r
+#define ANX7150_HDCP_AN8_REG 0xB1\r
+\r
+#define ANX7150_HDCP_BKSV1_REG 0xB2\r
+#define ANX7150_HDCP_BKSV2_REG 0xB3\r
+#define ANX7150_HDCP_BKSV3_REG 0xB4\r
+#define ANX7150_HDCP_BKSV4_REG 0xB5\r
+#define ANX7150_HDCP_BKSV5_REG 0xB6\r
+\r
+#define ANX7150_HDCP_RI1_REG 0xB7\r
+#define ANX7150_HDCP_RI2_REG 0xB8\r
+\r
+#define ANX7150_HDCP_PJ_REG 0xB9\r
+#define ANX7150_HDCP_RX_CAPS_REG 0xBA\r
+#define ANX7150_HDCP_BSTATUS0_REG 0xBB\r
+#define ANX7150_HDCP_BSTATUS1_REG 0xBC\r
+\r
+#define ANX7150_HDCP_AMO0_REG 0xD0\r
+#define ANX7150_HDCP_AMO1_REG 0xD1\r
+#define ANX7150_HDCP_AMO2_REG 0xD2\r
+#define ANX7150_HDCP_AMO3_REG 0xD3\r
+#define ANX7150_HDCP_AMO4_REG 0xD4\r
+#define ANX7150_HDCP_AMO5_REG 0xD5\r
+#define ANX7150_HDCP_AMO6_REG 0xD6\r
+#define ANX7150_HDCP_AMO7_REG 0xD7\r
+\r
+#define ANX7150_HDCP_DBG_CTRL_REG 0xBD\r
+\r
+#define ANX7150_HDCP_DBG_ENC_INC 0x08 // u8 position\r
+#define ANX7150_HDCP_DBG_DDC_SPEED 0x06 // u8 position\r
+#define ANX7150_HDCP_DBG_SKIP_RPT 0x01 // u8 position\r
+\r
+#define ANX7150_HDCP_KEY_STATUS_REG 0xBE\r
+#define ANX7150_HDCP_KEY_BIST_EN 0x04 // u8 position\r
+#define ANX7150_HDCP_KEY_BIST_ERR 0x02 // u8 position\r
+#define ANX7150_HDCP_KEY_CMD_DONE 0x01 // u8 position\r
+\r
+#define ANX7150_KEY_CMD_REGISTER 0xBF //added\r
+\r
+#define ANX7150_HDCP_AUTHDBG_STATUS_REG 0xC7\r
+#define ANX7150_HDCP_ENCRYPTDBG_STATUS_REG 0xC8\r
+#define ANX7150_HDCP_FRAME_NUM_REG 0xC9\r
+\r
+#define ANX7150_DDC_MSTR_INTER_REG 0xCA\r
+#define ANX7150_DDC_MSTR_LINK_REG 0xCB\r
+\r
+#define ANX7150_HDCP_BLUESCREEN0_REG 0xCC\r
+#define ANX7150_HDCP_BLUESCREEN1_REG 0xCD\r
+#define ANX7150_HDCP_BLUESCREEN2_REG 0xCE\r
+// DEV_ADDR = 0x7A or 0x7E\r
+#define ANX7150_INFO_PKTCTRL1_REG 0xC0\r
+#define ANX7150_INFO_PKTCTRL1_SPD_RPT 0x80 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_SPD_EN 0x40 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_AVI_RPT 0x20 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_AVI_EN 0x10 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_GCP_RPT 0x08 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_GCP_EN 0x04 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_ACR_NEW 0x02 // u8 position\r
+#define ANX7150_INFO_PKTCTRL1_ACR_EN 0x01 // u8 position\r
+\r
+#define ANX7150_INFO_PKTCTRL2_REG 0xC1\r
+#define ANX7150_INFO_PKTCTRL2_UD1_RPT 0x80 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_UD1_EN 0x40 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_UD0_RPT 0x20 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_UD0_EN 0x10 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_MPEG_RPT 0x08 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_MPEG_EN 0x04 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_AIF_RPT 0x02 // u8 position\r
+#define ANX7150_INFO_PKTCTRL2_AIF_EN 0x01 // u8 position\r
+\r
+#define ANX7150_ACR_N1_SW_REG 0xC2\r
+#define ANX7150_ACR_N2_SW_REG 0xC3\r
+#define ANX7150_ACR_N3_SW_REG 0xC4\r
+\r
+#define ANX7150_ACR_CTS1_SW_REG 0xC5\r
+#define ANX7150_ACR_CTS2_SW_REG 0xC6\r
+#define ANX7150_ACR_CTS3_SW_REG 0xC7\r
+\r
+#define ANX7150_ACR_CTS1_HW_REG 0xC8\r
+#define ANX7150_ACR_CTS2_HW_REG 0xC9\r
+#define ANX7150_ACR_CTS3_HW_REG 0xCA\r
+\r
+#define ANX7150_ACR_CTS_CTRL_REG 0xCB\r
+\r
+#define ANX7150_GNRL_CTRL_PKT_REG 0xCC\r
+#define ANX7150_GNRL_CTRL_CLR_AVMUTE 0x02 // u8 position\r
+#define ANX7150_GNRL_CTRL_SET_AVMUTE 0x01 // u8 position\r
+\r
+#define ANX7150_AUD_PKT_FLATCTRL_REG 0xCD\r
+#define ANX7150_AUD_PKT_AUTOFLAT_EN 0x80 // u8 position\r
+#define ANX7150_AUD_PKT_FLAT 0x07 // u8 position\r
+\r
+\r
+//select video hardware interface\r
+#define ANX7150_VID_HW_INTERFACE 0x03//0x00:RGB and YcbCr 4:4:4 Formats with Separate Syncs (24-bpp mode)\r
+ //0x01:YCbCr 4:2:2 Formats with Separate Syncs(16-bbp)\r
+ //0x02:YCbCr 4:2:2 Formats with Embedded Syncs(No HS/VS/DE)\r
+ //0x03:YC Mux 4:2:2 Formats with Separate Sync Mode1(u815:8 and u8 3:0 are used)\r
+ //0x04:YC Mux 4:2:2 Formats with Separate Sync Mode2(u811:0 are used)\r
+ //0x05:YC Mux 4:2:2 Formats with Embedded Sync Mode1(u815:8 and u8 3:0 are used)\r
+ //0x06:YC Mux 4:2:2 Formats with Embedded Sync Mode2(u811:0 are used)\r
+ //0x07:RGB and YcbCr 4:4:4 DDR Formats with Separate Syncs\r
+ //0x08:RGB and YcbCr 4:4:4 DDR Formats with Embedded Syncs\r
+ //0x09:RGB and YcbCr 4:4:4 Formats with Separate Syncs but no DE\r
+ //0x0a:YCbCr 4:2:2 Formats with Separate Syncs but no DE\r
+//select input color space\r
+#define ANX7150_INPUT_COLORSPACE 0x01//0x00: input color space is RGB\r
+ //0x01: input color space is YCbCr422\r
+ //0x02: input color space is YCbCr444\r
+//select input pixel clock edge for DDR mode\r
+#define ANX7150_IDCK_EDGE_DDR 0x00 //0x00:use rising edge to latch even numbered pixel data//jack wen\r
+ //0x01:use falling edge to latch even numbered pixel data\r
+\r
+//select audio hardware interface\r
+#define ANX7150_AUD_HW_INTERFACE 0x01//0x01:audio input comes from I2S\r
+ //0x02:audio input comes from SPDIF\r
+ //0x04:audio input comes from one u8 audio\r
+//select MCLK and Fs relationship if audio HW interface is I2S\r
+#define ANX7150_MCLK_Fs_RELATION 0x01//0x00:MCLK = 128 * Fs\r
+ //0x01:MCLK = 256 * Fs\r
+ //0x02:MCLK = 384 * Fs\r
+ //0x03:MCLK = 512 * Fs //wen updated error\r
+\r
+#define ANX7150_AUD_CLK_EDGE 0x00 //0x00:use MCLK and SCK rising edge to latch audio data\r
+ //0x08, revised by wen. //0x80:use MCLK and SCK falling edge to latch audio data\r
+//select I2S channel numbers if audio HW interface is I2S\r
+#define ANX7150_I2S_CH0_ENABLE 0x01 //0x01:enable channel 0 input; 0x00: disable\r
+#define ANX7150_I2S_CH1_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
+#define ANX7150_I2S_CH2_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
+#define ANX7150_I2S_CH3_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
+//select I2S word length if audio HW interface is I2S\r
+#define ANX7150_I2S_WORD_LENGTH 0x0b\r
+ //0x02 = 16u8s; 0x04 = 18 u8s; 0x08 = 19 u8s; 0x0a = 20 u8s(maximal word length is 20u8s); 0x0c = 17 u8s;\r
+ // 0x03 = 20u8s(maximal word length is 24u8s); 0x05 = 22 u8s; 0x09 = 23 u8s; 0x0b = 24 u8s; 0x0d = 21 u8s;\r
+\r
+//select I2S format if audio HW interface is I2S\r
+#define ANX7150_I2S_SHIFT_CTRL 0x00//0x00: fist u8 shift(philips spec)\r
+ //0x01:no shift\r
+#define ANX7150_I2S_DIR_CTRL 0x00//0x00:SD data MSB first\r
+ //0x01:LSB first\r
+#define ANX7150_I2S_WS_POL 0x00//0x00:left polarity when word select is low\r
+ //0x01:left polarity when word select is high\r
+#define ANX7150_I2S_JUST_CTRL 0x00//0x00:data is left justified\r
+ //0x01:data is right justified\r
+\r
+#define EDID_Parse_Enable 1 // cwz 0 for test, 1 normal\r
+//InfoFrame and Control Packet Registers\r
+// 0x7A or 0X7E\r
+/*\r
+#define AVI_HB0 0x00\r
+#define AVI_HB1 0x01\r
+#define AVI_HB2 0x02\r
+#define AVI_PB0 0x03\r
+#define AVI_PB1 0x04\r
+#define AVI_PB2 0x05\r
+#define AVI_PB3 0x06\r
+#define AVI_PB4 0x07\r
+#define AVI_PB5 0x08\r
+#define AVI_PB6 0x09\r
+#define AVI_PB7 0x0A\r
+#define AVI_PB8 0x0B\r
+#define AVI_PB9 0x0C\r
+#define AVI_PB10 0x0D\r
+#define AVI_PB11 0x0E\r
+#define AVI_PB12 0x0F\r
+#define AVI_PB13 0x10\r
+#define AVI_PB14 0x11\r
+#define AVI_PB15 0x12\r
+\r
+#define AUD_HBO 0x20\r
+#define AUD_HB1 0x21\r
+#define AUD_HB2 0x22\r
+#define AUD_PB0 0x23\r
+#define AUD_PB1 0x24\r
+#define AUD_PB2 0x25\r
+#define AUD_PB3 0x26\r
+#define AUD_PB4 0x27\r
+#define AUD_PB5 0x28\r
+#define AUD_PB6 0x29\r
+#define AUD_PB7 0x2A\r
+#define AUD_PB8 0x2B\r
+#define AUD_PB9 0x2C\r
+#define AUD_PB10 0x2D\r
+\r
+#define SPD_HBO 0x40\r
+#define SPD_HB1 0x41\r
+#define SPD_HB2 0x42\r
+#define SPD_PB0 0x43\r
+#define SPD_PB1 0x44\r
+#define SPD_PB2 0x45\r
+#define SPD_PB3 0x46\r
+#define SPD_PB4 0x47\r
+#define SPD_PB5 0x48\r
+#define SPD_PB6 0x49\r
+#define SPD_PB7 0x4A\r
+#define SPD_PB8 0x4B\r
+#define SPD_PB9 0x4C\r
+#define SPD_PB10 0x4D\r
+#define SPD_PB11 0x4E\r
+#define SPD_PB12 0x4F\r
+#define SPD_PB13 0x50\r
+#define SPD_PB14 0x51\r
+#define SPD_PB15 0x52\r
+#define SPD_PB16 0x53\r
+#define SPD_PB17 0x54\r
+#define SPD_PB18 0x55\r
+#define SPD_PB19 0x56\r
+#define SPD_PB20 0x57\r
+#define SPD_PB21 0x58\r
+#define SPD_PB22 0x59\r
+#define SPD_PB23 0x5A\r
+#define SPD_PB24 0x5B\r
+#define SPD_PB25 0x5C\r
+#define SPD_PB26 0x5D\r
+#define SPD_PB27 0x5E\r
+\r
+#define MPEG_HBO 0x60\r
+#define MPEG_HB1 0x61\r
+#define MPEG_HB2 0x62\r
+#define MPEG_PB0 0x63\r
+#define MPEG_PB1 0x64\r
+#define MPEG_PB2 0x65\r
+#define MPEG_PB3 0x66\r
+#define MPEG_PB4 0x67\r
+#define MPEG_PB5 0x68\r
+#define MPEG_PB6 0x69\r
+#define MPEG_PB7 0x6A\r
+#define MPEG_PB8 0x6B\r
+#define MPEG_PB9 0x6C\r
+#define MPEG_PB10 0x6D\r
+#define MPEG_PB11 0x6E\r
+#define MPEG_PB12 0x6F\r
+#define MPEG_PB13 0x70\r
+#define MPEG_PB14 0x71\r
+#define MPEG_PB15 0x72\r
+#define MPEG_PB16 0x73\r
+#define MPEG_PB17 0x74\r
+#define MPEG_PB18 0x75\r
+#define MPEG_PB19 0x76\r
+#define MPEG_PB20 0x77\r
+#define MPEG_PB21 0x78\r
+#define MPEG_PB22 0x79\r
+#define MPEG_PB23 0x7A\r
+#define MPEG_PB24 0x7B\r
+#define MPEG_PB25 0x7C\r
+#define MPEG_PB26 0x7D\r
+#define MPEG_PB27 0x7E\r
+\r
+#define USRDF0_HBO 0x80\r
+#define USRDF0_HB1 0x81\r
+#define USRDF0_HB2 0x82\r
+#define USRDF0_PB0 0x83\r
+#define USRDF0_PB1 0x84\r
+#define USRDF0_PB2 0x85\r
+#define USRDF0_PB3 0x86\r
+#define USRDF0_PB4 0x87\r
+#define USRDF0_PB5 0x88\r
+#define USRDF0_PB6 0x89\r
+#define USRDF0_PB7 0x8A\r
+#define USRDF0_PB8 0x8B\r
+#define USRDF0_PB9 0x8C\r
+#define USRDF0_PB10 0x8D\r
+#define USRDF0_PB11 0x8E\r
+#define USRDF0_PB12 0x8F\r
+#define USRDF0_PB13 0x90\r
+#define USRDF0_PB14 0x91\r
+#define USRDF0_PB15 0x92\r
+#define USRDF0_PB16 0x93\r
+#define USRDF0_PB17 0x94\r
+#define USRDF0_PB18 0x95\r
+#define USRDF0_PB19 0x96\r
+#define USRDF0_PB20 0x97\r
+#define USRDF0_PB21 0x98\r
+#define USRDF0_PB22 0x99\r
+#define USRDF0_PB23 0x9A\r
+#define USRDF0_PB24 0x9B\r
+#define USRDF0_PB25 0x9C\r
+#define USRDF0_PB26 0x9D\r
+#define USRDF0_PB27 0x9E\r
+\r
+#define USRDF1_HBO 0xA0\r
+#define USRDF1_HB1 0xA1\r
+#define USRDF1_HB2 0xA2\r
+#define USRDF1_PB0 0xA3\r
+#define USRDF1_PB1 0xA4\r
+#define USRDF1_PB2 0xA5\r
+#define USRDF1_PB3 0xA6\r
+#define USRDF1_PB4 0xA7\r
+#define USRDF1_PB5 0xA8\r
+#define USRDF1_PB6 0xA9\r
+#define USRDF1_PB7 0xAA\r
+#define USRDF1_PB8 0xAB\r
+#define USRDF1_PB9 0xAC\r
+#define USRDF1_PB10 0xAD\r
+#define USRDF1_PB11 0xAE\r
+#define USRDF1_PB12 0xAF\r
+#define USRDF1_PB13 0xB0\r
+#define USRDF1_PB14 0xB1\r
+#define USRDF1_PB15 0xB2\r
+#define USRDF1_PB16 0xB3\r
+#define USRDF1_PB17 0xB4\r
+#define USRDF1_PB18 0xB5\r
+#define USRDF1_PB19 0xB6\r
+#define USRDF1_PB20 0xB7\r
+#define USRDF1_PB21 0xB8\r
+#define USRDF1_PB22 0xB9\r
+#define USRDF1_PB23 0xBA\r
+#define USRDF1_PB24 0xBB\r
+#define USRDF1_PB25 0xBC\r
+#define USRDF1_PB26 0xBD\r
+#define USRDF1_PB27 0xBE\r
+*/\r
+ int anx7150_get_hpd(struct i2c_client *client);\r
+\r
+void ANX7150_API_HDCP_ONorOFF(u8 HDCP_ONorOFF);\r
+int anx7150_detect_device(struct anx7150_pdata *anx);\r
+u8 ANX7150_Get_System_State(void);\r
+int ANX7150_Interrupt_Process(struct anx7150_pdata *anx, int cur_state);\r
+int anx7150_unplug(struct i2c_client *client);\r
+int anx7150_plug(struct i2c_client *client);\r
+int ANX7150_API_Initial(struct i2c_client *client);\r
+void ANX7150_Shutdown(struct i2c_client *client);\r
+int ANX7150_Parse_EDID(struct i2c_client *client, struct anx7150_dev_s *dev);\r
+int ANX7150_GET_SENSE_STATE(struct i2c_client *client);\r
+int ANX7150_Get_Optimal_resolution(int resolution_set);\r
+void HDMI_Set_Video_Format(u8 video_format);\r
+void HDMI_Set_Audio_Fs( u8 audio_fs);\r
+void ANX7150_API_System_Config(void);\r
+u8 ANX7150_Config_Audio(struct i2c_client *client);\r
+u8 ANX7150_Config_Packet(struct i2c_client *client);\r
+void ANX7150_HDCP_Process(struct i2c_client *client,int enable);\r
+int ANX7150_PLAYBACK_Process(void);\r
+void ANX7150_Set_System_State(struct i2c_client *client, u8 new_state);\r
+int ANX7150_Config_Video(struct i2c_client *client);\r
+int ANX7150_GET_RECIVER_TYPE(void);\r
+void HDMI_Set_Video_Format(u8 video_format);\r
+void HDMI_Set_Audio_Fs( u8 audio_fs);\r
+int ANX7150_PLAYBACK_Process(void);\r
+int ANX7150_Blue_Screen(struct anx7150_pdata *anx);\r
+int anx7150_set_avmute(struct i2c_client *client);\r
+int anx7150_initial(struct i2c_client *client);\r
+\r
+#endif\r
+++ /dev/null
-#include <linux/delay.h>\r
-#include <linux/i2c.h>\r
-#include <linux/hdmi.h>\r
-#include <linux/slab.h>\r
-\r
-#include "anx7150.h"\r
-#include "anx7150_hw.h"\r
-//#ifdef ITU656\r
-struct ANX7150_video_timingtype ANX7150_video_timingtype_table =\r
-{\r
- //640x480p-60hz\r
- {0x20/*H_RES_LOW*/, 0x03/*H_RES_HIGH*/,0x80 /*ACT_PIX_LOW*/,0x02 /*ACT_PIX_HIGH*/,\r
- 0x60/*HSYNC_WIDTH_LOW*/,0x00 /*HSYNC_WIDTH_HIGH*/,0x30 /*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
- 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/,0x02 /*VSYNC_WIDTH*/, 0x21/*V_BP_LINE*/,\r
- 0x0a/*V_FP_LINE*/,0x10 /*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
- //720x480p-60hz\r
- {0x5a/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0/*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
- 0x3e/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x3c/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/, 0x06/*VSYNC_WIDTH*/, 0x1e/*V_BP_LINE*/,\r
- 0x09/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
- //720p-60hz\r
- {0x72/*H_RES_LOW*/, 0x06/*H_RES_HIGH*/, 0x00/*ACT_PIX_LOW*/, 0x05/*ACT_PIX_HIGH*/,\r
- 0x28/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0xdc/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0xd0/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x14/*V_BP_LINE*/,\r
- 0x05/*V_FP_LINE*/, 0x6e/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Progressive, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
- //1080i-60hz\r
- {0x98/*H_RES_LOW*/, 0x08/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
- 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
- 0x02/*V_FP_LINE*/, 0x58/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
- //720x480i-60hz\r
- {0x5a/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0/*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
- 0x3e/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x39/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0xe0/*ACT_LINE_LOW*/, 0x01/*ACT_LINE_HIGH*/, 0x03/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
- 0x04/*V_FP_LINE*/, 0x13/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol}, //update\r
- //1080p-60hz\r
- {0x98/*H_RES_LOW*/, 0x08/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
- 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x24/*V_BP_LINE*/,\r
- 0x04/*V_FP_LINE*/, 0x58/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
- //576p-50hz\r
- {0x60/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0 /*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
- 0x40/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x44/*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
- 0x40/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x27/*V_BP_LINE*/,\r
- 0x05/*V_FP_LINE*/, 0x0c/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Progressive, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
- //720p-50hz\r
- {0xbc/*H_RES_LOW*/, 0x07/*H_RES_HIGH*/, 0x00/*ACT_PIX_LOW*/, 0x05/*ACT_PIX_HIGH*/,\r
- 0x28/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0xdc/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0xd0/*ACT_LINE_LOW*/, 0x02/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x14/*V_BP_LINE*/,\r
- 0x05/*V_FP_LINE*/, 0xb8/*H_FP_LOW*/, 0x01/*H_FP_HIGH*/,\r
- ANX7150_Progressive, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
- //1080i-50hz\r
- {0x50/*H_RES_LOW*/, 0x0a/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
- 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x0f/*V_BP_LINE*/,\r
- 0x02/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x02/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
- //576i-50hz\r
- {0x60/*H_RES_LOW*/,0x03 /*H_RES_HIGH*/,0xd0 /*ACT_PIX_LOW*/, 0x02/*ACT_PIX_HIGH*/,\r
- 0x3f/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x45/*H_BP_LOW*/,0x00 /*H_BP_HIGH*/,\r
- 0x40/*ACT_LINE_LOW*/,0x02 /*ACT_LINE_HIGH*/, 0x03/*VSYNC_WIDTH*/, 0x13/*V_BP_LINE*/,\r
- 0x02/*V_FP_LINE*/, 0x0c/*H_FP_LOW*/, 0x00/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Neg_Hsync_pol, ANX7150_Neg_Vsync_pol},\r
- \r
- //1080p-50hz\r
- {0x50/*H_RES_LOW*/, 0x0a/*H_RES_HIGH*/, 0x80/*ACT_PIX_LOW*/, 0x07/*ACT_PIX_HIGH*/,\r
- 0x2c/*HSYNC_WIDTH_LOW*/, 0x00/*HSYNC_WIDTH_HIGH*/, 0x94/*H_BP_LOW*/, 0x00/*H_BP_HIGH*/,\r
- 0x38/*ACT_LINE_LOW*/, 0x04/*ACT_LINE_HIGH*/, 0x05/*VSYNC_WIDTH*/, 0x24/*V_BP_LINE*/,\r
- 0x04/*V_FP_LINE*/, 0x10/*H_FP_LOW*/, 0x02/*H_FP_HIGH*/,\r
- ANX7150_Interlace, ANX7150_Pos_Hsync_pol, ANX7150_Pos_Vsync_pol},\r
-};\r
-//#endif\r
-int anx7150_mass_read_need_delay = 0;\r
-\r
-u8 g_video_format = 0x00;\r
-u8 g_audio_format = 0x00;\r
-\r
-\r
-u8 timer_slot = 0;\r
-u8 *ANX7150_EDID_Buf = NULL;\r
-u8 ANX7150_avi_data[19];//, ANX7150_avi_checksum;\r
-u8 ANX7150_system_state = HDMI_INITIAL;\r
-u8 spdif_error_cnt = 0x00;\r
-u8 misc_reset_needed;\r
-u8 ANX7150_stdaddr,ANX7150_stdreg,ANX7150_ext_block_num;\r
-u8 ANX7150_svd_length,ANX7150_sau_length;\r
-u8 ANX7150_edid_dtd[18];\r
-u32 ANX7150_edid_length;\r
-ANX7150_edid_result_4_system ANX7150_edid_result;\r
-\r
-u8 ANX7150_ddc_fifo_full;\r
-u8 ANX7150_ddc_progress;\r
-u8 ANX7150_hdcp_auth_en;\r
-//u8 ANX7150_bksv_ready; //replace by srm_checked xy 01.09\r
-u8 ANX7150_HDCP_enable;\r
-u8 ANX7150_ksv_srm_pass;\r
-u8 ANX7150_hdcp_bcaps;\r
-u8 ANX7150_hdcp_bstatus[2];\r
-u8 ANX7150_srm_checked;\r
-u8 ANX7150_hdcp_auth_pass;\r
-u8 ANX7150_avmute_enable;\r
-u8 ANX7150_send_blue_screen;\r
-u8 ANX7150_hdcp_encryption;\r
-u8 ANX7150_hdcp_init_done;\r
-u8 ANX7150_hdcp_wait_100ms_needed;\r
-u8 ANX7150_auth_fully_pass;\r
-u8 ANX7150_parse_edid_done;//060714 XY\r
-//u8 testen;\r
-//u8 ANX7150_avi_data[19], ANX7150_avi_checksum;\r
-u8 ANX7150_hdcp_auth_fail_counter ;\r
-\r
-u8 ANX7150_video_format_config;\r
-u8 ANX7150_emb_sync_mode,ANX7150_de_gen_en,ANX7150_demux_yc_en,ANX7150_ddr_bus_mode;\r
-u8 ANX7150_ddr_edge,ANX7150_ycmux_u8_sel;\r
-u8 ANX7150_system_config_done;\r
-u8 ANX7150_RGBorYCbCr; //modified by zy 060814\r
-u8 ANX7150_in_pix_rpt,ANX7150_tx_pix_rpt;\r
-u8 ANX7150_in_pix_rpt_bkp,ANX7150_tx_pix_rpt_bkp;\r
-u8 ANX7150_video_timing_id;\r
-u8 ANX7150_pix_rpt_set_by_sys;\r
-u8 ANX7150_video_timing_parameter[18];\r
-u8 switch_value_sw_backup,switch_value_pc_backup;\r
-u8 switch_value,bist_switch_value_pc;\r
-u8 ANX7150_new_csc,ANX7150_new_vid_id,ANX7150_new_HW_interface;\r
-u8 ANX7150_INT_Done;\r
-\r
-audio_config_struct s_ANX7150_audio_config;\r
-config_packets s_ANX7150_packet_config;\r
-\r
-u8 FREQ_MCLK; //0X72:0X50 u82:0\r
-//000b:Fm = 128*Fs\r
-//001b:Fm = 256*Fs\r
-//010b:Fm = 384*Fs\r
-//011b:Fm = 512*Fs\r
-u8 ANX7150_audio_clock_edge;\r
-int ANX7150_DDC_Mass_Read(struct i2c_client *client, u8 *buf, u16 len);\r
-\r
-int anx7150_detect_device(struct anx7150_pdata *anx)\r
-{\r
- int i, rc = 0; \r
- char d1, d2;\r
- \r
- for (i=0; i<10; i++) \r
- { \r
- if((rc = anx7150_i2c_read_p0_reg(anx->client, ANX7150_DEV_IDL_REG, &d1)) < 0) \r
- continue;\r
- if((rc = anx7150_i2c_read_p0_reg(anx->client, ANX7150_DEV_IDH_REG, &d2)) < 0) \r
- continue;\r
- if (d1 == 0x50 && d2 == 0x71)\r
- { \r
- hdmi_dbg(&anx->client->dev, "anx7150 detected!\n");\r
- return 0;\r
- } \r
- } \r
- \r
- hdmi_dbg(&anx->client->dev, "anx7150 not detected");\r
- return -1;\r
-}\r
-u8 ANX7150_Get_System_State(void)\r
-{\r
- return ANX7150_system_state;\r
-}\r
-void ANX7150_Set_System_State(struct i2c_client *client, u8 new_state)\r
-{\r
- ANX7150_system_state = new_state;\r
- switch (ANX7150_system_state)\r
- {\r
- case HDMI_INITIAL:\r
- hdmi_dbg(&client->dev, "INITIAL\n");\r
- break;\r
- case WAIT_HOTPLUG:\r
- hdmi_dbg(&client->dev, "WAIT_HOTPLUG\n");\r
- break;\r
- case READ_PARSE_EDID:\r
- hdmi_dbg(&client->dev, "READ_PARSE_EDID\n");\r
- break;\r
- case WAIT_RX_SENSE:\r
- hdmi_dbg(&client->dev, "WAIT_RX_SENSE\n");\r
- break;\r
- case WAIT_HDMI_ENABLE:\r
- hdmi_dbg(&client->dev, "WAIT_HDMI_ENABLE\n");\r
- break;\r
- case SYSTEM_CONFIG:\r
- hdmi_dbg(&client->dev, "SYSTEM_CONFIG\n");\r
- break;\r
- case CONFIG_VIDEO:\r
- dev_info(&client->dev, "CONFIG_VIDEO\n");\r
- break;\r
- case CONFIG_AUDIO:\r
- hdmi_dbg(&client->dev, "CONFIG_AUDIO\n");\r
- break;\r
- case CONFIG_PACKETS:\r
- hdmi_dbg(&client->dev, "CONFIG_PACKETS\n");\r
- break;\r
- case HDCP_AUTHENTICATION:\r
- hdmi_dbg(&client->dev, "HDCP_AUTHENTICATION\n");\r
- break;\r
- ////////////////////////////////////////////////\r
- // System ANX7150_RESET_LINK is kept for RX clock recovery error case, not used in normal case.\r
- case RESET_LINK:\r
- hdmi_dbg(&client->dev, "RESET_LINK\n");\r
- break;\r
- ////////////////////////////////////////////////\r
- case PLAY_BACK:\r
- dev_info(&client->dev, "PLAY_BACK\n");\r
- break;\r
- default:\r
- hdmi_dbg(&client->dev, "unknown state\n");\r
- break;\r
- }\r
-}\r
-\r
-int anx7150_get_hpd(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char sys_ctl3, intr_state, sys_state, hpd_state;\r
- \r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &sys_ctl3)) < 0)\r
- return rc;\r
- if(sys_ctl3 & ANX7150_SYS_CTRL3_PWON_ALL)\r
- {\r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &sys_state)) < 0)\r
- return rc;\r
- hpd_state = (sys_state & ANX7150_SYS_STATE_HP)? 1:0;\r
- }\r
- else\r
- {\r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR_STATE_REG, &intr_state)) < 0)\r
- return rc;\r
- hpd_state = (intr_state)? 1:0;\r
- }\r
- return hpd_state;\r
-}\r
-static int anx7150_get_interrupt_status(struct i2c_client *client, struct anx7150_interrupt_s *interrupt_staus)\r
-{\r
- int rc = 0;\r
- u8 int_s1;\r
- u8 int_s2;\r
- u8 int_s3;\r
- \r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_STATUS_REG, &int_s1);//jack wen, for spdif input from SD0.\r
- rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_STATUS_REG, &int_s1);//power down all, 090630\r
- rc |= anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_STATUS_REG, &int_s2);//jack wen, for spdif input from SD0.\r
- rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_STATUS_REG, &int_s2);//power down all, 090630\r
- rc |= anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_STATUS_REG, &int_s3);//jack wen, for spdif input from SD0.\r
- rc |= anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_STATUS_REG, &int_s3);//power down all, 090630\r
-\r
- interrupt_staus->hotplug_change = (int_s1 & ANX7150_INTR1_STATUS_HP_CHG) ? 1 : 0;\r
- interrupt_staus->video_format_change = (int_s3 & ANX7150_INTR3_STATUS_VIDF_CHG) ? 1 : 0;\r
- interrupt_staus->auth_done = (int_s2 & ANX7150_INTR2_STATUS_AUTH_DONE) ? 1 : 0;\r
- interrupt_staus->auth_state_change = (int_s2 & ANX7150_INTR2_STATUS_AUTH_CHG) ? 1 : 0;\r
- interrupt_staus->pll_lock_change = (int_s2 & ANX7150_INTR2_STATUS_PLLLOCK_CHG) ? 1 : 0;\r
- interrupt_staus->rx_sense_change = (int_s3 & ANX7150_INTR3_STATUS_RXSEN_CHG) ? 1 : 0;\r
- interrupt_staus->HDCP_link_change = (int_s2 & ANX7150_INTR2_STATUS_HDCPLINK_CHK) ? 1 : 0;\r
- interrupt_staus->audio_clk_change = (int_s3 & ANX7150_INTR3_STATUS_AUDCLK_CHG) ? 1 : 0;\r
- interrupt_staus->audio_FIFO_overrun = (int_s1 & ANX7150_INTR1_STATUS_AFIFO_OVER) ? 1 : 0;\r
- interrupt_staus->SPDIF_error = (int_s1 & ANX7150_INTR1_STATUS_SPDIF_ERR) ? 1 : 0;\r
- interrupt_staus->SPDIF_bi_phase_error = ((int_s3 & ANX7150_INTR3_STATUS_SPDIFBI_ERR) ? 1 : 0) \r
- || ((int_s3 & ANX7150_INTR3_STATUS_SPDIF_UNSTBL) ? 1 : 0);\r
- return 0;\r
-}\r
-static void ANX7150_Variable_Initial(void)\r
-{\r
- u8 i;\r
-\r
- ANX7150_hdcp_auth_en = 0;\r
- ANX7150_ksv_srm_pass =0;\r
- ANX7150_srm_checked = 0;\r
- ANX7150_hdcp_auth_pass = 0;\r
- ANX7150_avmute_enable = 1;\r
- ANX7150_hdcp_auth_fail_counter =0;\r
- ANX7150_hdcp_encryption = 0;\r
- ANX7150_send_blue_screen = 0;\r
- ANX7150_hdcp_init_done = 0;\r
- ANX7150_hdcp_wait_100ms_needed = 1;\r
- ANX7150_auth_fully_pass = 0;\r
- timer_slot = 0;\r
- //********************for video config**************\r
- ANX7150_video_timing_id = 0;\r
- ANX7150_in_pix_rpt = 0;\r
- ANX7150_tx_pix_rpt = 0;\r
- ANX7150_new_csc = 0;\r
- ANX7150_new_vid_id = 0;\r
- ANX7150_new_HW_interface = 0;\r
- //********************end of video config*********\r
-\r
- //********************for edid parse***********\r
- ANX7150_edid_result.is_HDMI = 1;\r
- ANX7150_edid_result.ycbcr422_supported = 0;\r
- ANX7150_edid_result.ycbcr444_supported = 0;\r
- ANX7150_edid_result.supported_720p_60Hz = 0;\r
- ANX7150_edid_result.supported_720p_50Hz = 0;\r
- ANX7150_edid_result.supported_576p_50Hz = 0;\r
- ANX7150_edid_result.supported_576i_50Hz = 0;\r
- ANX7150_edid_result.supported_1080i_60Hz = 0;\r
- ANX7150_edid_result.supported_1080i_50Hz = 0;\r
- ANX7150_edid_result.supported_640x480p_60Hz = 0;\r
- ANX7150_edid_result.supported_720x480p_60Hz = 0;\r
- ANX7150_edid_result.supported_720x480i_60Hz = 0;\r
- ANX7150_edid_result.edid_errcode = 0;\r
- ANX7150_edid_result.SpeakerFormat = 0;\r
- for (i = 0; i < 8; i ++)\r
- {\r
- ANX7150_edid_result.AudioChannel[i] = 0;\r
- ANX7150_edid_result.AudioFormat[i] = 0;\r
- ANX7150_edid_result.AudioFs[i] = 0;\r
- ANX7150_edid_result.AudioLength[i] = 0;\r
- }\r
- //********************end of edid**************\r
-\r
- s_ANX7150_packet_config.packets_need_config = 0x03; //new avi infoframe\r
- s_ANX7150_packet_config.avi_info.type = 0x82;\r
- s_ANX7150_packet_config.avi_info.version = 0x02;\r
- s_ANX7150_packet_config.avi_info.length = 0x0d;\r
- s_ANX7150_packet_config.avi_info.pb_u8[1] = 0x21;//YCbCr422\r
- s_ANX7150_packet_config.avi_info.pb_u8[2] = 0x08;\r
- s_ANX7150_packet_config.avi_info.pb_u8[3] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[4] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[5] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[6] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[7] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[8] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[9] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[10] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[11] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[12] = 0x00;\r
- s_ANX7150_packet_config.avi_info.pb_u8[13] = 0x00;\r
-\r
- // audio infoframe\r
- s_ANX7150_packet_config.audio_info.type = 0x84;\r
- s_ANX7150_packet_config.audio_info.version = 0x01;\r
- s_ANX7150_packet_config.audio_info.length = 0x0a;\r
- s_ANX7150_packet_config.audio_info.pb_u8[1] = 0x00; //zy 061123 for ATC\r
- s_ANX7150_packet_config.audio_info.pb_u8[2] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[3] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[4] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[5] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[6] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[7] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[8] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[9] = 0x00;\r
- s_ANX7150_packet_config.audio_info.pb_u8[10] = 0x00;\r
-\r
- ANX7150_INT_Done = 0;\r
-}\r
-static void ANX7150_HW_Interface_Variable_Initial(void)\r
-{\r
- u8 c;\r
-\r
- ANX7150_video_format_config = 0x00;\r
- ANX7150_RGBorYCbCr = 0x00;\r
- ANX7150_ddr_edge = ANX7150_IDCK_EDGE_DDR;\r
-\r
- c = 0;\r
- c = (ANX7150_I2S_CH0_ENABLE << 2) | (ANX7150_I2S_CH1_ENABLE << 3) |\r
- (ANX7150_I2S_CH2_ENABLE << 4) | (ANX7150_I2S_CH3_ENABLE << 5);\r
- s_ANX7150_audio_config.audio_type = ANX7150_AUD_HW_INTERFACE; // input I2S\r
- s_ANX7150_audio_config.down_sample = 0x00;\r
- s_ANX7150_audio_config.i2s_config.audio_channel = c;//0x04;\r
- s_ANX7150_audio_config.i2s_config.Channel_status1 =0x00;\r
- s_ANX7150_audio_config.i2s_config.Channel_status1 = 0x00;\r
- s_ANX7150_audio_config.i2s_config.Channel_status2 = 0x00;\r
- s_ANX7150_audio_config.i2s_config.Channel_status3 = 0x00;\r
- s_ANX7150_audio_config.i2s_config.Channel_status4 = 0x00;//0x02;//48k\r
- s_ANX7150_audio_config.i2s_config.Channel_status5 = ANX7150_I2S_WORD_LENGTH;//0x0b;\r
- s_ANX7150_audio_config.audio_layout = 0x00;\r
-\r
- c = (ANX7150_I2S_SHIFT_CTRL << 3) | (ANX7150_I2S_DIR_CTRL << 2) |\r
- (ANX7150_I2S_WS_POL << 1) | ANX7150_I2S_JUST_CTRL;\r
- s_ANX7150_audio_config.i2s_config.i2s_format = c;//0x00;\r
-\r
- FREQ_MCLK = ANX7150_MCLK_Fs_RELATION;//set the relation of MCLK and WS\r
- ANX7150_audio_clock_edge = ANX7150_AUD_CLK_EDGE;\r
-\r
-\r
-}\r
-static int anx7150_hardware_initial(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c = 0;\r
- \r
- //clear HDCP_HPD_RST\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
- c |= (0x01);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
-\r
- mdelay(10);\r
-\r
- c &= (~0x01);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
- \r
- //Power on I2C\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
- c |= (ANX7150_SYS_CTRL3_I2C_PWON);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
- c= 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
-\r
- //clear HDCP_HPD_RST\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c &= (0xbf);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
-\r
- //Power on Audio capture and Video capture module clock\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_PD_REG, &c);\r
- c |= (0x06);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_PD_REG, &c);\r
-\r
- //Enable auto set clock range for video PLL\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_CTRL_REG, &c);\r
- c &= (0x00);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_CHIP_CTRL_REG, &c);\r
-\r
- //Set registers value of Blue Screen when HDCP authentication failed--RGB mode,green field\r
- c = 0x10;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
- c = 0xeb;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
- c = 0x10;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
-\r
- //ANX7150_i2c_read_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, (c | 0x80));\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_PLL_CTRL0_REG, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_CTRL0_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);\r
- c |= (0x08);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_PLL_TX_AMP, &c);//jack wen\r
- c |= (0x01);\r
-\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_TX_AMP, &c); //TMDS swing\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_PLL_CTRL1_REG, &c); //Added for PLL unlock issue in high temperature - Feiw\r
- //if (ANX7150_AUD_HW_INTERFACE == 0x02) //jack wen, spdif\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);//jack wen, for spdif input from SD0.\r
- c &= (0xef);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);\r
-\r
- c = 0xc7;\r
- rc = anx7150_i2c_write_p0_reg(client, 0xE1, &c);\r
-\r
- //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);//power down HDCP, 090630\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//jack wen, for spdif input from SD0.\r
- c &= (0xfe);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//power down all, 090630\r
-\r
- return rc;\r
-}\r
-\r
-int anx7150_rst_ddcchannel(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- //Reset the DDC channel\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
-\r
- c |= (ANX7150_SYS_CTRL2_DDC_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
-\r
- c &= (~ANX7150_SYS_CTRL2_DDC_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
-\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//abort current operation\r
-\r
- c = 0x06;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//reset I2C command\r
-\r
- //Clear FIFO\r
- c = 0x05;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);//reset I2C command\r
-\r
- return rc;\r
-}\r
-\r
-int anx7150_initial(struct i2c_client *client)
-{
- ANX7150_Variable_Initial(); //simon\r
- ANX7150_HW_Interface_Variable_Initial(); //simon\r
- \r
- anx7150_hardware_initial(client); //simon\r
- return 0;
-}
-int anx7150_unplug(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- dev_info(&client->dev, "anx7150 unplug\n");\r
- \r
- //wen HDCP CTS\r
- ANX7150_Variable_Initial(); //simon\r
- ANX7150_HW_Interface_Variable_Initial(); //simon\r
- \r
- rc = anx7150_hardware_initial(client); //simon\r
- if(rc < 0)\r
- dev_err(&client->dev, "%s>> i2c transfer err\n", __func__);\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c); //simon\r
- if(rc < 0)\r
- dev_err(&client->dev, "%s>> i2c transfer err\n", __func__);\r
- //wen HDCP CTS\r
- ANX7150_hdcp_wait_100ms_needed = 1;\r
- ANX7150_auth_fully_pass = 0;\r
-\r
- // clear ANX7150_parse_edid_done & ANX7150_system_config_done\r
- ANX7150_parse_edid_done = 0;\r
-// ANX7150_system_config_done = 0;\r
- ANX7150_srm_checked = 0;\r
-\r
- return rc;\r
-}\r
-int anx7150_plug(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- dev_info(&client->dev, "anx7150 plug\n");\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);\r
- c |= (0x01);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL3_REG, &c);//power up all, 090630\r
-\r
- //disable audio & video & hdcp & TMDS and init begin\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c &= (~ANX7150_VID_CTRL_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- c &= (~ANX7150_TMDS_CLKCH_MUTE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
-\r
- ANX7150_Variable_Initial();\r
- //disable video & audio & hdcp & TMDS and init end\r
-\r
- \r
- //Power on chip and select DVI mode\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c |= (0x05);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);// cwz change 0x01 -> 0x05\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c &= (0xfd);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
-\r
- //D("ANX7150 is set to DVI mode\n");\r
- rc = anx7150_rst_ddcchannel(client);\r
- //Initial Interrupt\r
- // disable video/audio CLK,Format change and before config video. 060713 xy\r
-\r
- c = 0x04;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_STATUS_REG, &c);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_STATUS_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_STATUS_REG, &c);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_STATUS_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_STATUS_REG, &c);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_STATUS_REG, &c);\r
-\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR_CTRL_REG, &c);\r
-\r
- // clear ANX7150_parse_edid_done & ANX7150_system_config_done\r
- ANX7150_parse_edid_done = 0;\r
-// ANX7150_system_config_done = 0;\r
- ANX7150_srm_checked = 0;\r
-\r
- return rc;\r
-}\r
-\r
-int anx7150_set_avmute(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- c = 0x01;\r
- if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_GNRL_CTRL_PKT_REG, &c)) < 0)\r
- return rc;\r
- \r
- if((rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
- return rc;\r
- c |= (0x0c);\r
- if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
- return rc;\r
- ANX7150_avmute_enable = 1;\r
-\r
- return rc;\r
-}\r
-int anx7150_clear_avmute(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- c = 0x02;\r
- if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_GNRL_CTRL_PKT_REG, &c)) < 0)\r
- return rc;\r
- \r
- if((rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
- return rc;\r
- c |= (0x0c);\r
- if((rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c)) < 0)\r
- return rc;\r
- ANX7150_avmute_enable = 0;\r
-// D("@@@@@@@@@@@@@@@@@@@@ANX7150_Clear_AVMute\n");\r
- return rc;\r
-\r
-}\r
-\r
-static int anx7150_video_format_change(struct i2c_client *client)\r
-{\r
- int rc;\r
- char c;\r
- \r
- hdmi_dbg(&client->dev, "after video format change int \n");\r
- \r
- rc = anx7150_set_avmute(client);//wen\r
- //stop HDCP and reset DDC\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- \r
- rc = anx7150_rst_ddcchannel(client);\r
- \r
- //when format change, clear this reg to avoid error in package config\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
- //xy 11.06 when format change, need system config again\r
- // ANX7150_system_config_done = 0;\r
- return rc;\r
-}\r
-static int anx7150_blue_screen_disable(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
- return rc;\r
- c &= (0xfb);\r
- if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
- return rc;\r
-\r
- ANX7150_send_blue_screen = 0;\r
- \r
- return rc;\r
-}\r
-static int anx7150_blue_screen_enable(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- \r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
- return rc;\r
- c |= (ANX7150_HDCP_CTRL1_BLUE_SCREEN_EN);\r
- if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c)) < 0)\r
- return rc;\r
- ANX7150_send_blue_screen = 1;\r
-\r
- return rc;\r
-}\r
-static int anx7150_hdcp_encryption_enable(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 c;\r
- \r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
- return rc;\r
- c |= (ANX7150_HDCP_CTRL0_ENC_EN);\r
- if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
- return rc;\r
- ANX7150_hdcp_encryption = 1;\r
-\r
- return rc;\r
-}\r
-\r
-static int anx7150_hdcp_encryption_disable(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 c;\r
- \r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
- return rc;\r
- c &= (0xfb);\r
- if((rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c)) < 0)\r
- return rc;\r
-\r
- ANX7150_hdcp_encryption = 0;\r
-\r
- return rc;\r
-}\r
-\r
-static int anx7150_auth_done(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- hdmi_dbg(&client->dev, "anx7150 auth done\n");\r
- \r
- if((rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c)) < 0)\r
- return rc;\r
- \r
- if (c & ANX7150_HDCP_STATUS_AUTH_PASS)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_Authentication pass in Auth_Done\n");\r
- anx7150_blue_screen_disable(client);\r
- ANX7150_hdcp_auth_pass = 1;\r
- ANX7150_hdcp_auth_fail_counter = 0;\r
- }\r
- else\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_Authentication failed\n");\r
- ANX7150_hdcp_wait_100ms_needed = 1;\r
- ANX7150_auth_fully_pass = 0;\r
- ANX7150_hdcp_auth_pass = 0;\r
- ANX7150_hdcp_auth_fail_counter ++;\r
- if (ANX7150_hdcp_auth_fail_counter >= ANX7150_HDCP_FAIL_THRESHOLD)\r
- {\r
- ANX7150_hdcp_auth_fail_counter = 0;\r
- //ANX7150_bksv_ready = 0;\r
- // TODO: Reset link;\r
- rc = anx7150_blue_screen_enable(client);\r
- rc = anx7150_hdcp_encryption_disable(client);\r
- //disable audio\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
- }\r
- return rc;\r
-}\r
-\r
-static int anx7150_clean_hdcp(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- //mute TMDS link\r
- //ANX7150_i2c_read_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, &c);//jack wen\r
- //ANX7150_i2c_write_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, c & (~ANX7150_TMDS_CLKCH_MUTE));\r
-\r
- //Disable hardware HDCP\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- \r
- //Reset HDCP logic\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SRST_REG, &c);\r
- c |= (ANX7150_SRST_HDCP_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
- c &= (~ANX7150_SRST_HDCP_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
-\r
- //Set ReAuth\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c |= (ANX7150_HDCP_CTRL0_RE_AUTH);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_RE_AUTH);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- ANX7150_hdcp_auth_en = 0;\r
- //ANX7150_bksv_ready = 0;\r
- ANX7150_hdcp_auth_pass = 0;\r
- ANX7150_hdcp_auth_fail_counter =0 ;\r
- ANX7150_hdcp_encryption = 0;\r
- ANX7150_send_blue_screen = 0;\r
- ANX7150_hdcp_init_done = 0;\r
- ANX7150_hdcp_wait_100ms_needed = 1;\r
- ANX7150_auth_fully_pass = 0;\r
- ANX7150_srm_checked = 0;\r
- rc = anx7150_rst_ddcchannel(client);\r
-\r
- return rc;\r
-}\r
-static int anx7150_auth_change(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- \r
- int state = ANX7150_Get_System_State();\r
- \r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
- if (c & ANX7150_HDCP_STATUS_AUTH_PASS)\r
- {\r
- ANX7150_hdcp_auth_pass = 1;\r
- hdmi_dbg(&client->dev, "ANX7150_Authentication pass in Auth_Change\n");\r
- }\r
- else\r
- {\r
- rc = anx7150_set_avmute(client); //wen\r
- hdmi_dbg(&client->dev, "ANX7150_Authentication failed_by_Auth_change\n");\r
- ANX7150_hdcp_auth_pass = 0;\r
- ANX7150_hdcp_wait_100ms_needed = 1;\r
- ANX7150_auth_fully_pass = 0;\r
- ANX7150_hdcp_init_done=0; //wen HDCP CTS\r
- ANX7150_hdcp_auth_en=0; //wen HDCP CTS\r
- rc = anx7150_hdcp_encryption_disable(client);\r
- if (state == PLAY_BACK)\r
- {\r
- ANX7150_auth_fully_pass = 0;\r
- //disable audio\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- rc = anx7150_clean_hdcp(client); //wen updated for Changhong TV\r
- }\r
- }\r
- return rc;\r
-}\r
-int ANX7150_GET_RECIVER_TYPE(void)\r
-{
- return ANX7150_edid_result.is_HDMI;
-}\r
-static int anx7150_audio_clk_change(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- hdmi_dbg(&client->dev, "ANX7150: audio clock changed interrupt,disable audio.\n");\r
- // disable audio\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- //xy 11.06 when format change, need system config again\r
-// ANX7150_system_config_done = 0;\r
- return rc;\r
-}\r
-\r
-static int anx7150_afifo_overrun(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- hdmi_dbg(&client->dev, "ANX7150: AFIFO overrun interrupt,disable audio.\n");\r
- // disable audio\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- return rc;\r
-}\r
-static int anx7150_spdif_error(struct i2c_client *client, int cur_state, int SPDIF_bi_phase_err, int SPDIF_error)\r
-{\r
- int rc = 0;\r
- char c;\r
- int state = cur_state;\r
-\r
- if(SPDIF_bi_phase_err || SPDIF_error)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- if( c & ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN) \r
- {\r
- \r
- if ((state == CONFIG_AUDIO \r
- || state == CONFIG_PACKETS \r
- || state == HDCP_AUTHENTICATION \r
- || state == PLAY_BACK ))\r
- {\r
- if(SPDIF_bi_phase_err){\r
- hdmi_dbg(&client->dev, "SPDIF BI Phase or Unstable error.\n");\r
- spdif_error_cnt += 0x03;\r
- }\r
-\r
- if(SPDIF_error){\r
- hdmi_dbg(&client->dev, "SPDIF Parity error.\n");\r
- spdif_error_cnt += 0x01;\r
- }\r
-\r
- }\r
-\r
- // adjust spdif phase\r
- if (spdif_error_cnt >= spdif_error_th)\r
- {\r
- char freq_mclk,c1,c2;\r
- spdif_error_cnt = 0x00;\r
- hdmi_dbg(&client->dev, "adjust mclk phase!\n");\r
- \r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c2);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
-\r
- freq_mclk = c2 & 0x07;\r
- switch (freq_mclk)\r
- {\r
- case ANX7150_mclk_128_Fs: //invert 0x50[3]\r
- hdmi_dbg(&client->dev, "adjust mclk phase when 128*Fs!\n");\r
- if ( c2 & 0x08 ) c2 &= 0xf7;\r
- else c2 |= 0x08;\r
-\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c2);\r
- break;\r
-\r
- case ANX7150_mclk_256_Fs:\r
- case ANX7150_mclk_384_Fs:\r
- hdmi_dbg(&client->dev, "adjust mclk phase when 256*Fs or 384*Fs!\n");\r
- if ( c1 & 0x60 ) c1 &= 0x9f;\r
- else c1 |= 0x20;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
- break;\r
-\r
- case ANX7150_mclk_512_Fs:\r
- hdmi_dbg(&client->dev, "adjust mclk phase when 512*Fs!\n");\r
- if ( c1 & 0x60 ) c1 &= 0x9f;\r
- else c1 |= 0x40;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c1);\r
- break;\r
- default:\r
- break;\r
-\r
- }\r
- }\r
- }\r
- }\r
- else{\r
- if(spdif_error_cnt > 0 && state == PLAY_BACK) spdif_error_cnt --;\r
- if(spdif_error_cnt > 0 && state < CONFIG_AUDIO) spdif_error_cnt = 0x00;\r
-\r
- }\r
-\r
- return rc;\r
-}\r
-static int anx7150_plllock(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- \r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_CHIP_STATUS_REG, &c);\r
- if((c&0x01) == 0)\r
- {\r
- rc = anx7150_set_avmute(client);//wen\r
- hdmi_dbg(&client->dev, "ANX7150: PLL unlock interrupt,disable audio.\n");\r
- // disable audio & video\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c &= (~ANX7150_VID_CTRL_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-\r
- //when pll change, clear this reg to avoid error in package config\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);//wen\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
-\r
-// ANX7150_system_config_done = 0;//jack wen\r
- }\r
- return rc;\r
-}\r
-static int anx7150_rx_sense_change(struct i2c_client *client, int cur_state)\r
-{\r
- int rc = 0;\r
- char c;\r
- int state = cur_state;\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
- hdmi_dbg(&client->dev, "ANX7150_Rx_Sense_Interrupt, ANX7150_SYS_STATE_REG = %.2x\n", (unsigned int)c); //wen\r
-\r
- if ( c & ANX7150_SYS_STATE_RSV_DET)\r
- {\r
- //xy 11.06 Power on chip\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c |= (0x01);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
-\r
- s_ANX7150_packet_config.packets_need_config = 0x03; //new avi infoframe wen\r
- }\r
- else\r
- {\r
- // Rx is not active\r
- if (state > WAIT_HOTPLUG)\r
- {\r
- //stop HDCP and reset DDC when lost Rx sense\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_REG);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- \r
- rc = anx7150_rst_ddcchannel(client);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c &= (0xfd);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- \r
- // mute TMDS link\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- c &= (~ANX7150_TMDS_CLKCH_MUTE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- }\r
- //Power down chip\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c &= (0xfe);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- }\r
- //xy 11.06 when format change, need system config again\r
-// ANX7150_system_config_done = 0;//wen HDCP CTS\r
-\r
- return rc;\r
-}\r
-int ANX7150_Interrupt_Process(struct anx7150_pdata *anx, int cur_state)\r
-{\r
- struct anx7150_interrupt_s interrupt_staus;\r
-\r
- int state;\r
- int hot_plug;\r
- int rc;\r
-\r
- state = cur_state;\r
-\r
- hot_plug = anx7150_get_hpd(anx->client);\r
-\r
- rc = anx7150_get_interrupt_status(anx->client, &interrupt_staus);\r
- if(rc < 0){\r
- goto out;\r
- } \r
-\r
- if(anx->dev.HPD_status != hot_plug){\r
- anx->dev.HPD_change_cnt++;\r
- }\r
- else{\r
- anx->dev.HPD_change_cnt = 0;\r
- }\r
-\r
- if(anx->dev.HPD_change_cnt > 1){\r
- hdmi_dbg(&anx->client->dev, "hotplug_change\n");\r
-\r
- if(hot_plug == HDMI_RECIVER_UNPLUG){\r
- anx7150_unplug(anx->client);\r
- state = HDMI_INITIAL;\r
- anx->dev.reciver_status = HDMI_RECIVER_INACTIVE;\r
- }\r
-\r
- anx->dev.HPD_change_cnt = 0;\r
- anx->dev.HPD_status = hot_plug;\r
- }\r
- return state;\r
- if(state != HDMI_INITIAL && state != WAIT_HOTPLUG){\r
- if(interrupt_staus.video_format_change){\r
- if(state > SYSTEM_CONFIG){\r
- rc = anx7150_video_format_change(anx->client);\r
- state = CONFIG_VIDEO;\r
- }\r
- }\r
-\r
- if(interrupt_staus.auth_done){\r
- rc = anx7150_auth_done(anx->client);\r
- state = CONFIG_AUDIO;\r
- }\r
-\r
- if(interrupt_staus.auth_state_change){\r
- rc = anx7150_auth_change(anx->client);\r
- if(state == PLAY_BACK){\r
- state = HDCP_AUTHENTICATION;\r
- }\r
- }\r
-\r
- if(ANX7150_GET_RECIVER_TYPE() == 1){\r
- /*\r
- if(interrupt_staus.audio_clk_change){\r
- if(state > CONFIG_VIDEO){\r
- rc = anx7150_audio_clk_change(anx->client);\r
- state = SYSTEM_CONFIG;\r
- }\r
- }\r
- \r
- if(interrupt_staus.audio_FIFO_overrun){\r
- if(state > CONFIG_VIDEO){\r
- rc = anx7150_afifo_overrun(anx->client);\r
- state = CONFIG_AUDIO;\r
- }\r
- }\r
-\r
-*/\r
- rc = anx7150_spdif_error(anx->client, state, interrupt_staus.SPDIF_bi_phase_error, interrupt_staus.SPDIF_error);\r
- }\r
-\r
- if(interrupt_staus.pll_lock_change){\r
- if(state > SYSTEM_CONFIG){\r
- rc = anx7150_plllock(anx->client);\r
- state = SYSTEM_CONFIG;\r
- }\r
- }\r
-\r
- if(interrupt_staus.rx_sense_change){\r
- anx7150_rx_sense_change(anx->client, state);\r
- if(state > WAIT_RX_SENSE) \r
- state = WAIT_RX_SENSE;\r
- }\r
- }\r
-\r
-out:\r
- return state;\r
-}\r
-\r
-int ANX7150_API_Initial(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- hdmi_dbg(&client->dev, "%s\n", __func__);\r
-\r
- ANX7150_Variable_Initial();\r
- ANX7150_HW_Interface_Variable_Initial();\r
- rc = anx7150_hardware_initial(client);\r
-\r
- return rc;\r
-}\r
-\r
-void ANX7150_Shutdown(struct i2c_client *client)\r
-{\r
- hdmi_dbg(&client->dev, "%s\n", __func__);\r
- ANX7150_API_Initial(client);\r
- ANX7150_Set_System_State(client, HDMI_INITIAL);\r
-}\r
-\r
-static int anx7150_initddc_read(struct i2c_client *client, \r
- u8 devaddr, u8 segmentpointer,\r
- u8 offset, u8 access_num_Low,u8 access_num_high)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- //Write slave device address\r
- c = devaddr;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_ADDR_REG, &c);\r
- // Write segment address\r
- c = segmentpointer;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_SEGADDR_REG, &c);\r
- //Write offset\r
- c = offset;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_SLV_OFFADDR_REG, &c);\r
- //Write number for access\r
- c = access_num_Low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACCNUM0_REG, &c);\r
- c = access_num_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACCNUM1_REG, &c);\r
- //Clear FIFO\r
- c = 0x05;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);\r
- //EDDC sequential Read\r
- c = 0x04;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_DDC_ACC_CMD_REG, &c);\r
-\r
- return rc;\r
-}\r
-static int ANX7150_GetEDIDLength(struct i2c_client *client)\r
-{\r
- u8 edid_data_length;\r
- int rc = 0;\r
-\r
- anx7150_rst_ddcchannel(client);\r
-\r
- rc = anx7150_initddc_read(client, 0xa0, 0x00, 0x7e, 0x01, 0x00);\r
-\r
- mdelay(10);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &edid_data_length);\r
-\r
- ANX7150_edid_length = edid_data_length * 128 + 128;\r
-\r
- return rc;\r
-\r
-}\r
-/*** DDC fetch and block validation ***/\r
-\r
-static const u8 edid_header[] = {\r
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00\r
-};\r
-\r
-\r
-/*\r
- * Sanity check the EDID block (base or extension). Return 0 if the block\r
- * doesn't check out, or 1 if it's valid.\r
- */\r
- \r
-int anx7150_edid_block_valid(struct i2c_client *client, u8 *raw_edid)\r
-{\r
- int i;\r
- u8 csum = 0;\r
- struct edid *edid = (struct edid *)raw_edid;\r
-\r
- if (raw_edid[0] == 0x00) {\r
- int score = 0;\r
-\r
- for (i = 0; i < sizeof(edid_header); i++)\r
- if (raw_edid[i] == edid_header[i])\r
- score++;\r
-\r
- if (score == 8) ;\r
- else if (score >= 6) {\r
- hdmi_dbg(&client->dev, "Fixing EDID header, your hardware may be failing\n");\r
- memcpy(raw_edid, edid_header, sizeof(edid_header));\r
- } else {\r
- goto bad;\r
- }\r
- }\r
-\r
-#if 0\r
- for (i = 0; i < EDID_LENGTH; i++)\r
- csum += raw_edid[i];\r
- if (csum) {\r
- hdmi_dbg(&client->dev, "EDID checksum is invalid, remainder is %d\n", csum);\r
-\r
- /* allow CEA to slide through, switches mangle this */\r
- if (raw_edid[0] != 0x02)\r
- goto bad;\r
- }\r
-#endif\r
-\r
- /* per-block-type checks */\r
- switch (raw_edid[0]) {\r
- case 0: /* base */\r
- if (edid->version != 1) {\r
- dev_err(&client->dev, "EDID has major version %d, instead of 1\n", edid->version);\r
- goto bad;\r
- }\r
-\r
- if (edid->revision > 4)\r
- dev_err(&client->dev,"EDID minor > 4, assuming backward compatibility\n");\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return 1;\r
-\r
-bad:\r
- if (raw_edid) {\r
- dev_err(&client->dev, "Raw EDID:\n");\r
- print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);\r
- printk("\n");\r
- }\r
- return 0;\r
-}\r
-int ANX7150_DDC_EDID(struct i2c_client *client, u8 *buf, u8 block, u16 len)\r
-{\r
- u8 offset;\r
- u8 segment;\r
- u8 len_low;\r
- u8 len_high;\r
- \r
- offset = EDID_LENGTH * (block & 0x01);\r
- segment = block >> 1;\r
- len_low = len & 0xFF;\r
- len_high = (len >> 8) & 0xFF;\r
-\r
- anx7150_initddc_read(client, 0xa0, segment, offset, len_low, len_high);\r
- if(ANX7150_DDC_Mass_Read(client, buf, len) == len)\r
- return 0;\r
- else\r
- return -1;\r
-}\r
-u8 *ANX7150_Read_EDID(struct i2c_client *client)\r
-{\r
- u8 *block = NULL;\r
- u8 *raw_edid = NULL;\r
- u8 extend_block_num;\r
- int i = 0;\r
- int j = 0;\r
-\r
- anx7150_rst_ddcchannel(client);\r
-\r
- if ((block = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)\r
- return NULL;\r
-\r
- /* base block fetch */\r
- hdmi_dbg(&client->dev, "Read base block\n");\r
- for (i = 0; i < 4; i++) {\r
- if(ANX7150_DDC_EDID(client, block, 0, EDID_LENGTH))\r
- goto out;\r
- if(anx7150_edid_block_valid(client, block))\r
- break;\r
- else\r
- dev_err(&client->dev, "Read base block err, retry...\n");\r
- \r
- mdelay(10);\r
- }\r
-\r
- if(i == 4){\r
- dev_err(&client->dev, "Read base block failed\n");\r
- goto out;\r
- }\r
-\r
- /* if there's no extensions, we're done */\r
- extend_block_num = block[0x7e];\r
- if(extend_block_num == 0)\r
- goto out;\r
- \r
- dev_err(&client->dev, "extend_block_num = %d\n", extend_block_num);\r
-\r
- raw_edid = krealloc(block, (extend_block_num + 1) * EDID_LENGTH, GFP_KERNEL);\r
- if(!raw_edid)\r
- goto out;\r
-\r
- block = raw_edid;\r
-\r
- hdmi_dbg(&client->dev, "Read extend block\n");\r
- for(j=1; j<=extend_block_num; j++){\r
- for(i=0; i<4; i++){\r
- if(ANX7150_DDC_EDID(client, raw_edid + j * EDID_LENGTH, j, EDID_LENGTH))\r
- goto out;\r
- if(anx7150_edid_block_valid(client, raw_edid + j * EDID_LENGTH))\r
- break;\r
- else\r
- dev_err(&client->dev, "Read extend block %d err, retry...\n", j);\r
-\r
- mdelay(10);\r
- }\r
-\r
- if(i == 4){\r
- dev_err(&client->dev, "Read extend block %d failed\n", j);\r
- goto out;\r
- }\r
- }\r
-\r
- dev_err(&client->dev, "\n\nRaw EDID(extend_block_num = %d, total_len = %d):\n\n", extend_block_num, EDID_LENGTH*(extend_block_num+1));\r
- print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH*(extend_block_num+1));\r
- printk("\n\n");\r
-\r
- return raw_edid;\r
-\r
-out:\r
- kfree(block);\r
- return NULL;\r
-}\r
-int ANX7150_DDC_Mass_Read(struct i2c_client *client, u8 *buf, u16 len)\r
-{\r
- int rc = 0;\r
- u32 i, j;\r
- char c, c1,ddc_empty_cnt;\r
-\r
- i = len;\r
- while (i > 0)\r
- {\r
- //check DDC FIFO statue\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_CHSTATUS_REG, &c);\r
- if (c & ANX7150_DDC_CHSTATUS_DDC_OCCUPY)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150 DDC channel is accessed by an external device, break!.\n");\r
- break;\r
- }\r
- if (c & ANX7150_DDC_CHSTATUS_FIFO_FULL)\r
- ANX7150_ddc_fifo_full = 1;\r
- else\r
- ANX7150_ddc_fifo_full = 0;\r
- if (c & ANX7150_DDC_CHSTATUS_INPRO)\r
- ANX7150_ddc_progress = 1;\r
- else\r
- ANX7150_ddc_progress = 0;\r
- if (ANX7150_ddc_fifo_full)\r
- {\r
- hdmi_dbg(&client->dev, "DDC FIFO is full during edid reading");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFOCNT_REG, &c);\r
- hdmi_dbg(&client->dev, "FIFO counter is %.2x\n", (u32) c);\r
- for (j=0; j<c; j++)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &c1);\r
- buf[len - i + j] = c1;\r
-\r
- ANX7150_ddc_fifo_full = 0;\r
- if(anx7150_mass_read_need_delay)\r
- mdelay(1);\r
- }\r
- i = i - c;\r
- //D("\n");\r
- }\r
- else if (!ANX7150_ddc_progress)\r
- {\r
- //D("ANX7150 DDC FIFO access finished.\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFOCNT_REG, &c);\r
- //D("FIFO counter is %.2x\n", (u32) c);\r
- if (!c)\r
- {\r
- i =0;\r
- break;\r
- }\r
- for (j=0; j<c; j++)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &c1);\r
- buf[len - i + j] = c1;\r
- }\r
- i = i - c;\r
- //D("\ni=%d\n", i);\r
- }\r
- else\r
- {\r
- ddc_empty_cnt = 0x00;\r
- for (c1=0; c1<0x0a; c1++)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_CHSTATUS_REG, &c);\r
- //D("DDC FIFO access is progressing.\n");\r
- //D("DDC Channel status is 0x%.2x\n",(u32)c);\r
- if (c & ANX7150_DDC_CHSTATUS_FIFO_EMPT)\r
- ddc_empty_cnt++;\r
- mdelay(1);\r
- //D("ddc_empty_cnt = 0x%.2x\n",(u32)ddc_empty_cnt);\r
- }\r
- if (ddc_empty_cnt >= 0x0a)\r
- break;\r
- }\r
- }\r
- return (len - i);\r
-}\r
-\r
-static u8 ANX7150_Read_EDID_u8(u8 segmentpointer,u8 offset)\r
-{
- /*u8 c;
- anx7150_initddc_read(0xa0, segmentpointer, offset, 0x01, 0x00);\r
- ANX7150_i2c_read_p0_reg(ANX7150_DDC_FIFOCNT_REG, &c);
- while(c==0)
- ANX7150_i2c_read_p0_reg(ANX7150_DDC_FIFO_ACC_REG, &c);
- return c;*/
-
- return ANX7150_EDID_Buf[offset];
-}\r
-static u8 ANX7150_Parse_EDIDHeader(void)\r
-{\r
- u8 i,temp;\r
- temp = 0;\r
- // the EDID header should begin with 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00\r
- if ((ANX7150_Read_EDID_u8(0, 0) == 0x00) && (ANX7150_Read_EDID_u8(0, 7) == 0x00))\r
- {\r
- for (i = 1; i < 7; i++)\r
- {\r
- if (ANX7150_Read_EDID_u8(0, i) != 0xff)\r
- {\r
- temp = 0x01;\r
- break;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- temp = 0x01;\r
- }\r
- if (temp == 0x01)\r
- {\r
- return 0;\r
- }\r
- else\r
- {\r
- return 1;\r
- }\r
-}\r
-static u8 ANX7150_Parse_EDIDVersion(void)\r
-{\r
-\r
- if (!((ANX7150_Read_EDID_u8(0, 0x12) == 1) && (ANX7150_Read_EDID_u8(0, 0x13) >= 3) ))\r
- {\r
- return 0;\r
- }\r
- else\r
- {\r
- return 1;\r
- }\r
-}\r
-static void ANX7150_Parse_DTD(void)\r
-{
- u32 temp;
- unsigned long temp1,temp2;
- u32 Hresolution,Vresolution,Hblanking,Vblanking;
- u32 PixelCLK,Vtotal,H_image_size,V_image_size;
- u8 Hz;
- //float Ratio;
-
- temp = ANX7150_edid_dtd[1];
- temp = temp << 8;
- PixelCLK = temp + ANX7150_edid_dtd[0];
- // D("Pixel clock is 10000 * %u\n", temp);
-
- temp = ANX7150_edid_dtd[4];
- temp = (temp << 4) & 0x0f00;
- Hresolution = temp + ANX7150_edid_dtd[2];
- //D("Horizontal Active is %u\n", Hresolution);
-
- temp = ANX7150_edid_dtd[4];
- temp = (temp << 8) & 0x0f00;
- Hblanking = temp + ANX7150_edid_dtd[3];
- //D("Horizontal Blanking is %u\n", temp);
-
- temp = ANX7150_edid_dtd[7];
- temp = (temp << 4) & 0x0f00;
- Vresolution = temp + ANX7150_edid_dtd[5];
- //D("Vertical Active is %u\n", Vresolution);
-
- temp = ANX7150_edid_dtd[7];
- temp = (temp << 8) & 0x0f00;
- Vblanking = temp + ANX7150_edid_dtd[6];
- //D("Vertical Blanking is %u\n", temp);
-
- temp = ANX7150_edid_dtd[11];
- temp = (temp << 2) & 0x0300;
- temp = temp + ANX7150_edid_dtd[8];
- //D("Horizontal Sync Offset is %u\n", temp);
-
- temp = ANX7150_edid_dtd[11];
- temp = (temp << 4) & 0x0300;
- temp = temp + ANX7150_edid_dtd[9];
- //D("Horizontal Sync Pulse is %u\n", temp);
-
- temp = ANX7150_edid_dtd[11];
- temp = (temp << 2) & 0x0030;
- temp = temp + (ANX7150_edid_dtd[10] >> 4);
- //D("Vertical Sync Offset is %u\n", temp);
-
- temp = ANX7150_edid_dtd[11];
- temp = (temp << 4) & 0x0030;
- temp = temp + (ANX7150_edid_dtd[8] & 0x0f);
- //D("Vertical Sync Pulse is %u\n", temp);
-
- temp = ANX7150_edid_dtd[14];
- temp = (temp << 4) & 0x0f00;
- H_image_size = temp + ANX7150_edid_dtd[12];
- //D("Horizontal Image size is %u\n", temp);
-
- temp = ANX7150_edid_dtd[14];
- temp = (temp << 8) & 0x0f00;
- V_image_size = temp + ANX7150_edid_dtd[13];
- //D("Vertical Image size is %u\n", temp);
-
- //D("Horizontal Border is %bu\n", ANX7150_edid_dtd[15]);
-
- //D("Vertical Border is %bu\n", ANX7150_edid_dtd[16]);
-
- temp1 = Hresolution + Hblanking;
- Vtotal = Vresolution + Vblanking;
- temp1 = temp1 * Vtotal;
- temp2 = PixelCLK;
- temp2 = temp2 * 10000;
- if (temp1 == 0) //update
- Hz=0;
- else
- Hz = temp2 / temp1;
- //Hz = temp2 / temp1;
- if ((Hz == 59) || (Hz == 60))
- {
- Hz = 60;
- //D("_______________Vertical Active is %u\n", Vresolution);
- if (Vresolution == 540)
- ANX7150_edid_result.supported_1080i_60Hz = 1;
- if (Vresolution == 1080)
- ANX7150_edid_result.supported_1080p_60Hz = 1;
- if (Vresolution == 720)
- ANX7150_edid_result.supported_720p_60Hz = 1;
- if ((Hresolution == 640) && (Vresolution == 480))
- ANX7150_edid_result.supported_640x480p_60Hz = 1;
- if ((Hresolution == 720) && (Vresolution == 480))
- ANX7150_edid_result.supported_720x480p_60Hz = 1;
- if ((Hresolution == 720) && (Vresolution == 240))
- ANX7150_edid_result.supported_720x480i_60Hz = 1;
- }
- if (Hz == 50)
- {
- //D("+++++++++++++++Vertical Active is %u\n", Vresolution);
- if (Vresolution == 540)
- ANX7150_edid_result.supported_1080i_50Hz = 1;
- if (Vresolution == 1080)
- ANX7150_edid_result.supported_1080p_50Hz = 1;
- if (Vresolution == 720)
- ANX7150_edid_result.supported_720p_50Hz = 1;
- if (Vresolution == 576)
- ANX7150_edid_result.supported_576p_50Hz = 1;
- if (Vresolution == 288)
- ANX7150_edid_result.supported_576i_50Hz = 1;
- }
- //D("Fresh rate :% bu Hz\n", Hz);
- //Ratio = H_image_size;
- //Ratio = Ratio / V_image_size;
- //D("Picture ratio : %f \n", Ratio);
-}\r
-static void ANX7150_Parse_DTDinBlockONE(void)\r
-{
- u8 i;
- for (i = 0; i < 18; i++)
- {
- ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x36));
- }
- //D("Parse the first DTD in Block one:\n");
- ANX7150_Parse_DTD();
-
- if ((ANX7150_Read_EDID_u8(0, 0x48) == 0)
- && (ANX7150_Read_EDID_u8(0, 0x49) == 0)
- && (ANX7150_Read_EDID_u8(0, 0x4a) == 0))
- {
- ;//D("the second DTD in Block one is not used to descript video timing.\n");
- }
- else
- {
- for (i = 0; i < 18; i++)
- {
- ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x48));
- }
- ANX7150_Parse_DTD();
- }
-
- if ((ANX7150_Read_EDID_u8(0,0x5a) == 0)
- && (ANX7150_Read_EDID_u8(0,0x5b) == 0)
- && (ANX7150_Read_EDID_u8(0,0x5c) == 0))
- {
- ;//D("the third DTD in Block one is not used to descript video timing.\n");
- }
- else
- {
- for (i = 0; i < 18; i++)
- {
- ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0, (i + 0x5a));
- }
- ANX7150_Parse_DTD();
- }
-
- if ((ANX7150_Read_EDID_u8(0,0x6c) == 0)
- && (ANX7150_Read_EDID_u8(0,0x6d) == 0)
- && (ANX7150_Read_EDID_u8(0,0x6e) == 0))
- {
- ;//D("the fourth DTD in Block one is not used to descript video timing.\n");
- }
- else
- {
- for (i = 0; i < 18; i++)
- {
- ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(0,(i + 0x6c));
- }
- ANX7150_Parse_DTD();
- }
-}\r
-static void ANX7150_Parse_NativeFormat(void)\r
-{
- u8 temp;
- temp = ANX7150_Read_EDID_u8(0,0x83) & 0xf0;
- /*if(temp & 0x80)
- ;//D("DTV supports underscan.\n");
- if(temp & 0x40)
- ;//D("DTV supports BasicAudio.\n");*/
- if (temp & 0x20)
- {
- //D("DTV supports YCbCr 4:4:4.\n");
- ANX7150_edid_result.ycbcr444_supported= 1;
- }
- if (temp & 0x10)
- {
- //D("DTV supports YCbCr 4:2:2.\n");
- ANX7150_edid_result.ycbcr422_supported= 1;
- }
-}\r
-static void ANX7150_Parse_DTDinExtBlock(void)\r
-{
- u8 i,DTDbeginAddr;
- DTDbeginAddr = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2, 0x82)
- + 0x80;
- while (DTDbeginAddr < (0x6c + 0x80))
- {
- if ((ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,DTDbeginAddr) == 0)
- && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(DTDbeginAddr + 1)) == 0)
- && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(DTDbeginAddr + 2)) == 0))
- {
- ;//D("this DTD in Extension Block is not used to descript video timing.\n");
- }
- else
- {
- for (i = 0; i < 18; i++)
- {
- ANX7150_edid_dtd[i] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(i + DTDbeginAddr));
- }
- //D("Parse the DTD in Extension Block :\n");
- ANX7150_Parse_DTD();
- }
- DTDbeginAddr = DTDbeginAddr + 18;
- }
-}\r
-static void ANX7150_Parse_AudioSTD(void)\r
-{
- u8 i,AudioFormat,STDReg_tmp,STDAddr_tmp;
- STDReg_tmp = ANX7150_stdreg & 0x1f;
- STDAddr_tmp = ANX7150_stdaddr + 1;
- i = 0;
- while (i < STDReg_tmp)
- {
- AudioFormat = (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp ) & 0xF8) >> 3;
- ANX7150_edid_result.AudioChannel[i/3] = (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x07) + 1;
- ANX7150_edid_result.AudioFormat[i/3] = AudioFormat;
- ANX7150_edid_result.AudioFs[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 1)) & 0x7f;
-
- if (AudioFormat == 1)
- ANX7150_edid_result.AudioLength[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 2)) & 0x07;
- else
- ANX7150_edid_result.AudioLength[i/3] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(STDAddr_tmp + 2)) << 3;
-
- i = i + 3;
- STDAddr_tmp = STDAddr_tmp + 3;
- }
-}\r
-static void ANX7150_Parse_VideoSTD(void)\r
-{
- u8 i,STDReg_tmp,STDAddr_tmp;
- u8 SVD_ID[34];
- STDReg_tmp = ANX7150_stdreg & 0x1f;
- STDAddr_tmp = ANX7150_stdaddr + 1;
- i = 0;
- while (i < STDReg_tmp)
- {
- SVD_ID[i] = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x7F;
- //D("ANX7150_edid_result.SVD_ID[%.2x]=0x%.2x\n",(u32)i,(u32)ANX7150_edid_result.SVD_ID[i]);
- //if(ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,STDAddr_tmp) & 0x80)
- // D(" Native mode");
- if (SVD_ID[i] == 1)
- ANX7150_edid_result.supported_640x480p_60Hz = 1;
- else if (SVD_ID[i] == 4)
- ANX7150_edid_result.supported_720p_60Hz = 1;
- else if (SVD_ID[i] == 19)
- ANX7150_edid_result.supported_720p_50Hz = 1;
- else if (SVD_ID[i] == 16)
- ANX7150_edid_result.supported_1080p_60Hz = 1;
- else if (SVD_ID[i] == 31)
- ANX7150_edid_result.supported_1080p_50Hz = 1;
- else if (SVD_ID[i] == 5)
- ANX7150_edid_result.supported_1080i_60Hz = 1;
- else if (SVD_ID[i] == 20)
- ANX7150_edid_result.supported_1080i_50Hz = 1;
- else if ((SVD_ID[i] == 2) ||(SVD_ID[i] == 3))
- ANX7150_edid_result.supported_720x480p_60Hz = 1;
- else if ((SVD_ID[i] == 6) ||(SVD_ID[i] == 7))
- ANX7150_edid_result.supported_720x480i_60Hz = 1;
- else if ((SVD_ID[i] == 17) ||(SVD_ID[i] == 18))
- ANX7150_edid_result.supported_576p_50Hz = 1;
- else if ((SVD_ID[i] == 21) ||(SVD_ID[i] == 22))
- ANX7150_edid_result.supported_576i_50Hz = 1;
-
- i = i + 1;
- STDAddr_tmp = STDAddr_tmp + 1;
- }
-}\r
-static void ANX7150_Parse_SpeakerSTD(void)\r
-{
- ANX7150_edid_result.SpeakerFormat = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 1)) ;
-}\r
-static void ANX7150_Parse_VendorSTD(void)\r
-{\r
- //u8 c;\r
- if ((ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 1)) == 0x03)\r
- && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 2)) == 0x0c)\r
- && (ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,(ANX7150_stdaddr + 3)) == 0x00))\r
- {\r
- ANX7150_edid_result.is_HDMI = 1;\r
- //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c |ANX7150_SYS_CTRL1_HDMI);\r
- }\r
- else\r
- {\r
- ANX7150_edid_result.is_HDMI = 0;\r
- //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c & (~ANX7150_SYS_CTRL1_HDMI));\r
- }\r
-}\r
-\r
-static void ANX7150_Parse_STD(void)\r
-{
- u8 DTDbeginAddr;
- ANX7150_stdaddr = 0x84;
- DTDbeginAddr = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,0x82) + 0x80;
- // D("Video DTDbeginAddr Register :%.2x\n", (u32) DTDbeginAddr);
- while (ANX7150_stdaddr < DTDbeginAddr)
- {
- ANX7150_stdreg = ANX7150_Read_EDID_u8(ANX7150_ext_block_num/2,ANX7150_stdaddr);
- switch (ANX7150_stdreg & 0xe0)
- {
- case 0x20:
- ANX7150_Parse_AudioSTD();
- ANX7150_sau_length = ANX7150_stdreg & 0x1f;
- break;
- case 0x40:
- ANX7150_Parse_VideoSTD();
- ANX7150_svd_length = ANX7150_stdreg & 0x1f;
- break;
- case 0x80:
- ANX7150_Parse_SpeakerSTD();
- break;
- case 0x60:
- ANX7150_Parse_VendorSTD();
- break;
- default:
- break;
- }
- ANX7150_stdaddr = ANX7150_stdaddr + (ANX7150_stdreg & 0x1f) + 0x01;
- }
-}\r
-static u8 ANX7150_EDID_Checksum(u8 block_number)\r
-{
- u8 i, real_checksum;
- u8 edid_block_checksum;
-
- edid_block_checksum = 0;
- for (i = 0; i < 127; i ++)
- {
- if ((block_number / 2) * 2 == block_number)
- edid_block_checksum = edid_block_checksum + ANX7150_Read_EDID_u8(block_number/2, i);
- else
- edid_block_checksum = edid_block_checksum + ANX7150_Read_EDID_u8(block_number/2, i + 0x80);
- }
- edid_block_checksum = (~edid_block_checksum) + 1;
- // D("edid_block_checksum = 0x%.2x\n",(u32)edid_block_checksum);
- if ((block_number / 2) * 2 == block_number)
- real_checksum = ANX7150_Read_EDID_u8(block_number/2, 0x7f);
- else
- real_checksum = ANX7150_Read_EDID_u8(block_number/2, 0xff);
- if (real_checksum == edid_block_checksum)
- return 1;
- else
- return 0;
-}\r
-static u8 ANX7150_Parse_ExtBlock(void)\r
-{
- u8 i,c;
-
- for (i = 0; i < ANX7150_Read_EDID_u8(0, 0x7e); i++) //read in blocks
- {
- c = ANX7150_Read_EDID_u8(i/2, 0x80);
- if ( c == 0x02)
- {
- ANX7150_ext_block_num = i + 1;
- ANX7150_Parse_DTDinExtBlock();
- ANX7150_Parse_STD();
- if (!(ANX7150_EDID_Checksum(ANX7150_ext_block_num)))
- {
- ANX7150_edid_result.edid_errcode = ANX7150_EDID_CheckSum_ERR;
- return ANX7150_edid_result.edid_errcode;
- }
- }
- else
- {
- ANX7150_edid_result.edid_errcode = ANX7150_EDID_ExtBlock_NotFor_861B;
- return ANX7150_edid_result.edid_errcode;
- }
- }
-
- return 0;
-}\r
-int ANX7150_Parse_EDID(struct i2c_client *client, struct anx7150_dev_s *dev)\r
-{\r
- int rc = 0, i;\r
- char c;\r
-\r
- if(dev->rk29_output_status == RK29_OUTPUT_STATUS_LCD)\r
- anx7150_mass_read_need_delay = 1;\r
- else\r
- anx7150_mass_read_need_delay = 0;\r
-\r
- /* Clear HDCP Authentication indicator */\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= (~ANX7150_HDCP_CTRL0_HW_AUTHEN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- ANX7150_hdcp_auth_en = 0;\r
-\r
-\r
- ANX7150_EDID_Buf = ANX7150_Read_EDID(client);\r
- \r
- if(!ANX7150_EDID_Buf){\r
- ANX7150_edid_result.edid_errcode = ANX7150_EDID_BadHeader;\r
- dev_err(&client->dev, "READ EDID ERROR\n");\r
- goto err;\r
- }\r
-\r
-/*\r
- if(ANX7150_EDID_Checksum(0) == 0)\r
- {\r
- D("EDID Block one check sum error, Stop parsing\n");\r
- ANX7150_edid_result.edid_errcode = ANX7150_EDID_CheckSum_ERR;\r
- return ANX7150_edid_result.edid_errcode;\r
- }\r
-*/\r
-\r
- //ANX7150_Parse_BasicDis();\r
- ANX7150_Parse_DTDinBlockONE();\r
-\r
- if(ANX7150_EDID_Buf[0x7e] == 0)\r
- {\r
- hdmi_dbg(&client->dev, "No EDID extension blocks.\n");\r
- ANX7150_edid_result.edid_errcode = ANX7150_EDID_No_ExtBlock;\r
- return ANX7150_edid_result.edid_errcode;\r
- }\r
- \r
- ANX7150_Parse_NativeFormat();\r
- ANX7150_Parse_ExtBlock();\r
-\r
- if (ANX7150_edid_result.edid_errcode == ANX7150_EDID_ExtBlock_NotFor_861B){\r
- dev_err(&client->dev,"EDID ExtBlock not support for 861B, Stop parsing\n");\r
- goto err;\r
- }\r
-\r
- if (ANX7150_edid_result.edid_errcode == ANX7150_EDID_CheckSum_ERR){\r
- dev_err(&client->dev,"EDID Block check sum error, Stop parsing\n");\r
- goto err;\r
- }\r
-\r
- hdmi_dbg(&client->dev,"EDID parsing finished!\n");\r
-\r
- {\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.edid_errcode = 0x%.2x\n",(u32)ANX7150_edid_result.edid_errcode);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.is_HDMI = 0x%.2x\n",(u32)ANX7150_edid_result.is_HDMI);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.ycbcr422_supported = 0x%.2x\n",(u32)ANX7150_edid_result.ycbcr422_supported);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.ycbcr444_supported = 0x%.2x\n",(u32)ANX7150_edid_result.ycbcr444_supported);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080i_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080i_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080i_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080i_50Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080p_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_1080p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_1080p_50Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720p_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720p_50Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_640x480p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_640x480p_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720x480p_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720x480p_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_720x480i_60Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_720x480i_60Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_576p_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_576p_50Hz);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.supported_576i_50Hz = 0x%.2x\n",(u32)ANX7150_edid_result.supported_576i_50Hz);\r
- if (!ANX7150_edid_result.edid_errcode)\r
- {\r
- for (i = 0; i < ANX7150_sau_length/3; i++)\r
- {\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioChannel = 0x%.2x\n",(u32)ANX7150_edid_result.AudioChannel[i]);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioFormat = 0x%.2x\n",(u32)ANX7150_edid_result.AudioFormat[i]);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioFs = 0x%.2x\n",(u32)ANX7150_edid_result.AudioFs[i]);\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.AudioLength = 0x%.2x\n",(u32)ANX7150_edid_result.AudioLength[i]);\r
- }\r
- hdmi_dbg(&client->dev,"ANX7150_edid_result.SpeakerFormat = 0x%.2x\n",(u32)ANX7150_edid_result.SpeakerFormat);\r
- }\r
- }\r
- \r
- ANX7150_parse_edid_done = 1;\r
- kfree(ANX7150_EDID_Buf);\r
- ANX7150_EDID_Buf = NULL;\r
- return 0;\r
- \r
-err:\r
- if(ANX7150_EDID_Buf){\r
- kfree(ANX7150_EDID_Buf);\r
- ANX7150_EDID_Buf = NULL;\r
- }\r
- return ANX7150_edid_result.edid_errcode;\r
-}\r
-int ANX7150_GET_SENSE_STATE(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
-\r
- hdmi_dbg(&client->dev, "enter\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
-\r
- return (c & ANX7150_SYS_STATE_RSV_DET) ? 1 : 0;\r
-}\r
-int ANX7150_Get_Optimal_resolution(int resolution_set)\r
-{\r
- int resolution_real;\r
- int find_resolution = 0;\r
-\r
- switch(resolution_set){\r
- case HDMI_1280x720p_50Hz:\r
- if(ANX7150_edid_result.supported_720p_50Hz){\r
- resolution_real = HDMI_1280x720p_50Hz;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_1280x720p_60Hz:\r
- if(ANX7150_edid_result.supported_720p_60Hz){\r
- resolution_real = HDMI_1280x720p_60Hz;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_720x576p_50Hz_4x3:\r
- if(ANX7150_edid_result.supported_576p_50Hz){\r
- resolution_real = HDMI_720x576p_50Hz_4x3;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_720x576p_50Hz_16x9:\r
- if(ANX7150_edid_result.supported_576p_50Hz){\r
- resolution_real = HDMI_720x576p_50Hz_16x9;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_720x480p_60Hz_4x3:\r
- if(ANX7150_edid_result.supported_720x480p_60Hz){\r
- resolution_real = HDMI_720x480p_60Hz_4x3;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_720x480p_60Hz_16x9:\r
- if(ANX7150_edid_result.supported_720x480p_60Hz){\r
- resolution_real = HDMI_720x480p_60Hz_16x9;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_1920x1080p_50Hz:\r
- if(ANX7150_edid_result.supported_1080p_50Hz){\r
- resolution_real = HDMI_1920x1080p_50Hz;\r
- find_resolution = 1;\r
- }\r
- break;\r
- case HDMI_1920x1080p_60Hz:\r
- if(ANX7150_edid_result.supported_1080p_60Hz){\r
- resolution_real = HDMI_1920x1080p_60Hz;\r
- find_resolution = 1;\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- if(find_resolution == 0){\r
-\r
- if(ANX7150_edid_result.supported_720p_50Hz)\r
- resolution_real = HDMI_1280x720p_50Hz;\r
- else if(ANX7150_edid_result.supported_720p_60Hz)\r
- resolution_real = HDMI_1280x720p_60Hz;\r
- else if(ANX7150_edid_result.supported_576p_50Hz)\r
- resolution_real = HDMI_720x576p_50Hz_4x3;\r
- else if(ANX7150_edid_result.supported_720x480p_60Hz)\r
- resolution_real = HDMI_720x480p_60Hz_4x3;\r
- else if(ANX7150_edid_result.supported_1080p_50Hz)\r
- resolution_real = HDMI_1920x1080p_50Hz;\r
- else if(ANX7150_edid_result.supported_1080p_60Hz)\r
- resolution_real = HDMI_1920x1080p_60Hz;\r
- else\r
- resolution_real = HDMI_1280x720p_50Hz;\r
- }\r
-\r
- return resolution_real;\r
-}\r
-void ANX7150_API_HDCP_ONorOFF(u8 HDCP_ONorOFF)\r
-{ \r
- ANX7150_HDCP_enable = HDCP_ONorOFF;// 1: on; 0:off\r
-}\r
-static void ANX7150_API_Video_Config(u8 video_id,u8 input_pixel_rpt_time)\r
-{
- ANX7150_video_timing_id = video_id;
- ANX7150_in_pix_rpt = input_pixel_rpt_time;
-}\r
-static void ANX7150_API_Packets_Config(u8 pkt_sel)\r
-{
- s_ANX7150_packet_config.packets_need_config = pkt_sel;
-}\r
-static void ANX7150_API_AVI_Config(u8 pb1,u8 pb2,u8 pb3,u8 pb4,u8 pb5,\r
- u8 pb6,u8 pb7,u8 pb8,u8 pb9,u8 pb10,u8 pb11,u8 pb12,u8 pb13)
-{
- s_ANX7150_packet_config.avi_info.pb_u8[1] = pb1;
- s_ANX7150_packet_config.avi_info.pb_u8[2] = pb2;
- s_ANX7150_packet_config.avi_info.pb_u8[3] = pb3;
- s_ANX7150_packet_config.avi_info.pb_u8[4] = pb4;
- s_ANX7150_packet_config.avi_info.pb_u8[5] = pb5;
- s_ANX7150_packet_config.avi_info.pb_u8[6] = pb6;
- s_ANX7150_packet_config.avi_info.pb_u8[7] = pb7;
- s_ANX7150_packet_config.avi_info.pb_u8[8] = pb8;
- s_ANX7150_packet_config.avi_info.pb_u8[9] = pb9;
- s_ANX7150_packet_config.avi_info.pb_u8[10] = pb10;
- s_ANX7150_packet_config.avi_info.pb_u8[11] = pb11;
- s_ANX7150_packet_config.avi_info.pb_u8[12] = pb12;
- s_ANX7150_packet_config.avi_info.pb_u8[13] = pb13;
-}\r
-static void ANX7150_API_AUD_INFO_Config(u8 pb1,u8 pb2,u8 pb3,u8 pb4,u8 pb5,\r
- u8 pb6,u8 pb7,u8 pb8,u8 pb9,u8 pb10)
-{
- s_ANX7150_packet_config.audio_info.pb_u8[1] = pb1;
- s_ANX7150_packet_config.audio_info.pb_u8[2] = pb2;
- s_ANX7150_packet_config.audio_info.pb_u8[3] = pb3;
- s_ANX7150_packet_config.audio_info.pb_u8[4] = pb4;
- s_ANX7150_packet_config.audio_info.pb_u8[5] = pb5;
- s_ANX7150_packet_config.audio_info.pb_u8[6] = pb6;
- s_ANX7150_packet_config.audio_info.pb_u8[7] = pb7;
- s_ANX7150_packet_config.audio_info.pb_u8[8] = pb8;
- s_ANX7150_packet_config.audio_info.pb_u8[9] = pb9;
- s_ANX7150_packet_config.audio_info.pb_u8[10] = pb10;
-}\r
-static void ANX7150_API_AUD_CHStatus_Config(u8 MODE,u8 PCM_MODE,u8 SW_CPRGT,u8 NON_PCM,\r
- u8 PROF_APP,u8 CAT_CODE,u8 CH_NUM,u8 SOURCE_NUM,u8 CLK_ACCUR,u8 Fs)
-{
- //MODE: 0x00 = PCM Audio
- //PCM_MODE: 0x00 = 2 audio channels without pre-emphasis;
- //0x01 = 2 audio channels with 50/15 usec pre-emphasis;
- //SW_CPRGT: 0x00 = copyright is asserted;
- // 0x01 = copyright is not asserted;
- //NON_PCM: 0x00 = Represents linear PCM
- //0x01 = For other purposes
- //PROF_APP: 0x00 = consumer applications;
- // 0x01 = professional applications;
-
- //CAT_CODE: Category code
- //CH_NUM: 0x00 = Do not take into account
- // 0x01 = left channel for stereo channel format
- // 0x02 = right channel for stereo channel format
- //SOURCE_NUM: source number
- // 0x00 = Do not take into account
- // 0x01 = 1; 0x02 = 2; 0x03 = 3
- //CLK_ACCUR: 0x00 = level II
- // 0x01 = level I
- // 0x02 = level III
- // else reserved;
-
- s_ANX7150_audio_config.i2s_config.Channel_status1 = (MODE << 7) | (PCM_MODE << 5) |
- (SW_CPRGT << 2) | (NON_PCM << 1) | PROF_APP;
- s_ANX7150_audio_config.i2s_config.Channel_status2 = CAT_CODE;
- s_ANX7150_audio_config.i2s_config.Channel_status3 = (CH_NUM << 7) | SOURCE_NUM;
- s_ANX7150_audio_config.i2s_config.Channel_status4 = (CLK_ACCUR << 5) | Fs;\r
-}\r
-void ANX7150_API_System_Config(void)\r
-{\r
- ANX7150_API_Video_Config(g_video_format,input_pixel_clk_1x_repeatition);\r
- ANX7150_API_Packets_Config(ANX7150_avi_sel | ANX7150_audio_sel);\r
- if (s_ANX7150_packet_config.packets_need_config & ANX7150_avi_sel)\r
- ANX7150_API_AVI_Config( 0x00,source_ratio,null,null,null,null,null,null,null,null,null,null,null);\r
- if (s_ANX7150_packet_config.packets_need_config & ANX7150_audio_sel)\r
- ANX7150_API_AUD_INFO_Config(null,null,null,null,null,null,null,null,null,null);\r
- ANX7150_API_AUD_CHStatus_Config(null,null,null,null,null,null,null,null,null,g_audio_format);\r
-\r
-// ANX7150_system_config_done = 1;\r
-}\r
-\r
-static int anx7150_blue_screen_format_config(struct i2c_client *client)\r
-{\r
- int rc = 0 ;\r
- char c;\r
- \r
- // TODO:Add ITU 601 format.(Now only ITU 709 format added)\r
- switch (ANX7150_RGBorYCbCr)\r
- {\r
- case ANX7150_RGB: //select RGB mode\r
- c = 0x10;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
- c = 0xeb;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
- c = 0x10;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
- break;\r
- case ANX7150_YCbCr422: //select YCbCr4:2:2 mode\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
- c = 0xad;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
- c = 0x2a;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
- break;\r
- case ANX7150_YCbCr444: //select YCbCr4:4:4 mode\r
- c = 0x1a;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN0_REG, &c);\r
- c = 0xad;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN1_REG, &c);\r
- c = 0x2a;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_BLUESCREEN2_REG, &c);\r
- break;\r
- default:\r
- break;\r
- }\r
- return rc;\r
-}\r
-static void ANX7150_Get_Video_Timing(void)\r
-{\r
- u8 i;\r
- \r
-//#ifdef ITU656\r
- for (i = 0; i < 18; i++)\r
- {\r
- switch (ANX7150_video_timing_id)\r
- {\r
- case ANX7150_V640x480p_60Hz:\r
- //D("640x480p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_640x480p_60Hz[i];\r
- break;\r
- case ANX7150_V720x480p_60Hz_4x3:\r
- case ANX7150_V720x480p_60Hz_16x9:\r
- //D("720x480p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x480p_60Hz[i];\r
- break;\r
- case ANX7150_V1280x720p_60Hz:\r
- //D("1280x720p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1280x720p_60Hz[i];\r
- break;\r
- case ANX7150_V1920x1080i_60Hz:\r
- //D("1920x1080i_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1920x1080i_60Hz[i];\r
- break;\r
- case ANX7150_V720x480i_60Hz_4x3:\r
- case ANX7150_V720x480i_60Hz_16x9:\r
- //D("720x480i_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x480i_60Hz[i];\r
- break;\r
- case ANX7150_V720x576p_50Hz_4x3:\r
- case ANX7150_V720x576p_50Hz_16x9:\r
- //D("720x576p_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x576p_50Hz[i];\r
- break;\r
- case ANX7150_V1280x720p_50Hz:\r
- //D("1280x720p_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1280x720p_50Hz[i];\r
- break;\r
- case ANX7150_V1920x1080i_50Hz:\r
- //D("1920x1080i_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_1920x1080i_50Hz[i];\r
- break;\r
- case ANX7150_V720x576i_50Hz_4x3:\r
- case ANX7150_V720x576i_50Hz_16x9:\r
- //D("720x576i_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = ANX7150_video_timingtype_table.ANX7150_720x576i_50Hz[i];\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- //D("Video_Timing_Parameter[%.2x]=%.2x\n", (u32)i, (u32) ANX7150_video_timing_parameter[i]);\r
- }\r
- /*#else\r
- for(i = 0; i < 18; i++)\r
- {\r
- switch(ANX7150_video_timing_id)\r
- {\r
- case ANX7150_V640x480p_60Hz:\r
- //D("640x480p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V720x480p_60Hz_4x3:\r
- case ANX7150_V720x480p_60Hz_16x9:\r
- //D("720x480p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 18 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V1280x720p_60Hz:\r
- //D("1280x720p_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 36 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V1920x1080i_60Hz:\r
- //D("1920x1080i_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 54 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V720x480i_60Hz_4x3:\r
- case ANX7150_V720x480i_60Hz_16x9:\r
- //D("720x480i_60Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 72 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V720x576p_50Hz_4x3:\r
- case ANX7150_V720x576p_50Hz_16x9:\r
- //D("720x576p_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 90 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V1280x720p_50Hz:\r
- //D("1280x720p_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 108 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V1920x1080i_50Hz:\r
- //D("1920x1080i_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 126 + i);\r
- DRVDelayMs(3);\r
- break;\r
- case ANX7150_V720x576i_50Hz_4x3:\r
- case ANX7150_V720x576i_50Hz_16x9:\r
- //D("720x576i_50Hz!\n");\r
- ANX7150_video_timing_parameter[i] = Load_from_EEPROM(0, 144 + i);\r
- DRVDelayMs(3);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- //D("Video_Timing_Parameter[%.2x]=%.2x\n", (u32)i, (u32) ANX7150_video_timing_parameter[i]);\r
- }\r
- #endif*/\r
-}\r
-static void ANX7150_Parse_Video_Format(void)\r
-{\r
- switch (ANX7150_video_format_config)\r
- {\r
- case ANX7150_RGB_YCrCb444_SepSync:\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- //D("RGB_YCrCb444_SepSync mode!\n");\r
- break;\r
- case ANX7150_YCrCb422_SepSync:\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- //D("YCrCb422_SepSync mode!\n");\r
- break;\r
- case ANX7150_YCrCb422_EmbSync:\r
- //D("YCrCb422_EmbSync mode!\n");\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_emb_sync_mode = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- case ANX7150_YCMux422_SepSync_Mode1:\r
- //D("YCMux422_SepSync_Mode1 mode!\n");\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_ycmux_u8_sel = 0;\r
- ANX7150_demux_yc_en = 1;\r
- break;\r
- case ANX7150_YCMux422_SepSync_Mode2:\r
- //D("YCMux422_SepSync_Mode2 mode!\n");\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_ycmux_u8_sel = 1;\r
- ANX7150_demux_yc_en = 1;\r
- break;\r
- case ANX7150_YCMux422_EmbSync_Mode1:\r
- //D("YCMux422_EmbSync_Mode1 mode!\n");\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_emb_sync_mode = 1;\r
- ANX7150_ycmux_u8_sel = 0;\r
- ANX7150_demux_yc_en = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- case ANX7150_YCMux422_EmbSync_Mode2:\r
- //D("YCMux422_EmbSync_Mode2 mode!\n");\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_emb_sync_mode = 1;\r
- ANX7150_ycmux_u8_sel = 1;\r
- ANX7150_demux_yc_en = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- case ANX7150_RGB_YCrCb444_DDR_SepSync:\r
- //D("RGB_YCrCb444_DDR_SepSync mode!\n");\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_ddr_bus_mode = 1;\r
- break;\r
- case ANX7150_RGB_YCrCb444_DDR_EmbSync:\r
- //D("RGB_YCrCb444_DDR_EmbSync mode!\n");\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_de_gen_en = 0;\r
- ANX7150_emb_sync_mode = 1;\r
- ANX7150_ddr_bus_mode = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- case ANX7150_RGB_YCrCb444_SepSync_No_DE:\r
- //D("RGB_YCrCb444_SepSync_No_DE mode!\n");\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- case ANX7150_YCrCb422_SepSync_No_DE:\r
- //D("YCrCb422_SepSync_No_DE mode!\n");\r
- ANX7150_emb_sync_mode = 0;\r
- ANX7150_demux_yc_en = 0;\r
- ANX7150_ddr_bus_mode = 0;\r
- ANX7150_de_gen_en = 1;\r
- ANX7150_Get_Video_Timing();\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-static int anx7150_de_generator(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- u8 video_type,hsync_pol,vsync_pol,v_fp,v_bp,vsync_width;\r
- u8 hsync_width_low,hsync_width_high,v_active_low,v_active_high;\r
- u8 h_active_low,h_active_high,h_res_low,h_res_high,h_bp_low,h_bp_high;\r
- u32 hsync_width,h_active,h_res,h_bp;\r
-\r
- video_type = ANX7150_video_timing_parameter[15];\r
- hsync_pol = ANX7150_video_timing_parameter[16];\r
- vsync_pol = ANX7150_video_timing_parameter[17];\r
- v_fp = ANX7150_video_timing_parameter[12];\r
- v_bp = ANX7150_video_timing_parameter[11];\r
- vsync_width = ANX7150_video_timing_parameter[10];\r
- hsync_width = ANX7150_video_timing_parameter[5];\r
- hsync_width = (hsync_width << 8) + ANX7150_video_timing_parameter[4];\r
- v_active_high = ANX7150_video_timing_parameter[9];\r
- v_active_low = ANX7150_video_timing_parameter[8];\r
- h_active = ANX7150_video_timing_parameter[3];\r
- h_active = (h_active << 8) + ANX7150_video_timing_parameter[2];\r
- h_res = ANX7150_video_timing_parameter[1];\r
- h_res = (h_res << 8) + ANX7150_video_timing_parameter[0];\r
- h_bp = ANX7150_video_timing_parameter[7];\r
- h_bp = (h_bp << 8) + ANX7150_video_timing_parameter[6];\r
- if (ANX7150_demux_yc_en)\r
- {\r
- hsync_width = 2* hsync_width;\r
- h_active = 2 * h_active;\r
- h_res = 2 * h_res;\r
- h_bp = 2 * h_bp;\r
- }\r
- hsync_width_low = hsync_width & 0xff;\r
- hsync_width_high = (hsync_width >> 8) & 0xff;\r
- h_active_low = h_active & 0xff;\r
- h_active_high = (h_active >> 8) & 0xff;\r
- h_res_low = h_res & 0xff;\r
- h_res_high = (h_res >> 8) & 0xff;\r
- h_bp_low = h_bp & 0xff;\r
- h_bp_high = (h_bp >> 8) & 0xff;\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xf7) | video_type;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xdf) | hsync_pol;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xbf) | vsync_pol;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = v_active_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINEL_REG, &c);\r
- c = v_active_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINEH_REG, &c);\r
- c = vsync_width;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_WID_REG, &c);\r
- c = v_bp;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_TAIL2VIDLINE_REG, &c);\r
- c = h_active_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_PIXL_REG, &c);\r
- c = h_active_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_PIXH_REG, &c);\r
- c = h_res_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_RESL_REG, &c);\r
- c = h_res_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_RESH_REG, &c);\r
- c = hsync_width_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHL_REG, &c);\r
- c = hsync_width_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHH_REG, &c);\r
- c = h_bp_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_BACKPORCHL_REG, &c);\r
- c = h_bp_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_BACKPORCHH_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c |= ANX7150_VID_CAPCTRL0_DEGEN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
-\r
- return rc;\r
-}\r
-static int anx7150_embed_sync_decode(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- char c;\r
- u8 video_type,hsync_pol,vsync_pol,v_fp,vsync_width;\r
- u8 h_fp_low,h_fp_high,hsync_width_low,hsync_width_high;\r
- u32 h_fp,hsync_width;\r
- \r
- video_type = ANX7150_video_timing_parameter[15];\r
- hsync_pol = ANX7150_video_timing_parameter[16];\r
- vsync_pol = ANX7150_video_timing_parameter[17];\r
- v_fp = ANX7150_video_timing_parameter[12];\r
- vsync_width = ANX7150_video_timing_parameter[10];\r
- h_fp = ANX7150_video_timing_parameter[14];\r
- h_fp = (h_fp << 8) + ANX7150_video_timing_parameter[13];\r
- hsync_width = ANX7150_video_timing_parameter[5];\r
- hsync_width = (hsync_width << 8) + ANX7150_video_timing_parameter[4];\r
- if (ANX7150_demux_yc_en)\r
- {\r
- h_fp = 2 * h_fp;\r
- hsync_width = 2* hsync_width;\r
- }\r
- h_fp_low = h_fp & 0xff;\r
- h_fp_high = (h_fp >> 8) & 0xff;\r
- hsync_width_low = hsync_width & 0xff;\r
- hsync_width_high = (hsync_width >> 8) & 0xff;\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xf7) | video_type;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xdf) | hsync_pol;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- c = (c & 0xbf) | vsync_pol;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL1_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c = c | ANX7150_VID_CAPCTRL0_EMSYNC_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
-\r
- c = v_fp;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_ACT_LINE2VSYNC_REG, &c);\r
- c = vsync_width;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VSYNC_WID_REG, &c);\r
- c = h_fp_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_FRONTPORCHL_REG, &c);\r
- c = h_fp_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_H_FRONTPORCHH_REG, &c);\r
- c = hsync_width_low;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHL_REG, &c);\r
- c = hsync_width_high;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HSYNC_ACT_WIDTHH_REG, &c);\r
- return rc;\r
-}\r
-int ANX7150_Blue_Screen(struct anx7150_pdata *anx)\r
-{\r
- return anx7150_blue_screen_format_config(anx->client);\r
-}\r
-//******************************Video Config***************************************\r
-int ANX7150_Config_Video(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- int retry = 0;\r
- char c,TX_is_HDMI;\r
- char cspace_y2r, y2r_sel, up_sample,range_y2r;\r
-\r
- cspace_y2r = 0;\r
- y2r_sel = 0;\r
- up_sample = 0;\r
- range_y2r = 0;\r
-\r
- //ANX7150_RGBorYCbCr = 0x00; //RGB\r
- //ANX7150_RGBorYCbCr = ANX7150_INPUT_COLORSPACE; //update\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c &= (~ANX7150_VID_CTRL_u8CTRL_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-/*\r
- if (!ANX7150_system_config_done)\r
- {\r
- D("System has not finished config!\n");\r
- return;\r
- }\r
-*/\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_STATE_REG, &c);\r
- if (!(c & 0x02))\r
- {\r
- hdmi_dbg(&client->dev, "No clock detected !\n");\r
- //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL2_REG, 0x02);\r
- return -1;\r
- }\r
-\r
- rc = anx7150_clean_hdcp(client);\r
-\r
- //color space issue\r
- switch (ANX7150_video_timing_id)\r
- {\r
- case ANX7150_V1280x720p_50Hz:\r
- case ANX7150_V1280x720p_60Hz:\r
- case ANX7150_V1920x1080i_60Hz:\r
- case ANX7150_V1920x1080i_50Hz:\r
- case ANX7150_V1920x1080p_60Hz:\r
- case ANX7150_V1920x1080p_50Hz:\r
- y2r_sel = ANX7150_CSC_BT709;\r
- break;\r
- default:\r
- y2r_sel = ANX7150_CSC_BT601;\r
- break;\r
- }\r
- //rang[0~255]/[16~235] select\r
- if (ANX7150_video_timing_id == ANX7150_V640x480p_60Hz)\r
- range_y2r = 1;//rang[0~255]\r
- else\r
- range_y2r = 0;//rang[16~235]\r
- if ((ANX7150_RGBorYCbCr == ANX7150_YCbCr422) && (!ANX7150_edid_result.ycbcr422_supported))\r
- {\r
- up_sample = 1;\r
- if (ANX7150_edid_result.ycbcr444_supported)\r
- cspace_y2r = 0;\r
- else\r
- cspace_y2r = 1;\r
- }\r
- if ((ANX7150_RGBorYCbCr == ANX7150_YCbCr444) && (!ANX7150_edid_result.ycbcr444_supported))\r
- {\r
- cspace_y2r = 1;\r
- }\r
- //Config the embeded blue screen format according to output video format.\r
- rc = anx7150_blue_screen_format_config(client);\r
-\r
- ANX7150_Parse_Video_Format();\r
-\r
- if (ANX7150_de_gen_en)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_de_gen_en!\n");\r
- rc = anx7150_de_generator(client);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_DEGEN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- }\r
- if (ANX7150_emb_sync_mode)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_Embed_Sync_Decode!\n");\r
- rc = anx7150_embed_sync_decode(client);\r
- \r
- if (ANX7150_ddr_bus_mode) //jack wen; for DDR embeded sync\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- c |= (0x04);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- c &= (0xfb);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- }\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_EMSYNC_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- }\r
- if (ANX7150_demux_yc_en)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c |= (ANX7150_VID_CAPCTRL0_DEMUX_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- \r
- if (ANX7150_ycmux_u8_sel)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_YCu8_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- //jack wen, u8 mapping for yc mux, D3-8,1-0 -->D1-4\r
- hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!####D1-4\n");\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-\r
- c = 0x0d;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
- c = 0x0c;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
- c = 0x0b;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
- c = 0x0a;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
- c = 0x09;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL7, &c);\r
- c = 0x08;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL6, &c);\r
- c = 0x01;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL5, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL4, &c);\r
- //\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c &= (~ANX7150_VID_CTRL_YCu8_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- //jack wen, u8 mapping for yc mux, D3-8,1-0 -->D5-8,\r
- hdmi_dbg(&client->dev, "ANX7150_demux_yc_en!####D5-8\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- \r
- c = 0x0d;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL15, &c);\r
- c = 0x0c;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL14, &c);\r
- c = 0x0b;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL3, &c);\r
- c = 0x0a;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL12, &c);\r
- c = 0x09;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
- c = 0x08;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
- c = 0x01;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
- //\r
- }\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_DEMUX_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- //jack wen\r
-\r
- //\r
-\r
- }\r
- if (ANX7150_ddr_bus_mode)\r
- {\r
- //D("ANX7150_ddr_bus_mode!\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c |= (ANX7150_VID_CAPCTRL0_DV_BUSMODE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- //jack wen\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- c = (c & 0xfc) | 0x02;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_YCu8_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- \r
- //jack wen\r
-\r
- if (ANX7150_ddr_edge)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c |= (ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- }\r
-\r
- //jack wen for DDR+seperate maping\r
- if (ANX7150_video_format_config == 0x07)//jack wen, DDR yc422, 601,\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_DDR_601_Maping!\n");\r
- \r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_u8CTRL_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-\r
- c = 0x0b;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL23, &c);\r
- c = 0x0a;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL22, &c);\r
- c = 0x09;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL21, &c);\r
- c = 0x08;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL20, &c);\r
- c = 0x07;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL19, &c);\r
- c = 0x06;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL18, &c);\r
- c = 0x05;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL17, &c);\r
- c = 0x04;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL16, &c);\r
-\r
- c = 0x17;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL15, &c);\r
- c = 0x16;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL14, &c);\r
- c = 0x15;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL13, &c);\r
- c = 0x14;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL12, &c);\r
- c = 0x13;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL11, &c);\r
- c = 0x12;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL10, &c);\r
- c = 0x11;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL9, &c);\r
- c = 0x10;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL8, &c);\r
-\r
- c = 0x03;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL7, &c);\r
- c = 0x02;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL6, &c);\r
- c = 0x01;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL5, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL4, &c);\r
- c = 0x0f;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL3, &c);\r
- c = 0x0e;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL2, &c);\r
- c = 0x0d;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL1, &c);\r
- c = 0x0c;\r
- rc = anx7150_i2c_write_p0_reg(client, VID_u8_CTRL0, &c);\r
-\r
- }\r
- else if (ANX7150_video_format_config == 0x08)//jack wen, DDR yc422, 656,\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150_DDR_656_Maping!\n");\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c &= (~ANX7150_VID_CTRL_u8CTRL_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- }\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_DV_BUSMODE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
- c &= (~ANX7150_VID_CAPCTRL0_DDR_EDGE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CAPCTRL0_REG, &c);\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- c &= (0xfc);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL4_REG, &c);\r
- }\r
-\r
- if (cspace_y2r)\r
- {\r
- hdmi_dbg(&client->dev, "Color space Y2R enabled********\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c |= (ANX7150_VID_MODE_CSPACE_Y2R);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- if (y2r_sel)\r
- {\r
- hdmi_dbg(&client->dev, "Y2R_SEL!\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c |= (ANX7150_VID_MODE_Y2R_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c &= (~ANX7150_VID_MODE_Y2R_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c); \r
- }\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c &= (~ANX7150_VID_MODE_CSPACE_Y2R);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
-\r
- if (up_sample)\r
- {\r
- hdmi_dbg(&client->dev, "UP_SAMPLE!\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c |= (ANX7150_VID_MODE_UPSAMPLE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c &= (~ANX7150_VID_MODE_UPSAMPLE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
-\r
- if (range_y2r)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c |= (ANX7150_VID_MODE_RANGE_Y2R);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
- else\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c &= (~ANX7150_VID_MODE_RANGE_Y2R);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- }\r
-\r
- if (!ANX7150_pix_rpt_set_by_sys)\r
- {\r
- if ((ANX7150_video_timing_id == ANX7150_V720x480i_60Hz_16x9)\r
- || (ANX7150_video_timing_id == ANX7150_V720x576i_50Hz_16x9)\r
- || (ANX7150_video_timing_id == ANX7150_V720x480i_60Hz_4x3)\r
- || (ANX7150_video_timing_id == ANX7150_V720x576i_50Hz_4x3))\r
- ANX7150_tx_pix_rpt = 1;\r
- else\r
- ANX7150_tx_pix_rpt = 0;\r
- }\r
- //set input pixel repeat times\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- c = ((c & 0xfc) |ANX7150_in_pix_rpt);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_MODE_REG, &c);\r
- //set link pixel repeat times\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c = ((c & 0xfc) |ANX7150_tx_pix_rpt);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
-\r
- if ((ANX7150_in_pix_rpt != ANX7150_in_pix_rpt_bkp)\r
- ||(ANX7150_tx_pix_rpt != ANX7150_tx_pix_rpt_bkp) )\r
- {\r
- c = 0x02;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL2_REG, &c);\r
- hdmi_dbg(&client->dev, "MISC_Reset!\n");\r
- ANX7150_in_pix_rpt_bkp = ANX7150_in_pix_rpt;\r
- ANX7150_tx_pix_rpt_bkp = ANX7150_tx_pix_rpt;\r
- }\r
- //enable video input\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- c |= (ANX7150_VID_CTRL_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_VID_CTRL_REG, &c);\r
- //D("Video configure OK!\n");\r
-\r
- retry = 0;\r
- do{\r
- mdelay(60);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_VID_STATUS_REG, &c);\r
- if (c & ANX7150_VID_STATUS_VID_STABLE){\r
- hdmi_dbg(&client->dev, "Video stable, continue!\n");\r
- break;\r
- }\r
- else{\r
- hdmi_dbg(&client->dev,"Video not stable!, retry = %d\n", retry);\r
- }\r
- }while(retry++ < 5);\r
-\r
- if (cspace_y2r)\r
- ANX7150_RGBorYCbCr = ANX7150_RGB;\r
- //Enable video CLK,Format change after config video.\r
- // ANX7150_i2c_read_p0_reg(ANX7150_INTR1_MASK_REG, &c);\r
- // ANX7150_i2c_write_p0_reg(ANX7150_INTR1_MASK_REG, c |0x01);//3\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
- c |= (0x48);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR2_MASK_REG, &c);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
- c |= (0x40);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR3_MASK_REG, &c);\r
- \r
- if (ANX7150_edid_result.is_HDMI)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c |= (0x02);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- hdmi_dbg(&client->dev,"ANX7150 is set to HDMI mode\n");\r
- }\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- TX_is_HDMI = c & 0x02;\r
-\r
- if (TX_is_HDMI == 0x02)\r
- {\r
- anx7150_set_avmute(client);//wen\r
- }\r
-\r
- //reset TMDS link to align 4 channels xy 061120\r
- hdmi_dbg(&client->dev,"reset TMDS link to align 4 channels\n");\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SRST_REG, &c);\r
- c |= (ANX7150_TX_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
- c &= (~ANX7150_TX_RST);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SRST_REG, &c);\r
- \r
- //Enable TMDS clock output // just enable u87, and let the other u8s along to avoid overwriting.\r
- hdmi_dbg(&client->dev,"Enable TMDS clock output\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- c |= (ANX7150_TMDS_CLKCH_MUTE);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c);\r
- if(ANX7150_HDCP_enable)\r
- mdelay(100); //400ms only for HDCP CTS\r
-\r
- //ANX7150_i2c_read_p0_reg(ANX7150_VID_MODE_REG, &c); //zy 061110\r
- return 0;\r
-}\r
-static u8 anx7150_config_i2s(struct i2c_client *client)\r
-{\r
- int rc;\r
- char c = 0x00;\r
- u8 exe_result = 0x00;\r
- char c1 = 0x00;\r
-\r
- hdmi_dbg(&client->dev,"ANX7150: config i2s audio.\n");\r
-\r
- //select SCK as source\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= ~ANX7150_HDMI_AUDCTRL1_CLK_SEL;\r
- hdmi_dbg(&client->dev,"select SCK as source, c = 0x%.2x\n",(u32)c);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
-\r
- //config i2s channel\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c1 = s_ANX7150_audio_config.i2s_config.audio_channel; // need u8[5:2]\r
- c1 &= 0x3c;\r
- c &= ~0x3c;\r
- c |= c1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- hdmi_dbg(&client->dev,"config i2s channel, c = 0x%.2x\n",(u32)c);\r
- \r
- //config i2s format\r
- //ANX7150_i2c_read_p0_reg(ANX7150_I2S_CTRL_REG, &c);\r
- c = s_ANX7150_audio_config.i2s_config.i2s_format;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2S_CTRL_REG, &c);\r
- hdmi_dbg(&client->dev,"config i2s format, c = 0x%.2x\n",(u32)c);\r
-\r
- //map i2s fifo\r
-\r
- //TODO: config I2S channel map register according to system\r
-\r
-\r
- //ANX7150_i2c_write_p0_reg(ANX7150_I2SCH_CTRL_REG, c);\r
-\r
- //swap right/left channel\r
- /*ANX7150_i2c_read_p0_reg(ANX7150_I2SCH_SWCTRL_REG, &c);\r
- c1 = 0x00;\r
- c1 &= 0xf0;\r
- c &= ~0xf0;\r
- c |= c1;\r
- ANX7150_i2c_write_p0_reg(ANX7150_I2SCH_SWCTRL_REG, c);\r
- D("map i2s ffio, c = 0x%.2x\n",(u32)c);*/\r
-\r
- //down sample\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c1 = s_ANX7150_audio_config.down_sample;\r
- c1 &= 0x60;\r
- c &= ~0x60;\r
- c |= c1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- hdmi_dbg(&client->dev,"down sample, c = 0x%.2x\n",(u32)c);\r
-\r
- //config i2s channel status(5 regs)\r
- c = s_ANX7150_audio_config.i2s_config.Channel_status1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS1_REG, &c);\r
- c = s_ANX7150_audio_config.i2s_config.Channel_status2;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS2_REG, &c);\r
- c = s_ANX7150_audio_config.i2s_config.Channel_status3;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS3_REG, &c);\r
- c = s_ANX7150_audio_config.i2s_config.Channel_status4;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- hdmi_dbg(&client->dev,"@@@@@@@@config i2s channel status4, c = 0x%.2x\n",(unsigned int)c);//jack wen\r
-\r
- c = s_ANX7150_audio_config.i2s_config.Channel_status5;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS5_REG, &c);\r
- hdmi_dbg(&client->dev,"config i2s channel status, c = 0x%.2x\n",(u32)c);\r
-\r
- exe_result = ANX7150_i2s_input;\r
- //D("return = 0x%.2x\n",(u32)exe_result);\r
-\r
- // open corresponding interrupt\r
- //ANX7150_i2c_read_p0_reg(ANX7150_INTR1_MASK_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_INTR1_MASK_REG, (c | 0x22) );\r
- //ANX7150_i2c_read_p0_reg(ANX7150_INTR3_MASK_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_INTR3_MASK_REG, (c | 0x20) );\r
-\r
-\r
- return exe_result;\r
-}\r
-\r
-static u8 anx7150_config_spdif(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 exe_result = 0x00;\r
- char c = 0x00;\r
- char c1 = 0x00;\r
- // u8 c2 = 0x00;\r
- // u8 freq_mclk = 0x00;\r
-\r
- hdmi_dbg(&client->dev, "ANX7150: config SPDIF audio.\n");\r
-\r
-\r
- //Select MCLK\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= (ANX7150_HDMI_AUDCTRL1_CLK_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- //D("ANX7150: enable SPDIF audio.\n");\r
- //Enable SPDIF\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= (ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- //adjust MCLK phase in interrupt routine\r
-\r
- // adjust FS_FREQ //FS_FREQ\r
- c1 = s_ANX7150_audio_config.i2s_config.Channel_status4 & 0x0f;\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SPDIFCH_STATUS_REG, &c);\r
- c &= ANX7150_SPDIFCH_STATUS_FS_FREG;\r
- c = c >> 4;\r
-\r
- if ( c != c1)\r
- {\r
- //D("adjust FS_FREQ by system!\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- c &= 0xf0;\r
- c |= c1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
-\r
- //enable using FS_FREQ from 0x59\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= (0x02);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
-\r
- // down sample\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c1 = s_ANX7150_audio_config.down_sample;\r
- c1 &= 0x60;\r
- c &= ~0x60;\r
- c |= c1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
-\r
- if (s_ANX7150_audio_config.down_sample) //zy 060816\r
- {\r
- // adjust FS_FREQ by system because down sample\r
- //D("adjust FS_FREQ by system because down sample!\n");\r
-\r
- c1 = s_ANX7150_audio_config.i2s_config.Channel_status4 & 0x0f;\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- \r
- c &= 0xf0;\r
- c |= c1;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- }\r
-\r
-\r
- // spdif is stable\r
- hdmi_dbg(&client->dev, "config SPDIF audio done");\r
- exe_result = ANX7150_spdif_input;\r
-\r
- // open corresponding interrupt\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
- c |= (0x32);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_INTR1_MASK_REG, &c);\r
- //ANX7150_i2c_read_p0_reg(ANX7150_INTR3_MASK_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_INTR3_MASK_REG, (c | 0xa1) );\r
- return exe_result;\r
-}\r
-\r
-static u8 anx7150_config_super_audio(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 exe_result = 0x00;\r
- u8 c = 0x00;\r
-\r
-\r
- //D("ANX7150: config one u8 audio.\n");\r
-\r
- // select sck as source\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= (~ANX7150_HDMI_AUDCTRL1_CLK_SEL);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
-\r
- // Enable stream 0x60\r
- c = s_ANX7150_audio_config.super_audio_config.one_u8_ctrl;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
-\r
-\r
- // Map stream 0x61\r
- // TODO: config super audio map register according to system\r
-\r
- exe_result = ANX7150_super_audio_input;\r
- return exe_result;\r
-\r
-}\r
-\r
-u8 ANX7150_Config_Audio(struct i2c_client *client)\r
-{\r
- int rc;\r
- char c = 0x00;\r
- u8 exe_result = 0x00;\r
- u8 audio_layout = 0x00;\r
- u8 fs = 0x00;\r
- u32 ACR_N = 0x0000;\r
-\r
- //set audio clock edge\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c = ((c & 0xf7) | ANX7150_audio_clock_edge);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- \r
- //cts get select from SCK\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c = (c & 0xef);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- hdmi_dbg(&client->dev, "audio_type = 0x%.2x\n",(u32)s_ANX7150_audio_config.audio_type);\r
- if (s_ANX7150_audio_config.audio_type & ANX7150_i2s_input)\r
- {\r
- hdmi_dbg(&client->dev, "Config I2s.\n");\r
- exe_result |= anx7150_config_i2s(client);\r
- }\r
- else\r
- {\r
- //disable I2S audio input\r
- hdmi_dbg(&client->dev, "Disable I2S audio input.\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= 0xc3;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
-\r
- if (s_ANX7150_audio_config.audio_type & ANX7150_spdif_input)\r
- {\r
- exe_result |= anx7150_config_spdif(client);\r
- }\r
- else\r
- {\r
- //disable SPDIF audio input\r
- hdmi_dbg(&client->dev, "Disable SPDIF audio input.\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= ~ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
-\r
- if (s_ANX7150_audio_config.audio_type & ANX7150_super_audio_input)\r
- {\r
- exe_result |= anx7150_config_super_audio(client);\r
- }\r
- else\r
- {\r
- //disable super audio output\r
- hdmi_dbg(&client->dev, "ANX7150: disable super audio output.\n");\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
- }\r
-\r
- if ((s_ANX7150_audio_config.audio_type & 0x07) == 0x00)\r
- {\r
- hdmi_dbg(&client->dev, "ANX7150 input no audio type.\n");\r
- }\r
-\r
- //audio layout\r
- if (s_ANX7150_audio_config.audio_type & ANX7150_i2s_input)\r
- {\r
- //ANX7150_i2c_read_p0_reg(ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- audio_layout = s_ANX7150_audio_config.audio_layout;\r
-\r
- //HDMI_RX_ReadI2C_RX0(0x15, &c);\r
-#if 0\r
- if ((c & 0x08) ==0x08 ) //u8[5:3]\r
- {\r
- audio_layout = 0x80;\r
- }\r
- else\r
- {\r
- audio_layout = 0x00;\r
- }\r
-#endif\r
- }\r
- if (s_ANX7150_audio_config.audio_type & ANX7150_super_audio_input)\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_ONEu8_AUD_CTRL_REG, &c);\r
- if ( c & 0xfc) //u8[5:3]\r
- {\r
- audio_layout = 0x80;\r
- }\r
- }\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c &= ~0x80;\r
- c |= audio_layout;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
-\r
- if ( (s_ANX7150_audio_config.audio_type & 0x07) == exe_result )\r
- {\r
- //Initial N value\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- fs = c & 0x0f;\r
- // set default value to N\r
- ACR_N = ANX7150_N_48k;\r
- switch (fs)\r
- {\r
- case(0x00)://44.1k\r
- ACR_N = ANX7150_N_44k;\r
- break;\r
- case(0x02)://48k\r
- ACR_N = ANX7150_N_48k;\r
- break;\r
- case(0x03)://32k\r
- ACR_N = ANX7150_N_32k;\r
- break;\r
- case(0x08)://88k\r
- ACR_N = ANX7150_N_88k;\r
- break;\r
- case(0x0a)://96k\r
- ACR_N = ANX7150_N_96k;\r
- break;\r
- case(0x0c)://176k\r
- ACR_N = ANX7150_N_176k;\r
- break;\r
- case(0x0e)://192k\r
- ACR_N = ANX7150_N_192k;\r
- break;\r
- default:\r
- dev_err(&client->dev, "note wrong fs.\n");\r
- break;\r
- }\r
- // write N(ACR) to corresponding regs\r
- c = ACR_N;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N1_SW_REG, &c);\r
- c = ACR_N>>8;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N2_SW_REG, &c);\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_ACR_N3_SW_REG, &c);\r
- \r
- // set the relation of MCLK and Fs xy 070117\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c = (c & 0xf8) | FREQ_MCLK;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- hdmi_dbg(&client->dev, "Audio MCLK input mode is: %.2x\n",(u32)FREQ_MCLK);\r
-\r
- //Enable control of ACR\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c |= (ANX7150_INFO_PKTCTRL1_ACR_EN);\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- //audio enable:\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= (ANX7150_HDMI_AUDCTRL1_IN_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
-\r
- return exe_result;\r
-\r
-}\r
-static u8 ANX7150_Checksum(infoframe_struct *p)\r
-{
- u8 checksum = 0x00;
- u8 i;
-
- checksum = p->type + p->length + p->version;
- for (i=1; i <= p->length; i++)
- {
- checksum += p->pb_u8[i];
- }
- checksum = ~checksum;
- checksum += 0x01;
-
- return checksum;
-}\r
-static u8 anx7150_load_infoframe(struct i2c_client *client, packet_type member,\r
- infoframe_struct *p)\r
-{\r
- int rc = 0;\r
- u8 exe_result = 0x00;\r
- u8 address[8] = {0x00,0x20,0x40,0x60,0x80,0x80,0xa0,0xa0};\r
- u8 i;\r
- char c;\r
-\r
- p->pb_u8[0] = ANX7150_Checksum(p);\r
-\r
- // write infoframe to according regs\r
- c = p->type;\r
- rc = anx7150_i2c_write_p1_reg(client, address[member], &c);\r
- c = p->version;\r
- rc = anx7150_i2c_write_p1_reg(client, address[member]+1, &c);\r
- c = p->length;\r
- rc = anx7150_i2c_write_p1_reg(client, address[member]+2, &c);\r
-\r
- for (i=0; i <= p->length; i++)\r
- {\r
- c = p->pb_u8[i];\r
- rc = anx7150_i2c_write_p1_reg(client, address[member]+3+i, &c);\r
- rc = anx7150_i2c_read_p1_reg(client, address[member]+3+i, &c);\r
- }\r
- return exe_result;\r
-}\r
-\r
-//*************** Config Packet ****************************\r
-u8 ANX7150_Config_Packet(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 exe_result = 0x00; // There is no use in current solution\r
- u8 info_packet_sel;\r
- char c;\r
-\r
- info_packet_sel = s_ANX7150_packet_config.packets_need_config;\r
- hdmi_dbg(&client->dev, "info_packet_sel = 0x%.2x\n",(u32) info_packet_sel);\r
- // New packet?\r
- if ( info_packet_sel != 0x00)\r
- {\r
- // avi infoframe\r
- if ( info_packet_sel & ANX7150_avi_sel )\r
- {\r
- c = s_ANX7150_packet_config.avi_info.pb_u8[1]; //color space\r
- c &= 0x9f;\r
- c |= (ANX7150_RGBorYCbCr << 5);\r
- s_ANX7150_packet_config.avi_info.pb_u8[1] = c | 0x10;\r
- switch(ANX7150_video_timing_id) \r
- {\r
- case ANX7150_V720x480p_60Hz_4x3:\r
- case ANX7150_V720x480p_60Hz_16x9:\r
- case ANX7150_V720x576p_50Hz_4x3:\r
- case ANX7150_V720x576p_50Hz_16x9:\r
- s_ANX7150_packet_config.avi_info.pb_u8[2] = 0x58;\r
- break;\r
- case ANX7150_V1280x720p_50Hz:\r
- case ANX7150_V1280x720p_60Hz:\r
- case ANX7150_V1920x1080p_50Hz:\r
- case ANX7150_V1920x1080p_60Hz:\r
- s_ANX7150_packet_config.avi_info.pb_u8[2] = 0xa8;\r
- break;\r
- default:\r
- s_ANX7150_packet_config.avi_info.pb_u8[2] = 0xa8;\r
- break;\r
- }\r
-\r
- c = s_ANX7150_packet_config.avi_info.pb_u8[4];// vid ID\r
- c = c & 0x80;\r
- s_ANX7150_packet_config.avi_info.pb_u8[4] = c | ANX7150_video_timing_id;\r
- c = s_ANX7150_packet_config.avi_info.pb_u8[5]; //repeat times\r
- c = c & 0xf0;\r
- c |= (ANX7150_tx_pix_rpt & 0x0f);\r
- s_ANX7150_packet_config.avi_info.pb_u8[5] = c;\r
- hdmi_dbg(&client->dev, "config avi infoframe packet.\n");\r
- // Disable repeater\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL1_AVI_RPT;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
-\r
- // Enable?wait:go\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- if (c & ANX7150_INFO_PKTCTRL1_AVI_EN)\r
- {\r
- //D("wait disable, config avi infoframe packet.\n");\r
- return exe_result; //jack wen\r
- }\r
-\r
- // load packet data to regs\r
- rc = anx7150_load_infoframe(client, ANX7150_avi_infoframe,\r
- &(s_ANX7150_packet_config.avi_info));\r
- // Enable and repeater\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c |= 0x30;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL1_REG, &c);\r
-\r
- // complete avi packet\r
- hdmi_dbg(&client->dev, "config avi infoframe packet done.\n");\r
- s_ANX7150_packet_config.packets_need_config &= ~ANX7150_avi_sel;\r
-\r
- }\r
-\r
- // audio infoframe\r
- if ( info_packet_sel & ANX7150_audio_sel )\r
- {\r
- hdmi_dbg(&client->dev, "config audio infoframe packet.\n");\r
-\r
- // Disable repeater\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_AIF_RPT;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
-\r
- // Enable?wait:go\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if (c & ANX7150_INFO_PKTCTRL2_AIF_EN)\r
- {\r
- //D("wait disable, config audio infoframe packet.\n");\r
- //return exe_result;//jack wen\r
- }\r
- // config packet\r
-\r
- // load packet data to regs\r
- \r
- anx7150_load_infoframe( client, ANX7150_audio_infoframe,\r
- &(s_ANX7150_packet_config.audio_info));\r
- // Enable and repeater\r
- rc = anx7150_i2c_read_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0x03;\r
- rc = anx7150_i2c_write_p1_reg(client, ANX7150_INFO_PKTCTRL2_REG, &c);\r
-\r
- // complete avi packet\r
-\r
- hdmi_dbg(&client->dev, "config audio infoframe packet done.\n");\r
- s_ANX7150_packet_config.packets_need_config &= ~ANX7150_audio_sel;\r
-\r
- }\r
-\r
- // config other 4 packets\r
- /*\r
-\r
- if( info_packet_sel & 0xfc )\r
- {\r
- D("other packets.\n");\r
-\r
- //find the current type need config\r
- if(info_packet_sel & ANX7150_spd_sel) type_sel = ANX7150_spd_sel;\r
- else if(info_packet_sel & ANX7150_mpeg_sel) type_sel = ANX7150_mpeg_sel;\r
- else if(info_packet_sel & ANX7150_acp_sel) type_sel = ANX7150_acp_sel;\r
- else if(info_packet_sel & ANX7150_isrc1_sel) type_sel = ANX7150_isrc1_sel;\r
- else if(info_packet_sel & ANX7150_isrc2_sel) type_sel = ANX7150_isrc2_sel;\r
- else type_sel = ANX7150_vendor_sel;\r
-\r
-\r
- // Disable repeater\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_AIF_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
-\r
- switch(type_sel)\r
- {\r
- case ANX7150_spd_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL1_SPD_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL1_REG, c);\r
-\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL1_SPD_EN)\r
- {\r
- D("wait disable, config spd infoframe packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- case ANX7150_mpeg_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_MPEG_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
-\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL2_MPEG_EN)\r
- {\r
- D("wait disable, config mpeg infoframe packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- case ANX7150_acp_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_UD0_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
-\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL2_UD0_EN)\r
- {\r
- D("wait disable, config mpeg infoframe packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- case ANX7150_isrc1_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_UD0_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL2_UD0_EN)\r
- {\r
- D("wait disable, config isrc1 packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- case ANX7150_isrc2_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_UD_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL2_UD_EN)\r
- {\r
- D("wait disable, config isrc2 packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- case ANX7150_vendor_sel:\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c &= ~ANX7150_INFO_PKTCTRL2_UD_RPT;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- if(c & ANX7150_INFO_PKTCTRL2_UD_EN)\r
- {\r
- D("wait disable, config vendor packet.\n");\r
- return exe_result;\r
- }\r
- break;\r
-\r
- default : break;\r
- }\r
-\r
-\r
- // config packet\r
- // TODO: config packet in top level\r
-\r
- // load packet data to regs\r
- switch(type_sel)\r
- {\r
- case ANX7150_spd_sel:\r
- ANX7150_Load_Infoframe( ANX7150_spd_infoframe,\r
- &(s_ANX7150_packet_config.spd_info));\r
- D("config spd done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL1_REG, &c);\r
- c |= 0xc0;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL1_REG, c);\r
- break;\r
-\r
- case ANX7150_mpeg_sel:\r
- ANX7150_Load_Infoframe( ANX7150_mpeg_infoframe,\r
- &(s_ANX7150_packet_config.mpeg_info));\r
- D("config mpeg done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0x0c;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- break;\r
-\r
- case ANX7150_acp_sel:\r
- ANX7150_Load_Packet( ANX7150_acp_packet,\r
- &(s_ANX7150_packet_config.acp_pkt));\r
- D("config acp done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0x30;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- break;\r
-\r
- case ANX7150_isrc1_sel:\r
- ANX7150_Load_Packet( ANX7150_isrc1_packet,\r
- &(s_ANX7150_packet_config.acp_pkt));\r
- D("config isrc1 done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0x30;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- break;\r
-\r
- case ANX7150_isrc2_sel:\r
- ANX7150_Load_Packet( ANX7150_isrc2_packet,\r
- &(s_ANX7150_packet_config.acp_pkt));\r
- D("config isrc2 done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0xc0;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- break;\r
-\r
- case ANX7150_vendor_sel:\r
- ANX7150_Load_Infoframe( ANX7150_vendor_infoframe,\r
- &(s_ANX7150_packet_config.vendor_info));\r
- D("config vendor done.\n");\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0xc0;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
- break;\r
-\r
- default : break;\r
- }\r
-\r
- // Enable and repeater\r
- ANX7150_i2c_read_p1_reg(ANX7150_INFO_PKTCTRL2_REG, &c);\r
- c |= 0x03;\r
- ANX7150_i2c_write_p1_reg(ANX7150_INFO_PKTCTRL2_REG, c);\r
-\r
- // complete config packet\r
- D("config other packets done.\n");\r
- s_ANX7150_packet_config.packets_need_config &= ~type_sel;\r
-\r
- }\r
- */\r
- }\r
-\r
-\r
- if ( s_ANX7150_packet_config.packets_need_config == 0x00)\r
- {\r
- hdmi_dbg(&client->dev, "config packets done\n");\r
- //ANX7150_Set_System_State(ANX7150_HDCP_AUTHENTICATION);\r
- }\r
-\r
-\r
- return exe_result;\r
-}\r
-//******************** HDCP process ********************************\r
-static int anx7150_hardware_hdcp_auth_init(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- u8 c;\r
-\r
-// ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c); //72:07.2 hdcp on\r
-// ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, (c | ANX7150_SYS_CTRL1_HDCPMODE));\r
- // disable hw hdcp\r
-// ANX7150_i2c_read_p0_reg(ANX7150_HDCP_CTRL0_REG, &c);\r
-// ANX7150_i2c_write_p0_reg(ANX7150_HDCP_CTRL0_REG, (c & (~ANX7150_HDCP_CTRL0_HW_AUTHEN)));\r
-\r
- //ANX7150_i2c_write_p0_reg(ANX7150_HDCP_CTRL0_REG, 0x03); //h/w auth off, jh simplay/hdcp\r
- c = 0x00;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c); //bit 0/1 off, as from start, we don't know if Bksv/srm/KSVList valid or not. SY.\r
-\r
- // DDC reset\r
- rc = anx7150_rst_ddcchannel(client);\r
-\r
- anx7150_initddc_read(client, 0x74, 0x00, 0x40, 0x01, 0x00);\r
- mdelay(5);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bcaps);\r
- hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): ANX7150_hdcp_bcaps = 0x%.2x\n", (u32)ANX7150_hdcp_bcaps);\r
-\r
- if (ANX7150_hdcp_bcaps & 0x02)\r
- { //enable 1.1 feature\r
- hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps supports 1.1\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- c |= ANX7150_HDCP_CTRL1_HDCP11_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- }\r
- else\r
- { //disable 1.1 feature and enable HDCP two special point check\r
- hdmi_dbg(&client->dev, "bcaps don't support 1.1\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- c = ((c & (~ANX7150_HDCP_CTRL1_HDCP11_EN)) | ANX7150_LINK_CHK_12_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- }\r
- //handle repeater bit. SY.\r
- if (ANX7150_hdcp_bcaps & 0x40)\r
- {\r
- //repeater\r
- hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps shows Sink is a repeater\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c |= ANX7150_HDCP_CTRL0_RX_REP;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- }\r
- else\r
- {\r
- //receiver\r
- hdmi_dbg(&client->dev, "ANX7150_Hardware_HDCP_Auth_Init(): bcaps shows Sink is a receiver\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= ~ANX7150_HDCP_CTRL0_RX_REP;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- }\r
- anx7150_rst_ddcchannel(client);\r
- ANX7150_hdcp_auth_en = 0;\r
-\r
- return rc;\r
-}\r
-static u8 anx7150_bksv_srm(struct i2c_client *client)\r
-{
- int rc = 0;\r
-#if 1
- u8 bksv[5],i,bksv_one,c1;
- anx7150_initddc_read(client, 0x74, 0x00, 0x00, 0x05, 0x00);\r
- mdelay(15);\r
- for (i = 0; i < 5; i ++)
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &bksv[i]);\r
- }
-
- bksv_one = 0;
- for (i = 0; i < 8; i++)
- {
- c1 = 0x01 << i;
- if (bksv[0] & c1)
- bksv_one ++;
- if (bksv[1] & c1)
- bksv_one ++;
- if (bksv[2] & c1)
- bksv_one ++;
- if (bksv[3] & c1)
- bksv_one ++;
- if (bksv[4] & c1)
- bksv_one ++;
- }
- //wen HDCP CTS
- if (bksv_one != 20)
- {
- hdmi_dbg(&client->dev, "BKSV check fail\n");\r
- return 0;
- }
- else
- {
- hdmi_dbg(&client->dev, "BKSV check OK\n");\r
- return 1;
- }
-#endif
-
-#if 0 //wen HDCP CTS
- /*address by gerard.zhu*/
- u8 i,j,bksv_ones_count,bksv_data[Bksv_Data_Nums] = {0};
- ANX7150_DDC_Addr bksv_ddc_addr;
- u32 bksv_length;
- ANX7150_DDC_Type ddc_type;
-
- i = 0;
- j = 0;
- bksv_ones_count = 0;
- bksv_ddc_addr.dev_addr = HDCP_Dev_Addr;
- bksv_ddc_addr.sgmt_addr = 0;
- bksv_ddc_addr.offset_addr = HDCP_Bksv_Offset;
- bksv_length = Bksv_Data_Nums;
- ddc_type = DDC_Hdcp;
-
- if (!ANX7150_DDC_Read(bksv_ddc_addr, bksv_data, bksv_length, ddc_type))
- {
- /*Judge validity for Bksv*/
- while (i < Bksv_Data_Nums)
- {
- while (j < 8)
- {
- if (((bksv_data[i] >> j) & 0x01) == 1)
- {
- bksv_ones_count++;
- }
- j++;
- }
- i++;
- j = 0;
- }
- if (bksv_ones_count != 20)
- {
- rk29printk ("!!!!BKSV 1s ¡Ù20\n"); //update rk29printk ("!!!!BKSV 1s ¡Ù20\n");
- return 0;
- }
- }
- /*end*/
-
- D("bksv is ready.\n");
- // TODO: Compare the bskv[] value to the revocation list to decide if this value is a illegal BKSV. This is system depended.
- //If illegal, return 0; legal, return 1. Now just return 1
- return 1;
-#endif
-}\r
-\r
-static u8 anx7150_is_ksvlist_vld(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
-//wen HDCP CTS\r
-#if 1\r
- hdmi_dbg(&client->dev, "ANX7150_IS_KSVList_VLD() is called.\n");\r
- anx7150_initddc_read(client, 0x74, 0x00, 0x41, 0x02, 0x00); //Bstatus, two u8s\r
- mdelay(5);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bstatus[0]);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_DDC_FIFO_ACC_REG, &ANX7150_hdcp_bstatus[1]);\r
-\r
- if ((ANX7150_hdcp_bstatus[0] & 0x80) | (ANX7150_hdcp_bstatus[1] & 0x08))\r
- {\r
- hdmi_dbg(&client->dev, "Max dev/cascade exceeded: ANX7150_hdcp_bstatus[0]: 0x%x,ANX7150_hdcp_bstatus[1]:0x%x\n", (u32)ANX7150_hdcp_bstatus[0],(u32)ANX7150_hdcp_bstatus[1]);\r
- return 0;//HDCP topology error. More than 127 RX are attached or more than seven levels of repeater are cascaded.\r
- }\r
- return 1;\r
-#endif\r
-//wen HDCP CTS\r
-\r
-}\r
-\r
-static void anx7150_show_video_parameter(struct i2c_client *client)\r
-{\r
- int rc = 0;\r
- // int h_res,h_act,v_res,v_act,h_fp,hsync_width,h_bp;\r
- char c, c1;\r
-\r
- hdmi_dbg(&client->dev, "\n\n**********************************ANX7150 Info**********************************\n");\r
-\r
- hdmi_dbg(&client->dev, " ANX7150 mode = Normal mode\n");\r
- if ((ANX7150_demux_yc_en == 1) && (ANX7150_emb_sync_mode == 0))\r
- hdmi_dbg(&client->dev, " Input video format = YC_MUX\n");\r
- if ((ANX7150_demux_yc_en == 0) && (ANX7150_emb_sync_mode == 1))\r
- hdmi_dbg(&client->dev, " Input video format = 656\n");\r
- if ((ANX7150_demux_yc_en == 1) && (ANX7150_emb_sync_mode == 1))\r
- hdmi_dbg(&client->dev, " Input video format = YC_MUX + 656\n");\r
- if ((ANX7150_demux_yc_en == 0) && (ANX7150_emb_sync_mode == 0))\r
- hdmi_dbg(&client->dev, " Input video format = Seperate Sync\n");\r
- if (ANX7150_de_gen_en)\r
- hdmi_dbg(&client->dev, " DE generator = Enable\n");\r
- else\r
- hdmi_dbg(&client->dev, " DE generator = Disable\n");\r
- if ((ANX7150_ddr_bus_mode == 1)&& (ANX7150_emb_sync_mode == 0))\r
- hdmi_dbg(&client->dev, " Input video format = DDR mode\n");\r
- else if ((ANX7150_ddr_bus_mode == 1)&& (ANX7150_emb_sync_mode == 1))\r
- hdmi_dbg(&client->dev, " Input video format = DDR mode + 656\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c1);\r
- c1 = (c1 & 0x02);\r
- if (c1)\r
- {\r
- hdmi_dbg(&client->dev, " Output video mode = HDMI\n");\r
- rc = anx7150_i2c_read_p0_reg(client, 0x04, &c);\r
- c = (c & 0x60) >> 5;\r
- switch (c)\r
- {\r
- case ANX7150_RGB:\r
- hdmi_dbg(&client->dev, " Output video color format = RGB\n");\r
- break;\r
- case ANX7150_YCbCr422:\r
- hdmi_dbg(&client->dev, " Output video color format = YCbCr422\n");\r
- break;\r
- case ANX7150_YCbCr444:\r
- hdmi_dbg(&client->dev, " Output video color format = YCbCr444\n");\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- else\r
- {\r
- hdmi_dbg(&client->dev, " Output video mode = DVI\n");\r
- hdmi_dbg(&client->dev, " Output video color format = RGB\n");\r
- }\r
-\r
- /*for(i = 0x10; i < 0x25; i ++)\r
- {\r
- ANX7150_i2c_read_p0_reg(i, &c );\r
- D("0x%.2x = 0x%.2x\n",(unsigned int)i,(unsigned int)c);\r
- }*/\r
- /* ANX7150_i2c_read_p0_reg(ANX7150_VID_STATUS_REG, &c);\r
- if((c & ANX7150_VID_STATUS_TYPE) == 0x04)\r
- D("Video Type = Interlace");\r
- else\r
- D("Video Type = Progressive");\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HRESH_REG, &c);\r
- h_res = c;\r
- h_res = h_res << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HRESL_REG, &c);\r
- h_res = h_res + c;\r
- D("H_resolution = %u\n",h_res);\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_PIXH_REG, &c);\r
- h_act = c;\r
- h_act = h_act << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_PIXL_REG, &c);\r
- h_act = h_act + c;\r
- D("H_active = %u\n",h_act);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VRESH_REG, &c);\r
- v_res = c;\r
- v_res = v_res << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VRESL_REG, &c);\r
- v_res = v_res + c;\r
- D("V_resolution = %u\n",v_res);\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTVIDLINEH_REG, &c);\r
- v_act = c;\r
- v_act = v_act << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTVIDLINEL_REG, &c);\r
- v_act = v_act + c;\r
- D("V_active = %u\n",v_act);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HFORNTPORCHH_REG, &c);\r
- h_fp = c;\r
- h_fp = h_fp << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HFORNTPORCHL_REG, &c);\r
- h_fp = h_fp + c;\r
- D("H_FP = %u\n",h_fp);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HBACKPORCHH_REG, &c);\r
- h_bp = c;\r
- h_bp = h_bp << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HBACKPORCHL_REG, &c);\r
- h_bp = h_bp + c;\r
- D("H_BP = %u\n",h_bp);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HSYNCWIDH_REG, &c);\r
- hsync_width = c;\r
- hsync_width = hsync_width << 8;\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_HSYNCWIDL_REG, &c);\r
- hsync_width = hsync_width + c;\r
- D("Hsync_width = %u\n",hsync_width);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_ACTLINE2VSYNC_REG, &c);\r
- D("Vsync_FP = %bu\n",c);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VSYNCTAIL2VIDLINE_REG, &c);\r
- D("Vsync_BP = %bu\n",c);\r
-\r
- ANX7150_i2c_read_p0_reg(ANX7150_VIDF_VSYNCWIDLINE_REG, &c);\r
- D("Vsync_width = %bu\n",c);*/\r
- {\r
- hdmi_dbg(&client->dev, " Normal mode output video format: \n");\r
- switch (ANX7150_video_timing_id)\r
- {\r
- case ANX7150_V720x480p_60Hz_4x3:\r
- case ANX7150_V720x480p_60Hz_16x9:\r
- hdmi_dbg(&client->dev, "720x480p@60\n");\r
- if (ANX7150_edid_result.supported_720x480p_60Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1280x720p_60Hz:\r
- hdmi_dbg(&client->dev, "1280x720p@60\n");\r
- if (ANX7150_edid_result.supported_720p_60Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1920x1080i_60Hz:\r
- hdmi_dbg(&client->dev, "1920x1080i@60\n");\r
- if (ANX7150_edid_result.supported_1080i_60Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1920x1080p_60Hz:\r
- hdmi_dbg(&client->dev, "1920x1080p@60\n");\r
- if (ANX7150_edid_result.supported_1080p_60Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1920x1080p_50Hz:\r
- hdmi_dbg(&client->dev, "1920x1080p@50\n");\r
- if (ANX7150_edid_result.supported_1080p_50Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1280x720p_50Hz:\r
- hdmi_dbg(&client->dev, "1280x720p@50\n");\r
- if (ANX7150_edid_result.supported_720p_50Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V1920x1080i_50Hz:\r
- hdmi_dbg(&client->dev, "1920x1080i@50\n");\r
- if (ANX7150_edid_result.supported_1080i_50Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V720x576p_50Hz_4x3:\r
- case ANX7150_V720x576p_50Hz_16x9:\r
- hdmi_dbg(&client->dev, "720x576p@50\n");\r
- if (ANX7150_edid_result.supported_576p_50Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V720x576i_50Hz_4x3:\r
- case ANX7150_V720x576i_50Hz_16x9:\r
- hdmi_dbg(&client->dev, "720x576i@50\n");\r
- if (ANX7150_edid_result.supported_576i_50Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- case ANX7150_V720x480i_60Hz_4x3:\r
- case ANX7150_V720x480i_60Hz_16x9:\r
- hdmi_dbg(&client->dev, "720x480i@60\n");\r
- if (ANX7150_edid_result.supported_720x480i_60Hz)\r
- hdmi_dbg(&client->dev, "and sink supports this format.\n");\r
- else\r
- hdmi_dbg(&client->dev, "but sink does not support this format.\n");\r
- break;\r
- default:\r
- hdmi_dbg(&client->dev, "unknown(video ID is: %.2x).\n",(u32)ANX7150_video_timing_id);\r
- break;\r
- }\r
- }\r
- if (c1)//HDMI output\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL0_REG, &c);\r
- c = c & 0x03;\r
- hdmi_dbg(&client->dev, " MCLK Frequence = ");\r
-\r
- switch (c)\r
- {\r
- case 0x00:\r
- hdmi_dbg(&client->dev, "128 * Fs.\n");\r
- break;\r
- case 0x01:\r
- hdmi_dbg(&client->dev, "256 * Fs.\n");\r
- break;\r
- case 0x02:\r
- hdmi_dbg(&client->dev, "384 * Fs.\n");\r
- break;\r
- case 0x03:\r
- hdmi_dbg(&client->dev, "512 * Fs.\n");\r
- break;\r
- default :\r
- hdmi_dbg(&client->dev, "Wrong MCLK output.\n");\r
- break;\r
- }\r
-\r
- if ( ANX7150_AUD_HW_INTERFACE == 0x01)\r
- {\r
- hdmi_dbg(&client->dev, " Input Audio Interface = I2S.\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- }\r
- else if (ANX7150_AUD_HW_INTERFACE == 0x02)\r
- {\r
- hdmi_dbg(&client->dev, " Input Audio Interface = SPDIF.\n");\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SPDIFCH_STATUS_REG, &c);\r
- c=c>>4;\r
- }\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_I2SCH_STATUS4_REG, &c);\r
- hdmi_dbg(&client->dev, " Audio Fs = ");\r
- c &= 0x0f;\r
- switch (c)\r
- {\r
- case 0x00:\r
- hdmi_dbg(&client->dev, " Audio Fs = 44.1 KHz.\n");\r
- break;\r
- case 0x02:\r
- hdmi_dbg(&client->dev, " Audio Fs = 48 KHz.\n");\r
- break;\r
- case 0x03:\r
- hdmi_dbg(&client->dev, " Audio Fs = 32 KHz.\n");\r
- break;\r
- case 0x08:\r
- hdmi_dbg(&client->dev, " Audio Fs = 88.2 KHz.\n");\r
- break;\r
- case 0x0a:\r
- hdmi_dbg(&client->dev, " Audio Fs = 96 KHz.\n\n");\r
- break;\r
- case 0x0c:\r
- hdmi_dbg(&client->dev, " Audio Fs = 176.4 KHz.\n");\r
- break;\r
- case 0x0e:\r
- hdmi_dbg(&client->dev, " Audio Fs = 192 KHz.\n");\r
- hdmi_dbg(&client->dev, "192 KHz.\n");\r
- break;\r
- default :\r
- hdmi_dbg(&client->dev, " Audio Fs = Wrong Fs output.\n");\r
- hdmi_dbg(&client->dev, "Wrong Fs output.\n");\r
- break;\r
- }\r
-\r
- if (ANX7150_HDCP_enable == 1)\r
- hdmi_dbg(&client->dev, " ANX7150_HDCP_Enable.\n");\r
- else\r
- hdmi_dbg(&client->dev, " ANX7150_HDCP_Disable.\n");\r
-\r
- }\r
- hdmi_dbg(&client->dev, "\n********************************************************************************\n\n");\r
-}\r
-void ANX7150_HDCP_Process(struct i2c_client *client, int enable)\r
-{\r
- int rc = 0;\r
- char c,i;\r
- //u8 c1;\r
- u8 Bksv_valid=0;//wen HDCP CTS\r
-\r
- if (ANX7150_HDCP_enable)\r
- { //HDCP_EN =1 means to do HDCP authentication,SWITCH4 = 0 means not to do HDCP authentication.\r
-\r
- //ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_SYS_CTRL1_REG, c | 0x04);//power on HDCP, 090630\r
-\r
- //ANX7150_i2c_read_p0_reg(ANX7150_INTR2_MASK_REG, &c);\r
- //ANX7150_i2c_write_p0_reg(ANX7150_INTR2_MASK_REG, c |0x03);\r
- mdelay(10);//let unencrypted video play a while, required by HDCP CTS. SY//wen HDCP CTS\r
- anx7150_set_avmute(client);//before auth, set_avmute//wen\r
- mdelay(10);//wen HDCP CTS\r
-\r
- if ( !ANX7150_hdcp_init_done )\r
- {\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- c |= ANX7150_SYS_CTRL1_HDCPMODE;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c);\r
- if (ANX7150_edid_result.is_HDMI)\r
- rc = anx7150_hardware_hdcp_auth_init(client);\r
- else\r
- { //DVI, disable 1.1 feature and enable HDCP two special point check\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- c = ((c & (~ANX7150_HDCP_CTRL1_HDCP11_EN)) | ANX7150_LINK_CHK_12_EN);\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL1_REG, &c);\r
- }\r
-\r
- //wen HDCP CTS\r
- if (!anx7150_bksv_srm(client))\r
- {\r
- anx7150_blue_screen_enable(client);\r
- anx7150_clear_avmute(client);\r
- Bksv_valid=0;\r
- return;\r
- }\r
- else //SY.\r
- {\r
- Bksv_valid=1;\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c |= 0x03;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- }\r
-\r
- ANX7150_hdcp_init_done = 1;\r
-//wen HDCP CTS\r
- }\r
-\r
-\r
-//wen HDCP CTS\r
- if ((Bksv_valid) && (!ANX7150_hdcp_auth_en))\r
- {\r
- hdmi_dbg(&client->dev, "enable hw hdcp\n");\r
- anx7150_rst_ddcchannel(client);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c |= ANX7150_HDCP_CTRL0_HW_AUTHEN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- ANX7150_hdcp_auth_en = 1;\r
- }\r
-\r
- if ((Bksv_valid) && (ANX7150_hdcp_wait_100ms_needed))\r
- {\r
- ANX7150_hdcp_wait_100ms_needed = 0;\r
- //disable audio\r
-\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= ~ANX7150_HDMI_AUDCTRL1_IN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- \r
- hdmi_dbg(&client->dev, "++++++++ANX7150_hdcp_wait_100ms_needed+++++++++\n");\r
- mdelay(150); // 100 -> 150\r
- return;\r
- }\r
-//wen HDCP CTS\r
-\r
- if (ANX7150_hdcp_auth_pass) //wen HDCP CTS\r
- {\r
- //Clear the SRM_Check_Pass u8, then when reauthentication occurs, firmware can catch it.\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= 0xfc;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
-\r
- //Enable HDCP Hardware encryption\r
- if (!ANX7150_hdcp_encryption)\r
- {\r
- anx7150_hdcp_encryption_enable(client);\r
- }\r
- if (ANX7150_send_blue_screen)\r
- {\r
- anx7150_blue_screen_disable(client);\r
- }\r
- if (ANX7150_avmute_enable)\r
- {\r
- anx7150_clear_avmute(client);\r
- }\r
-\r
- i = 0;\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
- while((c&0x04)==0x00)//wait for encryption.\r
- {\r
- mdelay(2);\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_STATUS_REG, &c);\r
- i++;\r
- if (i > 10)\r
- break;\r
- }\r
-\r
- //enable audio SY.\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= ANX7150_HDMI_AUDCTRL1_IN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- hdmi_dbg(&client->dev, "@@@@@ HDCP Auth PASSED! @@@@@\n");\r
-\r
- if (ANX7150_hdcp_bcaps & 0x40) //repeater\r
- {\r
- hdmi_dbg(&client->dev, "Find a repeater!\n");\r
- //actually it is KSVList check. we can't do SRM check due to the lack of SRM file. SY.\r
- if (!ANX7150_srm_checked)\r
- {\r
- if (!anx7150_is_ksvlist_vld(client))\r
- {\r
- hdmi_dbg(&client->dev, "ksvlist not good. disable encryption");\r
- anx7150_hdcp_encryption_disable(client);\r
- anx7150_blue_screen_enable(client);\r
- anx7150_clear_avmute(client);\r
- ANX7150_ksv_srm_pass = 0;\r
- anx7150_clean_hdcp(client);//SY.\r
- //remove below will pass 1b-05/1b-06\r
- //ANX7150_Set_System_State(ANX7150_WAIT_HOTPLUG);//SY.\r
- return;\r
- }\r
- ANX7150_srm_checked=1;\r
- ANX7150_ksv_srm_pass = 1;\r
- }\r
- }\r
- else\r
- {\r
- hdmi_dbg(&client->dev, "Find a receiver.\n");\r
- }\r
- }\r
- else //wen HDCP CTS\r
- {\r
- hdmi_dbg(&client->dev, "##### HDCP Auth FAILED! #####\n");\r
- //also need to disable HW AUTHEN\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- c &= ~ANX7150_HDCP_CTRL0_HW_AUTHEN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDCP_CTRL0_REG, &c);\r
- ANX7150_hdcp_auth_en = 0;\r
- //ANX7150_hdcp_init_done = 0;\r
- //ANX7150_hdcp_wait_100ms_needed = 1; //wen, update 080703\r
-\r
- if (ANX7150_hdcp_encryption)\r
- {\r
- anx7150_hdcp_encryption_disable(client);\r
- }\r
- if (!ANX7150_send_blue_screen)\r
- {\r
- anx7150_blue_screen_enable(client);\r
- }\r
- if (ANX7150_avmute_enable)\r
- {\r
- anx7150_clear_avmute(client);\r
- }\r
- //disable audio\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c &= ~ANX7150_HDMI_AUDCTRL1_IN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- \r
- return;\r
- }\r
-\r
- }\r
- else //wen HDCP CTS\r
- {\r
- hdmi_dbg(&client->dev, "hdcp pin is off.\n");\r
- if (ANX7150_send_blue_screen)\r
- {\r
- anx7150_blue_screen_disable(client);\r
- }\r
- if (ANX7150_avmute_enable)\r
- {\r
- anx7150_clear_avmute(client);\r
- }\r
- //enable audio SY.\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- c |= ANX7150_HDMI_AUDCTRL1_IN_EN;\r
- rc = anx7150_i2c_write_p0_reg(client, ANX7150_HDMI_AUDCTRL1_REG, &c);\r
- }\r
-\r
-//wen HDCP CTS\r
- rc = anx7150_i2c_read_p0_reg(client, ANX7150_SYS_CTRL1_REG, &c); //72:07.1 hdmi or dvi mode\r
- c = c & 0x02;\r
- if (c == 0x02)\r
- {\r
- hdmi_dbg(&client->dev, "end of ANX7150_HDCP_Process(): in HDMI mode.\n");\r
- }\r
- else\r
- {\r
- hdmi_dbg(&client->dev, "!end of ANX7150_HDCP_Process(): in DVI mode.\n");\r
- //To-Do: Config to DVI mode.\r
- }\r
-\r
- anx7150_show_video_parameter(client);\r
- if(!enable)\r
- anx7150_set_avmute(client);\r
-}\r
-\r
-void HDMI_Set_Video_Format(u8 video_format) //CPU set the lowpower mode\r
-{ \r
- switch (video_format)\r
- {\r
- case HDMI_1280x720p_50Hz:\r
- g_video_format = ANX7150_V1280x720p_50Hz;\r
- break;\r
- case HDMI_1280x720p_60Hz:\r
- g_video_format = ANX7150_V1280x720p_60Hz;\r
- break;\r
- case HDMI_720x576p_50Hz_4x3:\r
- g_video_format = ANX7150_V720x576p_50Hz_4x3;\r
- break;\r
- case HDMI_720x576p_50Hz_16x9:\r
- g_video_format = ANX7150_V720x576p_50Hz_16x9;\r
- break;\r
- case HDMI_720x480p_60Hz_4x3:\r
- g_video_format = ANX7150_V720x480p_60Hz_4x3;\r
- break;\r
- case HDMI_720x480p_60Hz_16x9:\r
- g_video_format = ANX7150_V720x480p_60Hz_16x9;\r
- break;\r
- case HDMI_1920x1080p_50Hz:\r
- g_video_format = ANX7150_V1920x1080p_50Hz;\r
- break;\r
- case HDMI_1920x1080p_60Hz:\r
- g_video_format = ANX7150_V1920x1080p_60Hz;\r
- break;\r
- default:\r
- g_video_format = ANX7150_V1280x720p_50Hz;\r
- break;\r
- }\r
-// ANX7150_system_config_done = 0;\r
-}\r
-void HDMI_Set_Audio_Fs( u8 audio_fs) //ANX7150 call this to check lowpower\r
-{\r
- g_audio_format = audio_fs;\r
-// ANX7150_system_config_done = 0;\r
-}\r
-int ANX7150_PLAYBACK_Process(void)\r
-{\r
-// D("enter\n");\r
-\r
- if ((s_ANX7150_packet_config.packets_need_config != 0x00) && (ANX7150_edid_result.is_HDMI == 1))\r
- {\r
- return 1;\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-\r
+++ /dev/null
-#ifndef _ANX7150_HW_H\r
-#define _ANX7150_HW_H\r
-\r
-#include <linux/hdmi.h>\r
-\r
-#define EDID_LENGTH 128\r
-struct est_timings {\r
- u8 t1;\r
- u8 t2;\r
- u8 mfg_rsvd;\r
-} __attribute__((packed));\r
-\r
-struct std_timing {\r
- u8 hsize; /* need to multiply by 8 then add 248 */\r
- u8 vfreq_aspect;\r
-} __attribute__((packed));\r
-\r
-/* If detailed data is pixel timing */\r
-struct detailed_pixel_timing {\r
- u8 hactive_lo;\r
- u8 hblank_lo;\r
- u8 hactive_hblank_hi;\r
- u8 vactive_lo;\r
- u8 vblank_lo;\r
- u8 vactive_vblank_hi;\r
- u8 hsync_offset_lo;\r
- u8 hsync_pulse_width_lo;\r
- u8 vsync_offset_pulse_width_lo;\r
- u8 hsync_vsync_offset_pulse_width_hi;\r
- u8 width_mm_lo;\r
- u8 height_mm_lo;\r
- u8 width_height_mm_hi;\r
- u8 hborder;\r
- u8 vborder;\r
- u8 misc;\r
-} __attribute__((packed));\r
-\r
-/* If it's not pixel timing, it'll be one of the below */\r
-struct detailed_data_string {\r
- u8 str[13];\r
-} __attribute__((packed));\r
-\r
-struct detailed_data_monitor_range {\r
- u8 min_vfreq;\r
- u8 max_vfreq;\r
- u8 min_hfreq_khz;\r
- u8 max_hfreq_khz;\r
- u8 pixel_clock_mhz; /* need to multiply by 10 */\r
- __le16 sec_gtf_toggle; /* A000=use above, 20=use below */\r
- u8 hfreq_start_khz; /* need to multiply by 2 */\r
- u8 c; /* need to divide by 2 */\r
- __le16 m;\r
- u8 k;\r
- u8 j; /* need to divide by 2 */\r
-} __attribute__((packed));\r
-\r
-struct detailed_data_wpindex {\r
- u8 white_yx_lo; /* Lower 2 bits each */\r
- u8 white_x_hi;\r
- u8 white_y_hi;\r
- u8 gamma; /* need to divide by 100 then add 1 */\r
-} __attribute__((packed));\r
-\r
-struct detailed_data_color_point {\r
- u8 windex1;\r
- u8 wpindex1[3];\r
- u8 windex2;\r
- u8 wpindex2[3];\r
-} __attribute__((packed));\r
-\r
-struct cvt_timing {\r
- u8 code[3];\r
-} __attribute__((packed));\r
-\r
-struct detailed_non_pixel {\r
- u8 pad1;\r
- u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name\r
- fb=color point data, fa=standard timing data,\r
- f9=undefined, f8=mfg. reserved */\r
- u8 pad2;\r
- union {\r
- struct detailed_data_string str;\r
- struct detailed_data_monitor_range range;\r
- struct detailed_data_wpindex color;\r
- struct std_timing timings[6];\r
- struct cvt_timing cvt[4];\r
- } data;\r
-} __attribute__((packed));\r
-\r
-struct detailed_timing {\r
- __le16 pixel_clock; /* need to multiply by 10 KHz */\r
- union {\r
- struct detailed_pixel_timing pixel_data;\r
- struct detailed_non_pixel other_data;\r
- } data;\r
-} __attribute__((packed));\r
-\r
-struct edid {\r
- u8 header[8];\r
- /* Vendor & product info */\r
- u8 mfg_id[2];\r
- u8 prod_code[2];\r
- u32 serial; /* FIXME: byte order */\r
- u8 mfg_week;\r
- u8 mfg_year;\r
- /* EDID version */\r
- u8 version;\r
- u8 revision;\r
- /* Display info: */\r
- u8 input;\r
- u8 width_cm;\r
- u8 height_cm;\r
- u8 gamma;\r
- u8 features;\r
- /* Color characteristics */\r
- u8 red_green_lo;\r
- u8 black_white_lo;\r
- u8 red_x;\r
- u8 red_y;\r
- u8 green_x;\r
- u8 green_y;\r
- u8 blue_x;\r
- u8 blue_y;\r
- u8 white_x;\r
- u8 white_y;\r
- /* Est. timings and mfg rsvd timings*/\r
- struct est_timings established_timings;\r
- /* Standard timings 1-8*/\r
- struct std_timing standard_timings[8];\r
- /* Detailing timings 1-4 */\r
- struct detailed_timing detailed_timings[4];\r
- /* Number of 128 byte ext. blocks */\r
- u8 extensions;\r
- /* Checksum */\r
- u8 checksum;\r
-} __attribute__((packed));\r
-\r
-extern u8 timer_slot,misc_reset_needed;\r
-extern u8 bist_switch_value_pc,switch_value;\r
-extern u8 switch_value_sw_backup,switch_value_pc_backup;\r
-extern u8 ANX7150_system_state;\r
-extern u8 ANX7150_srm_checked;\r
-extern u8 ANX7150_HDCP_enable;\r
-extern u8 ANX7150_INT_Done;\r
-extern u8 FREQ_MCLK;\r
-//extern u8 int_s1, int_s2, int_s3;\r
-extern u8 HDMI_Mode_Auto_Manual,HDMI_Lowpower_Mode;\r
-\r
-struct anx7150_interrupt_s{\r
- int hotplug_change;\r
- int video_format_change;\r
- int auth_done;\r
- int auth_state_change;\r
- int pll_lock_change;\r
- int rx_sense_change;\r
- int HDCP_link_change;\r
- int audio_clk_change;\r
- int audio_FIFO_overrun;\r
- int SPDIF_bi_phase_error;\r
- int SPDIF_error;\r
-};\r
-typedef struct\r
-{\r
- u8 is_HDMI;\r
- u8 ycbcr444_supported;\r
- u8 ycbcr422_supported;\r
- u8 supported_1080p_60Hz;\r
- u8 supported_1080p_50Hz;\r
- u8 supported_1080i_60Hz;\r
- u8 supported_1080i_50Hz;\r
- u8 supported_720p_60Hz;\r
- u8 supported_720p_50Hz;\r
- u8 supported_576p_50Hz;\r
- u8 supported_576i_50Hz;\r
- u8 supported_640x480p_60Hz;\r
- u8 supported_720x480p_60Hz;\r
- u8 supported_720x480i_60Hz;\r
- u8 AudioFormat[10];//MAX audio STD block is 10(0x1f / 3)\r
- u8 AudioChannel[10];\r
- u8 AudioFs[10];\r
- u8 AudioLength[10];\r
- u8 SpeakerFormat;u8 edid_errcode;}ANX7150_edid_result_4_system;\r
- extern ANX7150_edid_result_4_system ANX7150_edid_result;\r
-//#define ITU656\r
-//#ifdef ITU656\r
-struct ANX7150_video_timingtype{ //CEA-861C format\r
- u8 ANX7150_640x480p_60Hz[18];//format 1\r
- u8 ANX7150_720x480p_60Hz[18];//format 2 & 3\r
- u8 ANX7150_1280x720p_60Hz[18];//format 4\r
- u8 ANX7150_1920x1080i_60Hz[18];//format 5\r
- u8 ANX7150_720x480i_60Hz[18];//format 6 & 7\r
- u8 ANX7150_1920x1080p_60Hz[18];\r
- //u8 ANX7150_720x240p_60Hz[18];//format 8 & 9\r
- //u8 ANX7150_2880x480i_60Hz[18];//format 10 & 11\r
- //u8 ANX7150_2880x240p_60Hz[18];//format 12 & 13\r
- //u8 ANX7150_1440x480p_60Hz[18];//format 14 & 15\r
- //u8 ANX7150_1920x1080p_60Hz[18];//format 16\r
- u8 ANX7150_720x576p_50Hz[18];//format 17 & 18\r
- u8 ANX7150_1280x720p_50Hz[18];//format 19\r
- u8 ANX7150_1920x1080i_50Hz[18];//format 20*/\r
- u8 ANX7150_720x576i_50Hz[18];//format 21 & 22\r
- u8 ANX7150_1920x1080p_50Hz[18];\r
- /* u8 ANX7150_720x288p_50Hz[18];//formats 23 & 24\r
- u8 ANX7150_2880x576i_50Hz[18];//formats 25 & 26\r
- u8 ANX7150_2880x288p_50Hz[18];//formats 27 & 28\r
- u8 ANX7150_1440x576p_50Hz[18];//formats 29 & 30\r
- u8 ANX7150_1920x1080p_50Hz[18];//format 31\r
- u8 ANX7150_1920x1080p_24Hz[18];//format 32\r
- u8 ANX7150_1920x1080p_25Hz[18];//format 33\r
- u8 ANX7150_1920x1080p_30Hz[18];//format 34*/\r
-};\r
-//#endif\r
-// 8 type of packets are legal, It is possible to sent 6 types in the same time;\r
-// So select 6 types below at most;\r
-// avi_infoframe and audio_infoframe have fixxed address;\r
-// config other selected types of packet to the rest 4 address with no limits.\r
-typedef enum\r
-{\r
- ANX7150_avi_infoframe,\r
- ANX7150_audio_infoframe,\r
- /*ANX7150_spd_infoframe,\r
- ANX7150_mpeg_infoframe,\r
- ANX7150_acp_packet,\r
- ANX7150_isrc1_packet,\r
- ANX7150_isrc2_packet,\r
- ANX7150_vendor_infoframe,*/\r
-}packet_type;\r
-\r
-typedef struct\r
-{\r
- u8 type;\r
- u8 version;\r
- u8 length;\r
- u8 pb_u8[28];\r
-}infoframe_struct;\r
-\r
-typedef struct\r
-{\r
- u8 packets_need_config; //which infoframe packet is need updated\r
- infoframe_struct avi_info;\r
- infoframe_struct audio_info;\r
- /* for the funture use\r
- infoframe_struct spd_info;\r
- infoframe_struct mpeg_info;\r
- infoframe_struct acp_pkt;\r
- infoframe_struct isrc1_pkt;\r
- infoframe_struct isrc2_pkt;\r
- infoframe_struct vendor_info; */\r
-\r
-} config_packets;\r
-/*\r
- u8 i2s_format;\r
-\r
- u8(s) Name Type Default Description\r
- 7 EXT_VUCP R/W 0x0\r
- Enable indicator of VUCP u8s extraction from input\r
- I2S audio stream. 0 = disable; 1 = enable.\r
- 6:5 MCLK_PHS_CTRL R/W 0x0\r
- MCLK phase control for audio SPDIF input, which value\r
- is depended on the value of MCLK frequency set and not great than it.\r
- 4 Reserved\r
- 3 SHIFT_CTRL R/W 0x0\r
- WS to SD shift first u8. 0 = fist u8 shift (Philips Spec); 1 = no shift.\r
- 2 DIR_CTRL R/W 0x0\r
- SD data Indian (MSB or LSB first) control. 0 = MSB first; 1 = LSB first.\r
- 1 WS_POL R/W 0x0\r
- Word select left/right polarity select. 0 = left polarity\r
- when works select is low; 1 = left polarity when word select is high.\r
- 0 JUST_CTRL R/W 0x0\r
- SD Justification control. 1 = data is right justified;\r
- 0 = data is left justified.\r
-\r
-*/\r
-/*\r
- u8 audio_channel\r
-u8(s) Name Type Default Description\r
-5 AUD_SD3_IN R/W 0x0 Set I2S input channel #3 enable. 0 = disable; 1 = enable.\r
-4 AUD_SD2_IN R/W 0x0 Set I2S input channel #2 enable. 0 = disable; 1 = enable.\r
-3 AUD_SD1_IN R/W 0x0 Set I2S input channel #1 enable. 0 = disable; 1 = enable.\r
-2 AUD_SD0_IN R/W 0x0 Set I2S input channel #0 enable. 0 = disable; 1 = enable.\r
-\r
-\r
-*/\r
-/*\r
- u8 i2s_map0\r
-u8(s) Name Type Default Description\r
-7:6 FIFO3_SEL R/W 0x3 I2S Channel data stream select for audio FIFO 3. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
-5:4 FIFO2_SEL R/W 0x2 I2S Channel data stream select for audio FIFO 2. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
-3:2 FIFO1_SEL R/W 0x1 I2S Channel data stream select for audio FIFO 1. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
-1:0 FIFO0_SEL R/W 0x0 I2S Channel data stream select for audio FIFO 0. 0 = SD 0; 1 = SD 1; 2 = SD 2; 3 = SD 3;\r
-\r
- u8 i2s_map1\r
-u8(s) Name Type Default Description\r
-7 SW3 R/W 0x0 Swap left/right channel on I2S channel 3. 1 = swap; 0 = no swap.\r
-6 SW2 R/W 0x0 Swap left/right channel on I2S channel 2. 1 = swap; 0 = no swap.\r
-5 SW1 R/W 0x0 Swap left/right channel on I2S channel 1. 1 = swap; 0 = no swap.\r
-4 SW0 R/W 0x0 Swap left/right channel on I2S channel 0. 1 = swap; 0 = no swap.\r
-3:1 IN_WORD_LEN R/W 0x5 Input I2S audio word length (corresponding to channel status u8s [35:33]). When IN_WORD_MAX = 0, 001 = 16 u8s; 010 = 18 u8s; 100 = 19 u8s; 101 = 20 u8s; 110 = 17 u8s; when IN_WORD_MAX = 1, 001 = 20 u8s; 010 = 22 u8s; 100 = 23 u8s; 101 = 24 u8s; 110 = 21 u8s.\r
-0 IN_WORD_MAX R/W 0x1 Input I2S audio word length Max (corresponding to channel status u8s 32). 0 = maximal word length is 20 u8s; 1 = maximal word length is 24 u8s.\r
-*/\r
-/*\r
- u8 Channel_status1\r
-u8(s) Name Type Default Description\r
-7:6 MODE R/W 0x0 00 = PCM Audio\r
-5:3 PCM_MODE R/W 0x0 000 = 2 audio channels without pre-emphasis;\r
- 001 = 2 audio channels with 50/15 usec pre-emphasis\r
-2 SW_CPRGT R/W 0x0 0 = software for which copyright is asserted;\r
- 1 = software for which no copyright is asserted\r
-1 NON_PCM R/W 0x0 0 = audio sample word represents linear PCM samples;\r
- 1 = audio sample word used for other purposes.\r
-0 PROF_APP R/W 0x0 0 = consumer applications; 1 = professional applications.\r
-\r
- u8 Channel_status2\r
-u8(s) Name Type Default Description\r
-7:0 CAT_CODE R/W 0x0 Category code (corresponding to channel status u8s [15:8])\r
-\r
- u8 Channel_status3\r
-u8(s) Name Type Default Description\r
-7:4 CH_NUM R/W 0x0 Channel number (corresponding to channel status u8s [23:20])\r
-3:0 SOURCE_NUM R/W 0x0 Source number (corresponding to channel status u8s [19:16])\r
-\r
- u8 Channel_status4\r
-u8(s) Name Type Default Description\r
-7:6 CHNL_u81 R/W 0x0 corresponding to channels status u8s [31:30]\r
-5:4 CLK_ACCUR R/W 0x0 Clock accuracy (corresponding to channels status u8s [29:28]). These two u8s define the sampling frequency tolerance. The u8s are set in the transmitter.\r
-3:0 FS_FREQ R/W 0x0 Sampling clock frequency (corresponding to channel status u8s [27:24]). 0000 = 44.1 KHz; 0010 = 48 KHz; 0011 = 32 KHz; 1000 = 88.2 KHz; 1010 = 96 KHz; 176.4 KHz; 1110 = 192 KHz; others = reserved.\r
-\r
- u8 Channel_status5\r
-u8(s) Name Type Default Description\r
-7:4 CHNL_u82 R/W 0x0 corresponding to channels status u8s [39:36]\r
-3:1 WORD_LENGTH R/W 0x5 Audio word length (corresponding to channel status u8s [35:33]). When WORD_MAX = 0, 001 = 16 u8s; 010 = 18 u8s; 100 = 19 u8s; 101 = 20 u8s; 110 = 17 u8s; when WORD_MAX = 1, 001 = 20 u8s; 010 = 22 u8s; 100 = 23 u8s; 101 = 24 u8s; 110 = 21 u8s.\r
-0 WORD_MAX R/W 0x1 Audio word length Max (corresponding to channel status u8s 32). 0 = maximal word length is 20 u8s; 1 = maximal word length is 24 u8s.\r
-\r
-*/\r
-typedef struct\r
-{\r
- u8 audio_channel;\r
- u8 i2s_format;\r
- u8 i2s_swap;\r
- u8 Channel_status1;\r
- u8 Channel_status2;\r
- u8 Channel_status3;\r
- u8 Channel_status4;\r
- u8 Channel_status5;\r
-} i2s_config_struct;\r
-/*\r
- u8 FS_FREQ;\r
-\r
- 7:4 FS_FREQ R 0x0\r
- Sampling clock frequency (corresponding to channel status u8s [27:24]).\r
- 0000 = 44.1 KHz; 0010 = 48 KHz; 0011 = 32 KHz; 1000 = 88.2 KHz; 1010 = 96 KHz;\r
- 176.4 KHz; 1110 = 192 KHz; others = reserved.\r
-*/\r
-\r
-typedef struct\r
-{\r
- u8 one_u8_ctrl;\r
-\r
-} super_audio_config_struct;\r
-\r
-typedef struct\r
-{\r
- u8 audio_type; // audio type\r
- // #define ANX7150_i2s_input 0x01\r
- // #define ANX7150_spdif_input 0x02\r
- // #define ANX7150_super_audio_input 0x04\r
-\r
- u8 down_sample; // 0x72:0x50\r
- // 0x00: 00 no down sample\r
- // 0x20: 01 2 to 1 down sample\r
- // 0x60: 11 4 to 1 down sample\r
- // 0x40: 10 reserved\r
- u8 audio_layout;//audio layout;\r
- //0x00, 2-channel\r
- //0x80, 8-channel\r
-\r
- i2s_config_struct i2s_config;\r
- super_audio_config_struct super_audio_config;\r
-\r
-} audio_config_struct;\r
-\r
-/*added by gerard.zhu*/\r
-/*DDC type*/\r
-typedef enum {\r
- DDC_Hdcp,\r
- DDC_Edid,\r
-}ANX7150_DDC_Type;\r
-\r
-/*Read DDC status type*/\r
-typedef enum {\r
- report,\r
- Judge,\r
-}ANX7150_DDC_Status_Check_Type;\r
-\r
-/*Define DDC address struction*/\r
-typedef struct {\r
- u8 dev_addr;\r
- u8 sgmt_addr;\r
- u8 offset_addr;\r
-}ANX7150_DDC_Addr;\r
-\r
-/*DDC status u8*/\r
-#define DDC_Error_u8 0x07\r
-#define DDC_Occup_u8 0x06\r
-#define DDC_Fifo_Full_u8 0x05\r
-#define DDC_Fifo_Empt_u8 0x04\r
-#define DDC_No_Ack_u8 0x03\r
-#define DDC_Fifo_Rd_u8 0x02\r
-#define DDC_Fifo_Wr_u8 0x01\r
-#define DDC_Progress_u8 0x00\r
-\r
-#define YCbCr422 0x20\r
-#define null 0\r
-#define source_ratio 0x08\r
-\r
-/*DDC Command*/\r
-#define Abort_Current_Operation 0x00\r
-#define Sequential_u8_Read 0x01\r
-#define Sequential_u8_Write 0x02\r
-#define Implicit_Offset_Address_Read 0x3\r
-#define Enhanced_DDC_Sequenital_Read 0x04\r
-#define Clear_DDC_Fifo 0x05\r
-#define I2c_reset 0x06\r
-\r
-/*DDC result*/\r
-#define DDC_NO_Err 0x00\r
-#define DDC_Status_Err 0x01\r
-#define DDC_Data_Addr_Err 0x02\r
-#define DDC_Length_Err 0x03\r
-\r
-/*checksum result*/\r
-#define Edid_Checksum_No_Err 0x00\r
-#define Edid_Checksum_Err 0x01\r
-\r
-/*HDCP device base address*/\r
-#define HDCP_Dev_Addr 0x74\r
-\r
-/*HDCP Bksv offset*/\r
-#define HDCP_Bksv_Offset 0x00\r
-\r
-/*HDCP Bcaps offset*/\r
-#define HDCP_Bcaps_Offset 0x40\r
-\r
-/*HDCP Bstatus offset*/\r
-#define HDCP_Bstatus_offset 0x41\r
-\r
-/*HDCP KSV Fifo offset */\r
-#define HDCP_Ksv_Fifo_Offset 0x43\r
-\r
-/*HDCP bksv data nums*/\r
-#define Bksv_Data_Nums 5\r
-\r
-/*HDCP ksvs data number by defult*/\r
-#define ksvs_data_nums 50\r
-\r
-/*DDC Max u8s*/\r
-#define DDC_Max_Length 1024\r
-\r
-/*DDC fifo depth*/\r
-#define DDC_Fifo_Depth 16\r
-\r
-/*DDC read delay ms*/\r
-#define DDC_Read_Delay 3\r
-\r
-/*DDC Write delay ms*/\r
-#define DDC_Write_Delay 3\r
-/*end*/\r
-\r
-extern u8 ANX7150_parse_edid_done;\r
-extern u8 ANX7150_system_config_done;\r
-extern u8 ANX7150_video_format_config,ANX7150_video_timing_id;\r
-extern u8 ANX7150_new_csc,ANX7150_new_vid_id,ANX7150_new_HW_interface;\r
-extern u8 ANX7150_ddr_edge;\r
-extern u8 ANX7150_in_pix_rpt_bkp,ANX7150_tx_pix_rpt_bkp;\r
-extern u8 ANX7150_in_pix_rpt,ANX7150_tx_pix_rpt;\r
-extern u8 ANX7150_pix_rpt_set_by_sys;\r
-extern u8 ANX7150_RGBorYCbCr;\r
-extern audio_config_struct s_ANX7150_audio_config;\r
-extern config_packets s_ANX7150_packet_config;\r
-\r
-//********************** BIST Enable***********************************\r
-\r
-\r
-#define ddr_falling_edge 1\r
-#define ddr_rising_edge 0\r
-\r
-#define input_pixel_clk_1x_repeatition 0x00\r
-#define input_pixel_clk_2x_repeatition 0x01\r
-#define input_pixel_clk_4x_repeatition 0x03\r
-\r
-//***********************Video Config***********************************\r
-#define ANX7150_RGB_YCrCb444_SepSync 0\r
-#define ANX7150_YCrCb422_SepSync 1\r
-#define ANX7150_YCrCb422_EmbSync 2\r
-#define ANX7150_YCMux422_SepSync_Mode1 3\r
-#define ANX7150_YCMux422_SepSync_Mode2 4\r
-#define ANX7150_YCMux422_EmbSync_Mode1 5\r
-#define ANX7150_YCMux422_EmbSync_Mode2 6\r
-#define ANX7150_RGB_YCrCb444_DDR_SepSync 7\r
-#define ANX7150_RGB_YCrCb444_DDR_EmbSync 8\r
-\r
-#define ANX7150_RGB_YCrCb444_SepSync_No_DE 9\r
-#define ANX7150_YCrCb422_SepSync_No_DE 10\r
-\r
-#define ANX7150_Progressive 0\r
-#define ANX7150_Interlace 0x08\r
-#define ANX7150_Neg_Hsync_pol 0x20\r
-#define ANX7150_Pos_Hsync_pol 0\r
-#define ANX7150_Neg_Vsync_pol 0x40\r
-#define ANX7150_Pos_Vsync_pol 0\r
-\r
-#define ANX7150_V640x480p_60Hz 1\r
-#define ANX7150_V720x480p_60Hz_4x3 2\r
-#define ANX7150_V720x480p_60Hz_16x9 3\r
-#define ANX7150_V1280x720p_60Hz 4\r
-#define ANX7150_V1280x720p_50Hz 19\r
-#define ANX7150_V1920x1080i_60Hz 5\r
-#define ANX7150_V1920x1080p_60Hz 16\r
-#define ANX7150_V1920x1080p_50Hz 31\r
-#define ANX7150_V1920x1080i_50Hz 20\r
-#define ANX7150_V720x480i_60Hz_4x3 6\r
-#define ANX7150_V720x480i_60Hz_16x9 7\r
-#define ANX7150_V720x576i_50Hz_4x3 21\r
-#define ANX7150_V720x576i_50Hz_16x9 22\r
-#define ANX7150_V720x576p_50Hz_4x3 17\r
-#define ANX7150_V720x576p_50Hz_16x9 18\r
-\r
-#define ANX7150_RGB 0x00\r
-#define ANX7150_YCbCr422 0x01\r
-#define ANX7150_YCbCr444 0x02\r
-#define ANX7150_CSC_BT709 1\r
-#define ANX7150_CSC_BT601 0\r
-\r
-#define ANX7150_EMBEDED_BLUE_SCREEN_ENABLE 1\r
-#define ANX7150_HDCP_FAIL_THRESHOLD 10\r
-\r
-#define ANX7150_avi_sel 0x01\r
-#define ANX7150_audio_sel 0x02\r
-#define ANX7150_spd_sel 0x04\r
-#define ANX7150_mpeg_sel 0x08\r
-#define ANX7150_acp_sel 0x10\r
-#define ANX7150_isrc1_sel 0x20\r
-#define ANX7150_isrc2_sel 0x40\r
-#define ANX7150_vendor_sel 0x80\r
-\r
-// audio type\r
-#define ANX7150_i2s_input 0x01\r
-#define ANX7150_spdif_input 0x02\r
-#define ANX7150_super_audio_input 0x04\r
-// freq_mclk\r
-#define ANX7150_mclk_128_Fs 0x00\r
-#define ANX7150_mclk_256_Fs 0x01\r
-#define ANX7150_mclk_384_Fs 0x02\r
-#define ANX7150_mclk_512_Fs 0x03\r
-// thresholds\r
-#define ANX7150_spdif_stable_th 0x03\r
-// fs -> N(ACR)\r
-#define ANX7150_N_32k 0x1000\r
-#define ANX7150_N_44k 0x1880\r
-#define ANX7150_N_88k 0x3100\r
-#define ANX7150_N_176k 0x6200\r
-#define ANX7150_N_48k 0x1800\r
-#define ANX7150_N_96k 0x3000\r
-#define ANX7150_N_192k 0x6000\r
-\r
-#define spdif_error_th 0x0a\r
-\r
-#define Hresolution_1920 1920\r
-#define Vresolution_540 540\r
-#define Vresolution_1080 1080\r
-#define Hresolution_1280 1280\r
-#define Vresolution_720 720\r
-#define Hresolution_640 640\r
-#define Vresolution_480 480\r
-#define Hresolution_720 720\r
-#define Vresolution_240 240\r
-#define Vresolution_576 576\r
-#define Vresolution_288 288\r
-#define Hz_50 50\r
-#define Hz_60 60\r
-#define Interlace_EDID 0\r
-#define Progressive_EDID 1\r
-#define ratio_16_9 1.777778\r
-#define ratio_4_3 1.333333\r
-\r
-#define ANX7150_EDID_BadHeader 0x01\r
-#define ANX7150_EDID_861B_not_supported 0x02\r
-#define ANX7150_EDID_CheckSum_ERR 0x03\r
-#define ANX7150_EDID_No_ExtBlock 0x04\r
-#define ANX7150_EDID_ExtBlock_NotFor_861B 0x05\r
-\r
-#define ANX7150_VND_IDL_REG 0x00\r
-#define ANX7150_VND_IDH_REG 0x01\r
-#define ANX7150_DEV_IDL_REG 0x02\r
-#define ANX7150_DEV_IDH_REG 0x03\r
-#define ANX7150_DEV_REV_REG 0x04\r
-\r
-#define ANX7150_SRST_REG 0x05\r
-#define ANX7150_TX_RST 0x40\r
-#define ANX7150_SRST_VIDCAP_RST 0x20 // u8 position\r
-#define ANX7150_SRST_AFIFO_RST 0x10 // u8 position\r
-#define ANX7150_SRST_HDCP_RST 0x08 // u8 position\r
-#define ANX7150_SRST_VID_FIFO_RST 0x04 // u8 position\r
-#define ANX7150_SRST_AUD_RST 0x02 // u8 position\r
-#define ANX7150_SRST_SW_RST 0x01 // u8 position\r
-\r
-#define ANX7150_SYS_STATE_REG 0x06\r
-#define ANX7150_SYS_STATE_AUD_CLK_DET 0x20 // u8 position\r
-#define ANX7150_SYS_STATE_AVMUTE 0x10 // u8 position\r
-#define ANX7150_SYS_STATE_HP 0x08 // u8 position\r
-#define ANX7150_SYS_STATE_VSYNC 0x04 // u8 position\r
-#define ANX7150_SYS_STATE_CLK_DET 0x02 // u8 position\r
-#define ANX7150_SYS_STATE_RSV_DET 0x01 // u8 position\r
-\r
-#define ANX7150_SYS_CTRL1_REG 0x07\r
-#define ANX7150_SYS_CTRL1_LINKMUTE_EN 0x80 // u8 position\r
-#define ANX7150_SYS_CTRL1_HDCPHPD_RST 0x40 // u8 position\r
-#define ANX7150_SYS_CTRL1_PDINT_SEL 0x20 // u8 position\r
-#define ANX7150_SYS_CTRL1_DDC_FAST 0x10 // u8 position\r
-#define ANX7150_SYS_CTRL1_DDC_SWCTRL 0x08 // u8 position\r
-#define ANX7150_SYS_CTRL1_HDCPMODE 0x04 // u8 position\r
-#define ANX7150_SYS_CTRL1_HDMI 0x02 // u8 position\r
-#define ANX7150_SYS_CTRL1_PWDN_CTRL 0x01 // u8 position\r
-\r
-#define ANX7150_SYS_CTRL2_REG 0x08\r
-#define ANX7150_SYS_CTRL2_DDC_RST 0x08 // u8 position\r
-#define ANX7150_SYS_CTRL2_TMDSBIST_RST 0x04 // u8 position\r
-#define ANX7150_SYS_CTRL2_MISC_RST 0x02 // u8 position\r
-#define ANX7150_SYS_CTRL2_HW_RST 0x01 // u8 position\r
-\r
-#define ANX7150_SYS_CTRL3_REG 0x09\r
-#define ANX7150_SYS_CTRL3_I2C_PWON 0x02\r
-#define ANX7150_SYS_CTRL3_PWON_ALL 0x01\r
-\r
-#define ANX7150_SYS_CTRL4_REG 0x0b\r
-\r
-#define ANX7150_VID_STATUS_REG 0x10\r
-#define ANX7150_VID_STATUS_VID_STABLE 0x20 // u8 position\r
-#define ANX7150_VID_STATUS_EMSYNC_ERR 0x10 // u8 position\r
-#define ANX7150_VID_STATUS_FLD_POL 0x08 // u8 position\r
-#define ANX7150_VID_STATUS_TYPE 0x04 // u8 position\r
-#define ANX7150_VID_STATUS_VSYNC_POL 0x02 // u8 position\r
-#define ANX7150_VID_STATUS_HSYNC_POL 0x01 // u8 position\r
-\r
-#define ANX7150_VID_MODE_REG 0x11\r
-#define ANX7150_VID_MODE_CHKSHARED_EN 0x80 // u8 position\r
-#define ANX7150_VID_MODE_LINKVID_EN 0x40 // u8 position\r
-#define ANX7150_VID_MODE_RANGE_Y2R 0x20 // u8 position\r
-#define ANX7150_VID_MODE_CSPACE_Y2R 0x10 // u8 position\r
-#define ANX7150_VID_MODE_Y2R_SEL 0x08 // u8 position\r
-#define ANX7150_VID_MODE_UPSAMPLE 0x04 // u8 position\r
-\r
-#define ANX7150_VID_CTRL_REG 0x12\r
-#define ANX7150_VID_CTRL_IN_EN 0x10 // u8 position\r
-#define ANX7150_VID_CTRL_YCu8_SEL 0x08 // u8 position\r
-#define ANX7150_VID_CTRL_u8CTRL_EN 0x04 // u8 position\r
-\r
-#define ANX7150_VID_CAPCTRL0_REG 0x13\r
-#define ANX7150_VID_CAPCTRL0_DEGEN_EN 0x80 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_EMSYNC_EN 0x40 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_DEMUX_EN 0x20 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_INV_IDCK 0x10 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_DV_BUSMODE 0x08 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_DDR_EDGE 0x04 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_VIDu8_SWAP 0x02 // u8 position\r
-#define ANX7150_VID_CAPCTRL0_VIDBIST_EN 0x01 // u8 position\r
-\r
-#define ANX7150_VID_CAPCTRL1_REG 0x14\r
-#define ANX7150_VID_CAPCTRL1_FORMAT_SEL 0x80 // u8 position\r
-#define ANX7150_VID_CAPCTRL1_VSYNC_POL 0x40 // u8 position\r
-#define ANX7150_VID_CAPCTRL1_HSYNC_POL 0x20 // u8 position\r
-#define ANX7150_VID_CAPCTRL1_INV_FLDPOL 0x10 // u8 position\r
-#define ANX7150_VID_CAPCTRL1_VID_TYPE 0x08 // u8 position\r
-\r
-#define ANX7150_H_RESL_REG 0x15\r
-#define ANX7150_H_RESH_REG 0x16\r
-#define ANX7150_VID_PIXL_REG 0x17\r
-#define ANX7150_VID_PIXH_REG 0x18\r
-#define ANX7150_H_FRONTPORCHL_REG 0x19\r
-#define ANX7150_H_FRONTPORCHH_REG 0x1A\r
-#define ANX7150_HSYNC_ACT_WIDTHL_REG 0x1B\r
-#define ANX7150_HSYNC_ACT_WIDTHH_REG 0x1C\r
-#define ANX7150_H_BACKPORCHL_REG 0x1D\r
-#define ANX7150_H_BACKPORCHH_REG 0x1E\r
-#define ANX7150_V_RESL_REG 0x1F\r
-#define ANX7150_V_RESH_REG 0x20\r
-#define ANX7150_ACT_LINEL_REG 0x21\r
-#define ANX7150_ACT_LINEH_REG 0x22\r
-#define ANX7150_ACT_LINE2VSYNC_REG 0x23\r
-#define ANX7150_VSYNC_WID_REG 0x24\r
-#define ANX7150_VSYNC_TAIL2VIDLINE_REG 0x25\r
-#define ANX7150_VIDF_HRESL_REG 0x26\r
-#define ANX7150_VIDF_HRESH_REG 0x27\r
-#define ANX7150_VIDF_PIXL_REG 0x28\r
-#define ANX7150_VIDF_PIXH_REG 0x29\r
-#define ANX7150_VIDF_HFORNTPORCHL_REG 0x2A\r
-#define ANX7150_VIDF_HFORNTPORCHH_REG 0x2B\r
-#define ANX7150_VIDF_HSYNCWIDL_REG 0x2C\r
-#define ANX7150_VIDF_HSYNCWIDH_REG 0x2D\r
-#define ANX7150_VIDF_HBACKPORCHL_REG 0x2E\r
-#define ANX7150_VIDF_HBACKPORCHH_REG 0x2F\r
-#define ANX7150_VIDF_VRESL_REG 0x30\r
-#define ANX7150_VIDF_VRESH_REG 0x31\r
-#define ANX7150_VIDF_ACTVIDLINEL_REG 0x32\r
-#define ANX7150_VIDF_ACTVIDLINEH_REG 0x33\r
-#define ANX7150_VIDF_ACTLINE2VSYNC_REG 0x34\r
-#define ANX7150_VIDF_VSYNCWIDLINE_REG 0x35\r
-#define ANX7150_VIDF_VSYNCTAIL2VIDLINE_REG 0x36\r
-\r
-//Video input data u8 control registers\r
-\r
-#define VID_u8_CTRL0 0x37 //added\r
-#define VID_u8_CTRL1 0x38\r
-#define VID_u8_CTRL2 0x39\r
-#define VID_u8_CTRL3 0x3A\r
-#define VID_u8_CTRL4 0x3B\r
-#define VID_u8_CTRL5 0x3C\r
-#define VID_u8_CTRL6 0x3D\r
-#define VID_u8_CTRL7 0x3E\r
-#define VID_u8_CTRL8 0x3F\r
-#define VID_u8_CTRL9 0x48\r
-#define VID_u8_CTRL10 0x49\r
-#define VID_u8_CTRL11 0x4A\r
-#define VID_u8_CTRL12 0x4B\r
-#define VID_u8_CTRL13 0x4C\r
-#define VID_u8_CTRL14 0x4D\r
-#define VID_u8_CTRL15 0x4E\r
-#define VID_u8_CTRL16 0x4F\r
-#define VID_u8_CTRL17 0x89\r
-#define VID_u8_CTRL18 0x8A\r
-#define VID_u8_CTRL19 0x8B\r
-#define VID_u8_CTRL20 0x8C\r
-#define VID_u8_CTRL21 0x8D\r
-#define VID_u8_CTRL22 0x8E\r
-#define VID_u8_CTRL23 0x8F\r
-\r
-\r
-#define ANX7150_INTR_STATE_REG 0x40\r
-\r
-#define ANX7150_INTR_CTRL_REG 0x41\r
-\r
-#define ANX7150_INTR_CTRL_SOFT_INTR 0x04 // u8 position\r
-#define ANX7150_INTR_CTRL_TYPE 0x02 // u8 position\r
-#define ANX7150_INTR_CTRL_POL 0x01 // u8 position\r
-\r
-#define ANX7150_INTR1_STATUS_REG 0x42\r
-#define ANX7150_INTR1_STATUS_CTS_CHG 0x80 // u8 position\r
-#define ANX7150_INTR1_STATUS_AFIFO_UNDER 0x40 // u8 position\r
-#define ANX7150_INTR1_STATUS_AFIFO_OVER 0x20 // u8 position\r
-#define ANX7150_INTR1_STATUS_SPDIF_ERR 0x10 // u8 position\r
-#define ANX7150_INTR1_STATUS_SW_INT 0x08 // u8 position\r
-#define ANX7150_INTR1_STATUS_HP_CHG 0x04 // u8 position\r
-#define ANX7150_INTR1_STATUS_CTS_OVRWR 0x02 // u8 position\r
-#define ANX7150_INTR1_STATUS_CLK_CHG 0x01 // u8 position\r
-\r
-#define ANX7150_INTR2_STATUS_REG 0x43\r
-#define ANX7150_INTR2_STATUS_ENCEN_CHG 0x80 // u8 position\r
-#define ANX7150_INTR2_STATUS_HDCPLINK_CHK 0x40 // u8 position\r
-#define ANX7150_INTR2_STATUS_HDCPENHC_CHK 0x20 // u8 position\r
-#define ANX7150_INTR2_STATUS_BKSV_RDY 0x10 // u8 position\r
-#define ANX7150_INTR2_STATUS_PLLLOCK_CHG 0x08 // u8 position\r
-#define ANX7150_INTR2_STATUS_SHA_DONE 0x04 // u8 position\r
-#define ANX7150_INTR2_STATUS_AUTH_CHG 0x02 // u8 position\r
-#define ANX7150_INTR2_STATUS_AUTH_DONE 0x01 // u8 position\r
-\r
-#define ANX7150_INTR3_STATUS_REG 0x44\r
-#define ANX7150_INTR3_STATUS_SPDIFBI_ERR 0x80 // u8 position\r
-#define ANX7150_INTR3_STATUS_VIDF_CHG 0x40 // u8 position\r
-#define ANX7150_INTR3_STATUS_AUDCLK_CHG 0x20 // u8 position\r
-#define ANX7150_INTR3_STATUS_DDCACC_ERR 0x10 // u8 position\r
-#define ANX7150_INTR3_STATUS_DDC_NOACK 0x08 // u8 position\r
-#define ANX7150_INTR3_STATUS_VSYNC_DET 0x04 // u8 position\r
-#define ANX7150_INTR3_STATUS_RXSEN_CHG 0x02 // u8 position\r
-#define ANX7150_INTR3_STATUS_SPDIF_UNSTBL 0x01 // u8 position\r
-\r
-#define ANX7150_INTR1_MASK_REG 0x45\r
-#define ANX7150_INTR2_MASK_REG 0x46\r
-#define ANX7150_INTR3_MASK_REG 0x47\r
-\r
-#define ANX7150_HDMI_AUDCTRL0_REG 0x50\r
-#define ANX7150_HDMI_AUDCTRL0_LAYOUT 0x80 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL0_DOWN_SMPL 0x60 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL0_CTSGEN_SC 0x10 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL0_INV_AUDCLK 0x08 // u8 position\r
-\r
-#define ANX7150_HDMI_AUDCTRL1_REG 0x51\r
-#define ANX7150_HDMI_AUDCTRL1_IN_EN 0x80 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SPDIFIN_EN 0x40 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SD3IN_EN 0x20 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SD2IN_EN 0x10 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SD1IN_EN 0x08 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SD0IN_EN 0x04 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_SPDIFFS_OVRWR 0x02 // u8 position\r
-#define ANX7150_HDMI_AUDCTRL1_CLK_SEL 0x01 // u8 position\r
-\r
-#define ANX7150_I2S_CTRL_REG 0x52\r
-#define ANX7150_I2S_CTRL_VUCP 0x80 // u8 position\r
-#define SPDIF_IN_SEL 0x10 //0-spdif, 1-multi with sd0\r
-#define ANX7150_I2S_CTRL_SHIFT_CTRL 0x08 // u8 position\r
-#define ANX7150_I2S_CTRL_DIR_CTRL 0x04 // u8 position\r
-#define ANX7150_I2S_CTRL_WS_POL 0x02 // u8 position\r
-#define ANX7150_I2S_CTRL_JUST_CTRL 0x01 // u8 position\r
-\r
-#define ANX7150_I2SCH_CTRL_REG 0x53\r
-#define ANX7150_I2SCH_FIFO3_SEL 0xC0 // u8 position\r
-#define ANX7150_I2SCH_FIFO2_SEL 0x30 // u8 position\r
-#define ANX7150_I2SCH_FIFO1_SEL 0x0C // u8 position\r
-#define ANX7150_I2SCH_FIFO0_SEL 0x03 // u8 position\r
-\r
-#define ANX7150_I2SCH_SWCTRL_REG 0x54\r
-\r
-#define ANX7150_I2SCH_SWCTRL_SW3 0x80 // u8 position\r
-#define ANX7150_I2SCH_SWCTRL_SW2 0x40 // u8 position\r
-#define ANX7150_I2SCH_SWCTRL_SW1 0x20 // u8 position\r
-#define ANX7150_I2SCH_SWCTRL_SW0 0x10 // u8 position\r
-#define ANX7150_I2SCH_SWCTRL_INWD_LEN 0xE0 // u8 position\r
-#define ANX7150_I2SCH_SWCTRL_INWD_MAX 0x01 // u8 position\r
-\r
-#define ANX7150_SPDIFCH_STATUS_REG 0x55\r
-#define ANX7150_SPDIFCH_STATUS_FS_FREG 0xF0 // u8 position\r
-#define ANX7150_SPDIFCH_STATUS_WD_LEN 0x0E // u8 position\r
-#define ANX7150_SPDIFCH_STATUS_WD_MX 0x01 // u8 position\r
-\r
-#define ANX7150_I2SCH_STATUS1_REG 0x56\r
-#define ANX7150_I2SCH_STATUS1_MODE 0xC0 // u8 position\r
-#define ANX7150_I2SCH_STATUS1_PCM_MODE 0x38 // u8 position\r
-#define ANX7150_I2SCH_STATUS1_SW_CPRGT 0x04 // u8 position\r
-#define ANX7150_I2SCH_STATUS1_NON_PCM 0x02 // u8 position\r
-#define ANX7150_I2SCH_STATUS1_PROF_APP 0x01 // u8 position\r
-\r
-#define ANX7150_I2SCH_STATUS2_REG 0x57\r
-\r
-#define ANX7150_I2SCH_STATUS3_REG 0x58\r
-#define ANX7150_I2SCH_STATUS3_CH_NUM 0xF0 // u8 position\r
-#define ANX7150_I2SCH_STATUS3_SRC_NUM 0x0F // u8 position\r
-\r
-\r
-\r
-#define ANX7150_I2SCH_STATUS4_REG 0x59\r
-\r
-#define ANX7150_I2SCH_STATUS5_REG 0x5A\r
-\r
-#define ANX7150_I2SCH_STATUS5_WORD_MAX 0x01 // u8 position\r
-\r
-#define ANX7150_HDMI_AUDSTATUS_REG 0x5B\r
-\r
-#define ANX7150_HDMI_AUDSTATUS_SPDIF_DET 0x01 // u8 position\r
-\r
-#define ANX7150_HDMI_AUDBIST_CTRL_REG 0x5C\r
-\r
-#define ANX7150_HDMI_AUDBIST_EN3 0x08 // u8 position\r
-#define ANX7150_HDMI_AUDBIST_EN2 0x04 // u8 position\r
-#define ANX7150_HDMI_AUDBIST_EN1 0x02 // u8 position\r
-#define ANX7150_HDMI_AUDBIST_EN0 0x01 // u8 position\r
-\r
-#define ANX7150_AUD_INCLK_CNT_REG 0x5D\r
-#define ANX7150_AUD_DEBUG_STATUS_REG 0x5E\r
-\r
-#define ANX7150_ONEu8_AUD_CTRL_REG 0x60\r
-\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN7 0x80 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN6 0x40 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN5 0x20 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN4 0x10 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN3 0x08 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN2 0x04 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN1 0x02 // u8 position\r
-#define ANX7150_ONEu8_AUD_CTRL_SEN0 0x01 // u8 position\r
-\r
-#define ANX7150_ONEu8_AUD0_CTRL_REG 0x61\r
-#define ANX7150_ONEu8_AUD1_CTRL_REG 0x62\r
-#define ANX7150_ONEu8_AUD2_CTRL_REG 0x63\r
-#define ANX7150_ONEu8_AUD3_CTRL_REG 0x64\r
-\r
-#define ANX7150_ONEu8_AUDCLK_CTRL_REG 0x65\r
-\r
-#define ANX7150_ONEu8_AUDCLK_DET 0x08 // u8 position\r
-\r
-#define ANX7150_SPDIF_ERR_THRSHLD_REG 0x66\r
-#define ANX7150_SPDIF_ERR_CNT_REG 0x67\r
-\r
-#define ANX7150_HDMI_LINK_CTRL_REG 0x70\r
-\r
-#define ANX7150_HDMI_LINK_DATA_MUTEEN1 0x80 // u8 position\r
-#define ANX7150_HDMI_LINK_DATA_MUTEEN0 0x40 // u8 position\r
-#define ANX7150_HDMI_LINK_CLK_MUTEEN2 0x20 // u8 position\r
-#define ANX7150_HDMI_LINK_CLK_MUTEEN1 0x10 // u8 position\r
-#define ANX7150_HDMI_LINK_CLK_MUTEEN0 0x08 // u8 position\r
-#define ANX7150_HDMI_LINK_DEC_DE 0x04 // u8 position\r
-#define ANX7150_HDMI_LINK_PRMB_INC 0x02 // u8 position\r
-#define ANX7150_HDMI_LINK_AUTO_PROG 0x01 // u8 position\r
-\r
-#define ANX7150_VID_CAPCTRL2_REG 0x71\r
-\r
-#define ANX7150_VID_CAPCTRL2_CHK_UPDATEEN 0x10 // u8 position\r
-\r
-#define ANX7150_LINK_MUTEEE_REG 0x72\r
-\r
-#define ANX7150_LINK_MUTEEE_AVMUTE_EN2 0x20 // u8 position\r
-#define ANX7150_LINK_MUTEEE_AVMUTE_EN1 0x10 // u8 position\r
-#define ANX7150_LINK_MUTEEE_AVMUTE_EN0 0x08 // u8 position\r
-#define ANX7150_LINK_MUTEEE_AUDMUTE_EN2 0x04 // u8 position\r
-#define ANX7150_LINK_MUTEEE_AUDMUTE_EN1 0x02 // u8 position\r
-#define ANX7150_LINK_MUTEEE_AUDMUTE_EN0 0x01 // u8 position\r
-\r
-#define ANX7150_SERDES_TEST0_REG 0x73\r
-#define ANX7150_SERDES_TEST1_REG 0x74\r
-#define ANX7150_SERDES_TEST2_REG 0x75\r
-\r
-#define ANX7150_PLL_TX_AMP 0x76\r
-\r
-\r
-#define ANX7150_DDC_SLV_ADDR_REG 0x80\r
-#define ANX7150_DDC_SLV_SEGADDR_REG 0x81\r
-#define ANX7150_DDC_SLV_OFFADDR_REG 0x82\r
-#define ANX7150_DDC_ACC_CMD_REG 0x83\r
-#define ANX7150_DDC_ACCNUM0_REG 0x84\r
-#define ANX7150_DDC_ACCNUM1_REG 0x85\r
-\r
-#define ANX7150_DDC_CHSTATUS_REG 0x86\r
-\r
-#define ANX7150_DDC_CHSTATUS_DDCERR 0x80 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_DDC_OCCUPY 0x40 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_FIFO_FULL 0x20 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_FIFO_EMPT 0x10 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_NOACK 0x08 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_FIFO_RD 0x04 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_FIFO_WR 0x02 // u8 position\r
-#define ANX7150_DDC_CHSTATUS_INPRO 0x01 // u8 position\r
-\r
-#define ANX7150_DDC_FIFO_ACC_REG 0x87\r
-#define ANX7150_DDC_FIFOCNT_REG 0x88\r
-\r
-#define ANX7150_SYS_PD_REG 0x90\r
-#define ANX7150_SYS_PD_PLL 0x80 // u8 position\r
-#define ANX7150_SYS_PD_TMDS 0x40 // u8 position\r
-#define ANX7150_SYS_PD_TMDS_CLK 0x20 // u8 position\r
-#define ANX7150_SYS_PD_MISC 0x10 // u8 position\r
-#define ANX7150_SYS_PD_LINK 0x08 // u8 position\r
-#define ANX7150_SYS_PD_IDCK 0x04 // u8 position\r
-#define ANX7150_SYS_PD_AUD 0x02 // u8 position\r
-#define ANX7150_SYS_PD_MACRO_ALL 0x01 // u8 position\r
-\r
-#define ANX7150_LINKFSM_DEBUG0_REG 0x91\r
-#define ANX7150_LINKFSM_DEBUG1_REG 0x92\r
-\r
-#define ANX7150_PLL_CTRL0_REG 0x93\r
-#define ANX7150_PLL_CTRL0_CPREG_BLEED 0x02 // u8 position\r
-#define ANX7150_PLL_CTRL0_TEST_EN 0x01 // u8 position\r
-\r
-#define ANX7150_PLL_CTRL1_REG 0x94\r
-#define ANX7150_PLL_CTRL1_TESTEN 0x80 // u8 position\r
-\r
-#define ANX7150_OSC_CTRL_REG 0x95\r
-#define ANX7150_OSC_CTRL_TESTEN 0x80 // u8 position\r
-#define ANX7150_OSC_CTRL_SEL_BG 0x40 // u8 position\r
-\r
-#define ANX7150_TMDS_CH0_CONFIG_REG 0x96\r
-#define ANX7150_TMDS_CH0_TESTEN 0x20 // u8 position\r
-#define ANX7150_TMDS_CH0_AMP 0x1C // u8 position\r
-#define ANX7150_TMDS_CHO_EMP 0x03 // u8 position\r
-\r
-#define ANX7150_TMDS_CH1_CONFIG_REG 0x97\r
-#define ANX7150_TMDS_CH1_TESTEN 0x20 // u8 position\r
-#define ANX7150_TMDS_CH1_AMP 0x1C // u8 position\r
-#define ANX7150_TMDS_CH1_EMP 0x03 // u8 position\r
-\r
-#define ANX7150_TMDS_CH2_CONFIG_REG 0x98\r
-#define ANX7150_TMDS_CH2_TESTEN 0x20 // u8 position\r
-#define ANX7150_TMDS_CH2_AMP 0x1C // u8 position\r
-#define ANX7150_TMDS_CH2_EMP 0x03 // u8 position\r
-\r
-#define ANX7150_TMDS_CLKCH_CONFIG_REG 0x99\r
-#define ANX7150_TMDS_CLKCH_MUTE 0x80 // u8 position\r
-#define ANX7150_TMDS_CLKCH_TESTEN 0x08 // u8 position\r
-#define ANX7150_TMDS_CLKCH_AMP 0x07 // u8 position\r
-\r
-#define ANX7150_CHIP_CTRL_REG 0x9A\r
-#define ANX7150_CHIP_CTRL_PRBS_GENEN 0x80 // u8 position\r
-#define ANX7150_CHIP_CTRL_LINK_DBGSEL 0x70 // u8 position\r
-#define ANX7150_CHIP_CTRL_VIDCHK_EN 0x08 // u8 position\r
-#define ANX7150_CHIP_CTRL_MISC_TIMER 0x04 // u8 position\r
-#define ANX7150_CHIP_CTRL_PLL_RNG 0x02 // u8 position\r
-#define ANX7150_CHIP_CTRL_PLL_MAN 0x01 // u8 position\r
-\r
-#define ANX7150_CHIP_STATUS_REG 0x9B\r
-#define ANX7150_CHIP_STATUS_GPIO 0x80 // u8 position\r
-#define ANX7150_CHIP_STATUS_SDA 0x40 // u8 position\r
-#define ANX7150_CHIP_STATUS_SCL 0x20 // u8 position\r
-#define ANX7150_CHIP_STATUS_PLL_HSPO 0x04 // u8 position\r
-#define ANX7150_CHIP_STATUS_PLL_LOCK 0x02 // u8 position\r
-#define ANX7150_CHIP_STATUS_MISC_LOCK 0x01 // u8 position\r
-\r
-#define ANX7150_DBG_PINGPIO_CTRL_REG 0x9C\r
-#define ANX7150_DBG_PINGPIO_VDLOW_SHAREDEN 0x04 // u8 position\r
-#define ANX7150_DBG_PINGPIO_GPIO_ADDREN 0x02 // u8 position\r
-#define ANX7150_DBG_PINGPIO_GPIO_OUT 0x01 // u8 position\r
-\r
-#define ANX7150_CHIP_DEBUG0_CTRL_REG 0x9D\r
-#define ANX7150_CHIP_DEBUG0_PRBS_ERR 0xE0 // u8 position\r
-#define ANX7150_CHIP_DEBUG0_CAPST 0x1F // u8 position\r
-\r
-#define ANX7150_CHIP_DEBUG1_CTRL_REG 0x9E\r
-#define ANX7150_CHIP_DEBUG1_SDA_SW 0x80 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_SCL_SW 0x40 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_SERDES_TESTEN 0x20 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_CLK_BYPASS 0x10 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_FORCE_PLLLOCK 0x08 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_PLLLOCK_BYPASS 0x04 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_FORCE_HP 0x02 // u8 position\r
-#define ANX7150_CHIP_DEBUG1_HP_DEGLITCH 0x01 // u8 position\r
-\r
-#define ANX7150_CHIP_DEBUG2_CTRL_REG 0x9F\r
-#define ANX7150_CHIP_DEBUG2_EXEMB_SYNCEN 0x04 // u8 position\r
-#define ANX7150_CHIP_DEBUG2_VIDBIST 0x02 // u8 position\r
-\r
-#define ANX7150_VID_INCLK_REG 0x5F\r
-\r
-#define ANX7150_HDCP_STATUS_REG 0xA0\r
-#define ANX7150_HDCP_STATUS_ADV_CIPHER 0x80 // u8 position\r
-#define ANX7150_HDCP_STATUS_R0_READY 0x10 // u8 position\r
-#define ANX7150_HDCP_STATUS_AKSV_ACT 0x08 // u8 position\r
-#define ANX7150_HDCP_STATUS_ENCRYPT 0x04 // u8 position\r
-#define ANX7150_HDCP_STATUS_AUTH_PASS 0x02 // u8 position\r
-#define ANX7150_HDCP_STATUS_KEY_DONE 0x01 // u8 position\r
-\r
-#define ANX7150_HDCP_CTRL0_REG 0xA1\r
-#define ANX7150_HDCP_CTRL0_STORE_AN 0x80 // u8 position\r
-#define ANX7150_HDCP_CTRL0_RX_REP 0x40 // u8 position\r
-#define ANX7150_HDCP_CTRL0_RE_AUTH 0x20 // u8 position\r
-#define ANX7150_HDCP_CTRL0_SW_AUTHOK 0x10 // u8 position\r
-#define ANX7150_HDCP_CTRL0_HW_AUTHEN 0x08 // u8 position\r
-#define ANX7150_HDCP_CTRL0_ENC_EN 0x04 // u8 position\r
-#define ANX7150_HDCP_CTRL0_BKSV_SRM 0x02 // u8 position\r
-#define ANX7150_HDCP_CTRL0_KSV_VLD 0x01 // u8 position\r
-\r
-#define ANX7150_HDCP_CTRL1_REG 0xA2\r
-#define ANX7150_LINK_CHK_12_EN 0x40\r
-#define ANX7150_HDCP_CTRL1_DDC_NOSTOP 0x20 // u8 position\r
-#define ANX7150_HDCP_CTRL1_DDC_NOACK 0x10 // u8 position\r
-#define ANX7150_HDCP_CTRL1_EDDC_NOACK 0x08 // u8 position\r
-#define ANX7150_HDCP_CTRL1_BLUE_SCREEN_EN 0x04 // u8 position\r
-#define ANX7150_HDCP_CTRL1_RCV11_EN 0x02 // u8 position\r
-#define ANX7150_HDCP_CTRL1_HDCP11_EN 0x01 // u8 position\r
-\r
-#define ANX7150_HDCP_Link_Check_FRAME_NUM_REG 0xA3\r
-#define ANX7150_HDCP_AKSV1_REG 0xA5\r
-#define ANX7150_HDCP_AKSV2_REG 0xA6\r
-#define ANX7150_HDCP_AKSV3_REG 0xA7\r
-#define ANX7150_HDCP_AKSV4_REG 0xA8\r
-#define ANX7150_HDCP_AKSV5_REG 0xA9\r
-\r
-#define ANX7150_HDCP_AN1_REG 0xAA\r
-#define ANX7150_HDCP_AN2_REG 0xAB\r
-#define ANX7150_HDCP_AN3_REG 0xAC\r
-#define ANX7150_HDCP_AN4_REG 0xAD\r
-#define ANX7150_HDCP_AN5_REG 0xAE\r
-#define ANX7150_HDCP_AN6_REG 0xAF\r
-#define ANX7150_HDCP_AN7_REG 0xB0\r
-#define ANX7150_HDCP_AN8_REG 0xB1\r
-\r
-#define ANX7150_HDCP_BKSV1_REG 0xB2\r
-#define ANX7150_HDCP_BKSV2_REG 0xB3\r
-#define ANX7150_HDCP_BKSV3_REG 0xB4\r
-#define ANX7150_HDCP_BKSV4_REG 0xB5\r
-#define ANX7150_HDCP_BKSV5_REG 0xB6\r
-\r
-#define ANX7150_HDCP_RI1_REG 0xB7\r
-#define ANX7150_HDCP_RI2_REG 0xB8\r
-\r
-#define ANX7150_HDCP_PJ_REG 0xB9\r
-#define ANX7150_HDCP_RX_CAPS_REG 0xBA\r
-#define ANX7150_HDCP_BSTATUS0_REG 0xBB\r
-#define ANX7150_HDCP_BSTATUS1_REG 0xBC\r
-\r
-#define ANX7150_HDCP_AMO0_REG 0xD0\r
-#define ANX7150_HDCP_AMO1_REG 0xD1\r
-#define ANX7150_HDCP_AMO2_REG 0xD2\r
-#define ANX7150_HDCP_AMO3_REG 0xD3\r
-#define ANX7150_HDCP_AMO4_REG 0xD4\r
-#define ANX7150_HDCP_AMO5_REG 0xD5\r
-#define ANX7150_HDCP_AMO6_REG 0xD6\r
-#define ANX7150_HDCP_AMO7_REG 0xD7\r
-\r
-#define ANX7150_HDCP_DBG_CTRL_REG 0xBD\r
-\r
-#define ANX7150_HDCP_DBG_ENC_INC 0x08 // u8 position\r
-#define ANX7150_HDCP_DBG_DDC_SPEED 0x06 // u8 position\r
-#define ANX7150_HDCP_DBG_SKIP_RPT 0x01 // u8 position\r
-\r
-#define ANX7150_HDCP_KEY_STATUS_REG 0xBE\r
-#define ANX7150_HDCP_KEY_BIST_EN 0x04 // u8 position\r
-#define ANX7150_HDCP_KEY_BIST_ERR 0x02 // u8 position\r
-#define ANX7150_HDCP_KEY_CMD_DONE 0x01 // u8 position\r
-\r
-#define ANX7150_KEY_CMD_REGISTER 0xBF //added\r
-\r
-#define ANX7150_HDCP_AUTHDBG_STATUS_REG 0xC7\r
-#define ANX7150_HDCP_ENCRYPTDBG_STATUS_REG 0xC8\r
-#define ANX7150_HDCP_FRAME_NUM_REG 0xC9\r
-\r
-#define ANX7150_DDC_MSTR_INTER_REG 0xCA\r
-#define ANX7150_DDC_MSTR_LINK_REG 0xCB\r
-\r
-#define ANX7150_HDCP_BLUESCREEN0_REG 0xCC\r
-#define ANX7150_HDCP_BLUESCREEN1_REG 0xCD\r
-#define ANX7150_HDCP_BLUESCREEN2_REG 0xCE\r
-// DEV_ADDR = 0x7A or 0x7E\r
-#define ANX7150_INFO_PKTCTRL1_REG 0xC0\r
-#define ANX7150_INFO_PKTCTRL1_SPD_RPT 0x80 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_SPD_EN 0x40 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_AVI_RPT 0x20 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_AVI_EN 0x10 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_GCP_RPT 0x08 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_GCP_EN 0x04 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_ACR_NEW 0x02 // u8 position\r
-#define ANX7150_INFO_PKTCTRL1_ACR_EN 0x01 // u8 position\r
-\r
-#define ANX7150_INFO_PKTCTRL2_REG 0xC1\r
-#define ANX7150_INFO_PKTCTRL2_UD1_RPT 0x80 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_UD1_EN 0x40 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_UD0_RPT 0x20 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_UD0_EN 0x10 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_MPEG_RPT 0x08 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_MPEG_EN 0x04 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_AIF_RPT 0x02 // u8 position\r
-#define ANX7150_INFO_PKTCTRL2_AIF_EN 0x01 // u8 position\r
-\r
-#define ANX7150_ACR_N1_SW_REG 0xC2\r
-#define ANX7150_ACR_N2_SW_REG 0xC3\r
-#define ANX7150_ACR_N3_SW_REG 0xC4\r
-\r
-#define ANX7150_ACR_CTS1_SW_REG 0xC5\r
-#define ANX7150_ACR_CTS2_SW_REG 0xC6\r
-#define ANX7150_ACR_CTS3_SW_REG 0xC7\r
-\r
-#define ANX7150_ACR_CTS1_HW_REG 0xC8\r
-#define ANX7150_ACR_CTS2_HW_REG 0xC9\r
-#define ANX7150_ACR_CTS3_HW_REG 0xCA\r
-\r
-#define ANX7150_ACR_CTS_CTRL_REG 0xCB\r
-\r
-#define ANX7150_GNRL_CTRL_PKT_REG 0xCC\r
-#define ANX7150_GNRL_CTRL_CLR_AVMUTE 0x02 // u8 position\r
-#define ANX7150_GNRL_CTRL_SET_AVMUTE 0x01 // u8 position\r
-\r
-#define ANX7150_AUD_PKT_FLATCTRL_REG 0xCD\r
-#define ANX7150_AUD_PKT_AUTOFLAT_EN 0x80 // u8 position\r
-#define ANX7150_AUD_PKT_FLAT 0x07 // u8 position\r
-\r
-\r
-//select video hardware interface\r
-#define ANX7150_VID_HW_INTERFACE 0x03//0x00:RGB and YcbCr 4:4:4 Formats with Separate Syncs (24-bpp mode)\r
- //0x01:YCbCr 4:2:2 Formats with Separate Syncs(16-bbp)\r
- //0x02:YCbCr 4:2:2 Formats with Embedded Syncs(No HS/VS/DE)\r
- //0x03:YC Mux 4:2:2 Formats with Separate Sync Mode1(u815:8 and u8 3:0 are used)\r
- //0x04:YC Mux 4:2:2 Formats with Separate Sync Mode2(u811:0 are used)\r
- //0x05:YC Mux 4:2:2 Formats with Embedded Sync Mode1(u815:8 and u8 3:0 are used)\r
- //0x06:YC Mux 4:2:2 Formats with Embedded Sync Mode2(u811:0 are used)\r
- //0x07:RGB and YcbCr 4:4:4 DDR Formats with Separate Syncs\r
- //0x08:RGB and YcbCr 4:4:4 DDR Formats with Embedded Syncs\r
- //0x09:RGB and YcbCr 4:4:4 Formats with Separate Syncs but no DE\r
- //0x0a:YCbCr 4:2:2 Formats with Separate Syncs but no DE\r
-//select input color space\r
-#define ANX7150_INPUT_COLORSPACE 0x01//0x00: input color space is RGB\r
- //0x01: input color space is YCbCr422\r
- //0x02: input color space is YCbCr444\r
-//select input pixel clock edge for DDR mode\r
-#define ANX7150_IDCK_EDGE_DDR 0x00 //0x00:use rising edge to latch even numbered pixel data//jack wen\r
- //0x01:use falling edge to latch even numbered pixel data\r
-\r
-//select audio hardware interface\r
-#define ANX7150_AUD_HW_INTERFACE 0x01//0x01:audio input comes from I2S\r
- //0x02:audio input comes from SPDIF\r
- //0x04:audio input comes from one u8 audio\r
-//select MCLK and Fs relationship if audio HW interface is I2S\r
-#define ANX7150_MCLK_Fs_RELATION 0x01//0x00:MCLK = 128 * Fs\r
- //0x01:MCLK = 256 * Fs\r
- //0x02:MCLK = 384 * Fs\r
- //0x03:MCLK = 512 * Fs //wen updated error\r
-\r
-#define ANX7150_AUD_CLK_EDGE 0x00 //0x00:use MCLK and SCK rising edge to latch audio data\r
- //0x08, revised by wen. //0x80:use MCLK and SCK falling edge to latch audio data\r
-//select I2S channel numbers if audio HW interface is I2S\r
-#define ANX7150_I2S_CH0_ENABLE 0x01 //0x01:enable channel 0 input; 0x00: disable\r
-#define ANX7150_I2S_CH1_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
-#define ANX7150_I2S_CH2_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
-#define ANX7150_I2S_CH3_ENABLE 0x00 //0x01:enable channel 0 input; 0x00: disable\r
-//select I2S word length if audio HW interface is I2S\r
-#define ANX7150_I2S_WORD_LENGTH 0x0b\r
- //0x02 = 16u8s; 0x04 = 18 u8s; 0x08 = 19 u8s; 0x0a = 20 u8s(maximal word length is 20u8s); 0x0c = 17 u8s;\r
- // 0x03 = 20u8s(maximal word length is 24u8s); 0x05 = 22 u8s; 0x09 = 23 u8s; 0x0b = 24 u8s; 0x0d = 21 u8s;\r
-\r
-//select I2S format if audio HW interface is I2S\r
-#define ANX7150_I2S_SHIFT_CTRL 0x00//0x00: fist u8 shift(philips spec)\r
- //0x01:no shift\r
-#define ANX7150_I2S_DIR_CTRL 0x00//0x00:SD data MSB first\r
- //0x01:LSB first\r
-#define ANX7150_I2S_WS_POL 0x00//0x00:left polarity when word select is low\r
- //0x01:left polarity when word select is high\r
-#define ANX7150_I2S_JUST_CTRL 0x00//0x00:data is left justified\r
- //0x01:data is right justified\r
-\r
-#define EDID_Parse_Enable 1 // cwz 0 for test, 1 normal\r
-//InfoFrame and Control Packet Registers\r
-// 0x7A or 0X7E\r
-/*\r
-#define AVI_HB0 0x00\r
-#define AVI_HB1 0x01\r
-#define AVI_HB2 0x02\r
-#define AVI_PB0 0x03\r
-#define AVI_PB1 0x04\r
-#define AVI_PB2 0x05\r
-#define AVI_PB3 0x06\r
-#define AVI_PB4 0x07\r
-#define AVI_PB5 0x08\r
-#define AVI_PB6 0x09\r
-#define AVI_PB7 0x0A\r
-#define AVI_PB8 0x0B\r
-#define AVI_PB9 0x0C\r
-#define AVI_PB10 0x0D\r
-#define AVI_PB11 0x0E\r
-#define AVI_PB12 0x0F\r
-#define AVI_PB13 0x10\r
-#define AVI_PB14 0x11\r
-#define AVI_PB15 0x12\r
-\r
-#define AUD_HBO 0x20\r
-#define AUD_HB1 0x21\r
-#define AUD_HB2 0x22\r
-#define AUD_PB0 0x23\r
-#define AUD_PB1 0x24\r
-#define AUD_PB2 0x25\r
-#define AUD_PB3 0x26\r
-#define AUD_PB4 0x27\r
-#define AUD_PB5 0x28\r
-#define AUD_PB6 0x29\r
-#define AUD_PB7 0x2A\r
-#define AUD_PB8 0x2B\r
-#define AUD_PB9 0x2C\r
-#define AUD_PB10 0x2D\r
-\r
-#define SPD_HBO 0x40\r
-#define SPD_HB1 0x41\r
-#define SPD_HB2 0x42\r
-#define SPD_PB0 0x43\r
-#define SPD_PB1 0x44\r
-#define SPD_PB2 0x45\r
-#define SPD_PB3 0x46\r
-#define SPD_PB4 0x47\r
-#define SPD_PB5 0x48\r
-#define SPD_PB6 0x49\r
-#define SPD_PB7 0x4A\r
-#define SPD_PB8 0x4B\r
-#define SPD_PB9 0x4C\r
-#define SPD_PB10 0x4D\r
-#define SPD_PB11 0x4E\r
-#define SPD_PB12 0x4F\r
-#define SPD_PB13 0x50\r
-#define SPD_PB14 0x51\r
-#define SPD_PB15 0x52\r
-#define SPD_PB16 0x53\r
-#define SPD_PB17 0x54\r
-#define SPD_PB18 0x55\r
-#define SPD_PB19 0x56\r
-#define SPD_PB20 0x57\r
-#define SPD_PB21 0x58\r
-#define SPD_PB22 0x59\r
-#define SPD_PB23 0x5A\r
-#define SPD_PB24 0x5B\r
-#define SPD_PB25 0x5C\r
-#define SPD_PB26 0x5D\r
-#define SPD_PB27 0x5E\r
-\r
-#define MPEG_HBO 0x60\r
-#define MPEG_HB1 0x61\r
-#define MPEG_HB2 0x62\r
-#define MPEG_PB0 0x63\r
-#define MPEG_PB1 0x64\r
-#define MPEG_PB2 0x65\r
-#define MPEG_PB3 0x66\r
-#define MPEG_PB4 0x67\r
-#define MPEG_PB5 0x68\r
-#define MPEG_PB6 0x69\r
-#define MPEG_PB7 0x6A\r
-#define MPEG_PB8 0x6B\r
-#define MPEG_PB9 0x6C\r
-#define MPEG_PB10 0x6D\r
-#define MPEG_PB11 0x6E\r
-#define MPEG_PB12 0x6F\r
-#define MPEG_PB13 0x70\r
-#define MPEG_PB14 0x71\r
-#define MPEG_PB15 0x72\r
-#define MPEG_PB16 0x73\r
-#define MPEG_PB17 0x74\r
-#define MPEG_PB18 0x75\r
-#define MPEG_PB19 0x76\r
-#define MPEG_PB20 0x77\r
-#define MPEG_PB21 0x78\r
-#define MPEG_PB22 0x79\r
-#define MPEG_PB23 0x7A\r
-#define MPEG_PB24 0x7B\r
-#define MPEG_PB25 0x7C\r
-#define MPEG_PB26 0x7D\r
-#define MPEG_PB27 0x7E\r
-\r
-#define USRDF0_HBO 0x80\r
-#define USRDF0_HB1 0x81\r
-#define USRDF0_HB2 0x82\r
-#define USRDF0_PB0 0x83\r
-#define USRDF0_PB1 0x84\r
-#define USRDF0_PB2 0x85\r
-#define USRDF0_PB3 0x86\r
-#define USRDF0_PB4 0x87\r
-#define USRDF0_PB5 0x88\r
-#define USRDF0_PB6 0x89\r
-#define USRDF0_PB7 0x8A\r
-#define USRDF0_PB8 0x8B\r
-#define USRDF0_PB9 0x8C\r
-#define USRDF0_PB10 0x8D\r
-#define USRDF0_PB11 0x8E\r
-#define USRDF0_PB12 0x8F\r
-#define USRDF0_PB13 0x90\r
-#define USRDF0_PB14 0x91\r
-#define USRDF0_PB15 0x92\r
-#define USRDF0_PB16 0x93\r
-#define USRDF0_PB17 0x94\r
-#define USRDF0_PB18 0x95\r
-#define USRDF0_PB19 0x96\r
-#define USRDF0_PB20 0x97\r
-#define USRDF0_PB21 0x98\r
-#define USRDF0_PB22 0x99\r
-#define USRDF0_PB23 0x9A\r
-#define USRDF0_PB24 0x9B\r
-#define USRDF0_PB25 0x9C\r
-#define USRDF0_PB26 0x9D\r
-#define USRDF0_PB27 0x9E\r
-\r
-#define USRDF1_HBO 0xA0\r
-#define USRDF1_HB1 0xA1\r
-#define USRDF1_HB2 0xA2\r
-#define USRDF1_PB0 0xA3\r
-#define USRDF1_PB1 0xA4\r
-#define USRDF1_PB2 0xA5\r
-#define USRDF1_PB3 0xA6\r
-#define USRDF1_PB4 0xA7\r
-#define USRDF1_PB5 0xA8\r
-#define USRDF1_PB6 0xA9\r
-#define USRDF1_PB7 0xAA\r
-#define USRDF1_PB8 0xAB\r
-#define USRDF1_PB9 0xAC\r
-#define USRDF1_PB10 0xAD\r
-#define USRDF1_PB11 0xAE\r
-#define USRDF1_PB12 0xAF\r
-#define USRDF1_PB13 0xB0\r
-#define USRDF1_PB14 0xB1\r
-#define USRDF1_PB15 0xB2\r
-#define USRDF1_PB16 0xB3\r
-#define USRDF1_PB17 0xB4\r
-#define USRDF1_PB18 0xB5\r
-#define USRDF1_PB19 0xB6\r
-#define USRDF1_PB20 0xB7\r
-#define USRDF1_PB21 0xB8\r
-#define USRDF1_PB22 0xB9\r
-#define USRDF1_PB23 0xBA\r
-#define USRDF1_PB24 0xBB\r
-#define USRDF1_PB25 0xBC\r
-#define USRDF1_PB26 0xBD\r
-#define USRDF1_PB27 0xBE\r
-*/\r
- int anx7150_get_hpd(struct i2c_client *client);\r
-\r
-void ANX7150_API_HDCP_ONorOFF(u8 HDCP_ONorOFF);\r
-int anx7150_detect_device(struct anx7150_pdata *anx);\r
-u8 ANX7150_Get_System_State(void);\r
-int ANX7150_Interrupt_Process(struct anx7150_pdata *anx, int cur_state);\r
-int anx7150_unplug(struct i2c_client *client);\r
-int anx7150_plug(struct i2c_client *client);\r
-int ANX7150_API_Initial(struct i2c_client *client);\r
-void ANX7150_Shutdown(struct i2c_client *client);\r
-int ANX7150_Parse_EDID(struct i2c_client *client, struct anx7150_dev_s *dev);\r
-int ANX7150_GET_SENSE_STATE(struct i2c_client *client);\r
-int ANX7150_Get_Optimal_resolution(int resolution_set);\r
-void HDMI_Set_Video_Format(u8 video_format);\r
-void HDMI_Set_Audio_Fs( u8 audio_fs);\r
-void ANX7150_API_System_Config(void);\r
-u8 ANX7150_Config_Audio(struct i2c_client *client);\r
-u8 ANX7150_Config_Packet(struct i2c_client *client);\r
-void ANX7150_HDCP_Process(struct i2c_client *client,int enable);\r
-int ANX7150_PLAYBACK_Process(void);\r
-void ANX7150_Set_System_State(struct i2c_client *client, u8 new_state);\r
-int ANX7150_Config_Video(struct i2c_client *client);\r
-int ANX7150_GET_RECIVER_TYPE(void);\r
-void HDMI_Set_Video_Format(u8 video_format);\r
-void HDMI_Set_Audio_Fs( u8 audio_fs);\r
-int ANX7150_PLAYBACK_Process(void);\r
-int ANX7150_Blue_Screen(struct anx7150_pdata *anx);\r
-int anx7150_set_avmute(struct i2c_client *client);\r
-int anx7150_initial(struct i2c_client *client);\r
-\r
-#endif\r
--- /dev/null
+#include <linux/kernel.h>\r
+#include <linux/delay.h>\r
+#include <linux/module.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/hdmi.h>\r
+#include <linux/i2c.h>\r
+#include <linux/interrupt.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+#include <linux/irq.h>\r
+\r
+#include <linux/mfd/rk610_core.h>\r
+#include "rk610_hdmi.h"\r
+#include "rk610_hdmi_hw.h"\r
+\r
+\r
+struct i2c_client *rk610_g_hdmi_client=NULL;\r
+static bool hpd=0;\r
+\r
+static void rk610_handler(struct work_struct *work)\r
+{\r
+ struct i2c_client *client = rk610_g_hdmi_client;\r
+ if(client==NULL){\r
+ printk(">>> %s client==NULL\n",__func__);\r
+ }\r
+ Rk610_hdmi_event_work(client,&hpd);\r
+}\r
+\r
+static DECLARE_DELAYED_WORK(rk610_irq_work, rk610_handler);\r
+static int rk610_hdmi_precent(struct hdmi *hdmi)\r
+{\r
+ //struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);\r
+ schedule_delayed_work(&rk610_irq_work, msecs_to_jiffies(30));\r
+ return hpd;\r
+}\r
+\r
+static int rk610_hdmi_param_chg(struct rk610_hdmi_inf *rk610_hdmi)\r
+{\r
+ RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);\r
+ hdmi_switch_fb(rk610_hdmi->hdmi, rk610_hdmi->hdmi->display_on);\r
+ Rk610_hdmi_Set_Video(rk610_hdmi->hdmi->resolution);\r
+ Rk610_hdmi_Set_Audio(rk610_hdmi->hdmi->audio_fs);\r
+ Rk610_hdmi_Config_Done(rk610_hdmi->client);\r
+ return 0;\r
+}\r
+\r
+static int rk610_hdmi_set_param(struct hdmi *hdmi)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);\r
+ RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);\r
+ if(rk610_hdmi->init == 1)\r
+ return 0;\r
+\r
+ rk610_hdmi_param_chg(rk610_hdmi);\r
+ return 0;\r
+}\r
+static int rk610_hdmi_insert(struct hdmi *hdmi)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);\r
+ RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);\r
+ if(rk610_hdmi->init == 1)\r
+ return -1;\r
+ rk610_hdmi_param_chg(rk610_hdmi);\r
+ hdmi_set_spk(HDMI_DISABLE);\r
+ printk("rk610_hdmi_insert hdmi->display_on=%d\n",hdmi->display_on);\r
+ hdmi->scale = hdmi->scale_set;\r
+ return 0;\r
+}\r
+static int rk610_hdmi_remove(struct hdmi *hdmi)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);\r
+ RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);\r
+ if(rk610_hdmi->init == 1)\r
+ return -1;\r
+ hdmi_set_spk(HDMI_ENABLE);\r
+ hdmi_switch_fb(hdmi, HDMI_DISABLE);\r
+ printk("rk610_hdmi_remove hdmi->display_on=%d\n",hdmi->display_on);\r
+ return 0;\r
+}\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+static void rk610_hdmi_early_suspend(struct early_suspend *h)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = container_of(h,\r
+ struct rk610_hdmi_inf,\r
+ early_suspend);\r
+ printk( "rk610_hdmi enter early suspend\n");\r
+ hdmi_suspend(rk610_hdmi->hdmi);\r
+ Rk610_hdmi_suspend(rk610_hdmi->client);\r
+ return;\r
+}\r
+\r
+static void rk610_hdmi_early_resume(struct early_suspend *h)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = container_of(h,\r
+ struct rk610_hdmi_inf,\r
+ early_suspend);\r
+ printk("rk610_hdmi exit early suspend\n");\r
+ hdmi_resume(rk610_hdmi->hdmi);\r
+ Rk610_hdmi_resume(rk610_hdmi->client);\r
+ return;\r
+}\r
+#endif\r
+ \r
+static int rk610_hdmi_init(struct hdmi *hdmi)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);\r
+#ifdef CONFIG_HDMI_SAVE_DATA\r
+ int hdmi_data = hdmi_get_data();\r
+ if(hdmi_data<0){\r
+ hdmi_set_data((hdmi->resolution&0x7)|((hdmi->scale&0x1f)<<3));\r
+ }\r
+ else{\r
+ hdmi->resolution = hdmi_data&0x7;\r
+ hdmi->scale_set= ((hdmi_data>>3)&0x1f) + MIN_SCALE;\r
+ hdmi->scale = hdmi->scale_set;\r
+ }\r
+#endif \r
+ RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);\r
+ rk610_hdmi->init =0;\r
+ Rk610_hdmi_init(rk610_hdmi->client);\r
+ hdmi_changed(hdmi,1);\r
+ Rk610_hdmi_Set_Video(hdmi->resolution);\r
+ Rk610_hdmi_Set_Audio(hdmi->audio_fs);\r
+ Rk610_hdmi_Config_Done(rk610_hdmi->client);\r
+ return 0;\r
+}\r
+static struct hdmi_ops rk610_hdmi_ops = {\r
+ .set_param = rk610_hdmi_set_param,\r
+ .hdmi_precent = rk610_hdmi_precent,\r
+ .insert = rk610_hdmi_insert,\r
+ .remove = rk610_hdmi_remove,\r
+ .init = rk610_hdmi_init,\r
+};\r
+#ifdef CONFIG_RK610_DEBUG\r
+static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+\r
+static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+static ssize_t rk610_show_reg_attrs(struct device *dev,\r
+ struct device_attribute *attr,\r
+ char *buf)\r
+{\r
+\r
+ int i,size=0;\r
+ char val;\r
+ struct i2c_client *client=rk610_g_hdmi_client;\r
+\r
+ for(i=0;i<256;i++)\r
+ {\r
+ rk610_read_p0_reg(client, i, &val);\r
+ if(i%16==0)\r
+ size += sprintf(buf+size,"\n>>>rk610_hdmi %x:",i);\r
+ size += sprintf(buf+size," %2x",val);\r
+ }\r
+\r
+ return size;\r
+}\r
+static ssize_t rk610_store_reg_attrs(struct device *dev,\r
+ struct device_attribute *attr,\r
+ const char *buf, size_t size)\r
+{\r
+ struct i2c_client *client=NULL;\r
+ char val,reg,addr;\r
+ client = rk610_g_hdmi_client;\r
+ printk("/**********rk610 reg config******/");\r
+\r
+ sscanf(buf, "%x%x%x", &val,®,&addr);\r
+ printk("addr=%x ,reg=%x val=%x\n",addr,reg,val);\r
+ rk610_write_p0_reg(client, reg, &val);\r
+ printk("val=%x\n",val);\r
+ return size;\r
+}\r
+\r
+static struct device_attribute rk610_attrs[] = {\r
+ __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),\r
+};\r
+#endif\r
+#if 0\r
+static irqreturn_t rk610_hdmi_interrupt(int irq, void *dev_id)\r
+{\r
+ struct hdmi *hdmi = (struct hdmi *)dev_id;\r
+ unsigned long lock_flags = 0;\r
+ printk("The rk610_hdmi interrupt handeler is working..\n");\r
+ return IRQ_HANDLED;\r
+}\r
+#endif\r
+\r
+static int rk610_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)\r
+{\r
+ int ret = 0;\r
+ struct hdmi *hdmi = NULL;\r
+ struct rk610_hdmi_inf *rk610_hdmi = NULL;\r
+\r
+ struct hdmi_platform_data *pdata = client->dev.platform_data;\r
+ rk610_g_hdmi_client = client;\r
+ if(pdata && pdata->io_init)\r
+ {\r
+ printk("rk610_hdmi_i2c_probe io_init \n");\r
+ pdata->io_init();\r
+ }\r
+ hdmi = hdmi_register(sizeof(struct rk610_hdmi_inf), &client->dev);\r
+ if (!hdmi)\r
+ {\r
+ dev_err(&client->dev, "fail to register hdmi\n");\r
+ return -ENOMEM;\r
+ }\r
+ hdmi->ops = &rk610_hdmi_ops;\r
+ hdmi->display_on = HDMI_DEFAULT_MODE;\r
+ hdmi->hdcp_on = HDMI_DISABLE;\r
+ hdmi->audio_fs = HDMI_I2S_DEFAULT_Fs;\r
+ hdmi->resolution = HDMI_DEFAULT_RESOLUTION;\r
+ hdmi->dual_disp = DUAL_DISP_CAP;\r
+ hdmi->mode = DISP_ON_LCD;\r
+ hdmi->scale = 100;\r
+ hdmi->scale_set = 100;\r
+\r
+ rk610_hdmi = hdmi_priv(hdmi);\r
+ rk610_hdmi->init = 1;\r
+ rk610_hdmi->hdmi = hdmi;\r
+ i2c_set_clientdata(client, rk610_hdmi);\r
+ rk610_hdmi->client = client;\r
+ if((gpio_request(client->irq, "hdmi gpio")) < 0)\r
+ {\r
+ dev_err(&client->dev, "fail to request gpio %d\n", client->irq);\r
+ goto err_gpio_free;\r
+ }\r
+ rk610_hdmi->irq = gpio_to_irq(client->irq);\r
+ rk610_hdmi->gpio = client->irq;\r
+\r
+ gpio_direction_input(client->irq);\r
+ #if 0\r
+ if((ret = request_irq(rk610_hdmi->irq, rk610_hdmi_interrupt, IRQ_TYPE_EDGE_RISING,client->name, hdmi))<0){\r
+ RK610_ERR(&client->dev, "fail to request gpio %d\n", client->irq);\r
+ goto err_gpio_free;\r
+ }\r
+ #endif\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ rk610_hdmi->early_suspend.suspend = rk610_hdmi_early_suspend;\r
+ rk610_hdmi->early_suspend.resume = rk610_hdmi_early_resume;\r
+ rk610_hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;\r
+ register_early_suspend(&rk610_hdmi->early_suspend);\r
+#endif\r
+#ifdef CONFIG_RK610_DEBUG\r
+ device_create_file(&(client->dev), &rk610_attrs[0]);\r
+#endif\r
+ rk610_hdmi_init(rk610_hdmi->hdmi);\r
+ dev_info(&client->dev, "rk610_hdmi i2c probe ok\n");\r
+ return 0;\r
+err_gpio_free:\r
+ gpio_free(client->irq);\r
+err_hdmi_unregister:\r
+ hdmi_unregister(hdmi);\r
+ rk610_hdmi = NULL;\r
+ return ret;\r
+}\r
+\r
+static int __devexit rk610_hdmi_i2c_remove(struct i2c_client *client)\r
+{\r
+ struct rk610_hdmi_inf *rk610_hdmi = (struct rk610_hdmi_inf *)i2c_get_clientdata(client);\r
+ struct hdmi *hdmi = rk610_hdmi->hdmi;\r
+\r
+ gpio_free(client->irq);\r
+ hdmi_unregister(hdmi);\r
+ rk610_hdmi = NULL;\r
+ return 0;\r
+}\r
+static const struct i2c_device_id rk610_hdmi_id[] = {\r
+ { "rk610_hdmi", 0 },\r
+ { }\r
+};\r
+\r
+static struct i2c_driver rk610_hdmi_i2c_driver = {\r
+ .driver = {\r
+ .name = "rk610_hdmi",\r
+ },\r
+ .probe = &rk610_hdmi_i2c_probe,\r
+ .remove = &rk610_hdmi_i2c_remove,\r
+ .id_table = rk610_hdmi_id,\r
+};\r
+\r
+static int __init rk610_hdmi_module_init(void)\r
+{\r
+ return i2c_add_driver(&rk610_hdmi_i2c_driver);\r
+}\r
+\r
+static void __exit rk610_hdmi_module_exit(void)\r
+{\r
+ i2c_del_driver(&rk610_hdmi_i2c_driver);\r
+}\r
+\r
+late_initcall(rk610_hdmi_module_init);\r
+//module_init(rk610_hdmi_module_init);\r
+module_exit(rk610_hdmi_module_exit);\r
--- /dev/null
+#ifndef _RK610_H\r
+#define _RK610_H\r
+\r
+#include <linux/hdmi.h>
+#include <linux/earlysuspend.h>\r
+\r
+/************RK610 device addr***********/\r
+#define RK610_CTRL_ADDR 0x40\r
+#define RK610_TVE_ADDR 0x42\r
+#define RK610_HDMI_ADDR 0x46\r
+#define RK610_CODEC_ADDR 0xc0 // 0x11xxxxxx\r
+\r
+\r
+/****************HDMI STRUCT********************************/\r
+\r
+\r
+struct rk610_hdmi_inf{\r
+ int irq;\r
+ int gpio;\r
+ int init;\r
+ struct i2c_client *client;\r
+ struct hdmi *hdmi;\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ struct early_suspend early_suspend;
+#endif\r
+};\r
+\r
+/******************TVE STRUCT **************/\r
+\r
+/*************RK610 STRUCT**********************************/\r
+//struct rk610_pdata {\r
+// struct rk610_hdmi_inf hdmi;\r
+// struct rk610_lcd_info lcd;\r
+//};\r
+/*****************END ***********************************/\r
+#endif\r
--- /dev/null
+#include <linux/delay.h>\r
+#include <linux/mfd/rk610_core.h>\r
+#include "rk610_hdmi.h"\r
+#include "rk610_hdmi_hw.h"\r
+static struct rk610_hdmi_hw_inf g_hw_inf;\r
+static EDID_INF g_edid;\r
+static byte edid_buf[EDID_BLOCK_SIZE];\r
+static int RK610_hdmi_soft_reset(struct i2c_client *client);\r
+static int Rk610_hdmi_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+static int Rk610_hdmi_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+\r
+static int Rk610_hdmi_pwr_mode(struct i2c_client *client, int mode)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ switch(mode){\r
+ case NORMAL:\r
+ c=0x82;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe3, &c);\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe5, &c);\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe7, &c);\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe4, &c);\r
+ c=0x8e;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe1, &c);\r
+ break;\r
+ case LOWER_PWR:\r
+ c=0x02;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe3, &c);\r
+ c=0x1c;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe5, &c);\r
+ break;\r
+ case SHUTDOWN:\r
+ c=0x02;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe3, &c);\r
+ c=0x1c;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe5, &c);\r
+ c=0x04;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe7, &c);\r
+ c=0x03;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe4, &c);\r
+ c=0x8c;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe1, &c);\r
+ break;\r
+ default:\r
+ RK610_ERR(&client->dev,"unkown rk610 hdmi pwr mode %d\n",mode);\r
+ }\r
+ return ret;\r
+}\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+int Rk610_hdmi_suspend(struct i2c_client *client)\r
+{\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ ret = Rk610_hdmi_pwr_mode(client,SHUTDOWN);\r
+ return ret;\r
+}\r
+int Rk610_hdmi_resume(struct i2c_client *client)\r
+{\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev, "%s \n",__FUNCTION__);\r
+ ret = Rk610_hdmi_pwr_mode(client,NORMAL);\r
+ RK610_hdmi_soft_reset(client);\r
+ return ret;\r
+}\r
+#endif\r
+static int Rk610_hdmi_sys_power_down(struct i2c_client *client)\r
+{\r
+ char c = 0;\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ c= RK610_SYS_CLK<<2 |RK610_SYS_PWR_OFF<<1 |RK610_INT_POL;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x00, &c);\r
+ return ret;\r
+}\r
+static int Rk610_hdmi_sys_power_up(struct i2c_client *client)\r
+{\r
+ char c = 0;\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ c= RK610_SYS_CLK<<2 |RK610_SYS_PWR_ON<<1 |RK610_INT_POL;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x00, &c);\r
+ return ret;\r
+}\r
+//X=11.2896M/(4*100k), X = {0x4c,0x4b}\r
+static int RK610_DDC_BUS_CONFIG(struct i2c_client *client)\r
+{\r
+ char c = 0;\r
+ int ret = 0;\r
+ c= RK610_DDC_CONFIG&0xff;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x4b, &c);\r
+ c= (RK610_DDC_CONFIG>>8)&0xff;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x4c, &c);\r
+ return ret;\r
+}\r
+static int RK610_read_edid_block(struct i2c_client *client,u8 block, u8 * buf)\r
+{\r
+ char c = 0;\r
+ int ret = 0,i;\r
+ u8 Segment = 0;\r
+ u8 Offset = 0;\r
+ if(block%2)\r
+ Offset = EDID_BLOCK_SIZE;\r
+ if(block/2)\r
+ Segment = 1;\r
+ RK610_DBG(&client->dev,"EDID DATA (Segment = %d Block = %d Offset = %d):\n", (int) Segment, (int) block, (int) Offset);\r
+ //set edid fifo first addr\r
+ c = 0x00;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x4f, &c);\r
+ //set edid word address 00/80\r
+ c = Offset;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x4e, &c);\r
+ //set edid segment pointer\r
+ c = Segment;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x4d, &c);\r
+ \r
+ //enable edid interrupt\r
+ c=0xc6;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xc0, &c);\r
+ //wait edid interrupt\r
+ msleep(100);\r
+ RK610_DBG(&client->dev,"Interrupt generated\n");\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_read_p0_reg(client, 0xc1, &c);\r
+ RK610_DBG(&client->dev,"Interrupt reg=%x \n",c);\r
+ //clear EDID interrupt reg\r
+ c=0x04;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xc1, &c);\r
+ msleep(100);\r
+ for(i=0; i <EDID_BLOCK_SIZE;i++){\r
+ c = 0; \r
+ Rk610_hdmi_i2c_read_p0_reg(client, 0x50, &c);\r
+ buf[i] = c;\r
+ }\r
+ return ret;\r
+}\r
+#if 0\r
+//------------------------------------------------------------------------------\r
+// Function Name: Parse861ShortDescriptors()\r
+// Function Description: Parse CEA-861 extension short descriptors of the EDID block\r
+// passed as a parameter and save them in global structure g_edid.\r
+//\r
+// Accepts: A pointer to the EDID 861 Extension block being parsed.\r
+// Returns: EDID_PARSED_OK if EDID parsed correctly. Error code if failed.\r
+// Globals: EDID data\r
+// NOTE: Fields that are not supported by the 9022/4 (such as deep color) were not parsed.\r
+//------------------------------------------------------------------------------\r
+byte Parse861ShortDescriptors (byte *Data)\r
+{\r
+ byte LongDescriptorOffset;\r
+ byte DataBlockLength;\r
+ byte DataIndex;\r
+ byte ExtendedTagCode;\r
+ byte VSDB_BaseOffset = 0;\r
+\r
+ byte V_DescriptorIndex = 0; // static to support more than one extension\r
+ byte A_DescriptorIndex = 0; // static to support more than one extension\r
+\r
+ byte TagCode;\r
+\r
+ byte i;\r
+ byte j;\r
+\r
+ if (Data[EDID_TAG_ADDR] != EDID_EXTENSION_TAG)\r
+ {\r
+ RK610_HDMI_ERR("EDID -> Extension Tag Error\n");\r
+ return EDID_EXT_TAG_ERROR;\r
+ }\r
+\r
+ if (Data[EDID_REV_ADDR] != EDID_REV_THREE)\r
+ {\r
+ RK610_HDMI_ERR("EDID -> Revision Error\n"));\r
+ return EDID_REV_ADDR_ERROR;\r
+ }\r
+\r
+ LongDescriptorOffset = Data[LONG_DESCR_PTR_IDX]; // block offset where long descriptors start\r
+\r
+ g_edid.UnderScan = ((Data[MISC_SUPPORT_IDX]) >> 7) & LSBIT; // byte #3 of CEA extension version 3\r
+ g_edid.BasicAudio = ((Data[MISC_SUPPORT_IDX]) >> 6) & LSBIT;\r
+ g_edid.YCbCr_4_4_4 = ((Data[MISC_SUPPORT_IDX]) >> 5) & LSBIT;\r
+ g_edid.YCbCr_4_2_2 = ((Data[MISC_SUPPORT_IDX]) >> 4) & LSBIT;\r
+\r
+ DataIndex = EDID_DATA_START; // 4\r
+\r
+ while (DataIndex < LongDescriptorOffset)\r
+ {\r
+ TagCode = (Data[DataIndex] >> 5) & THREE_LSBITS;\r
+ DataBlockLength = Data[DataIndex++] & FIVE_LSBITS;\r
+ if ((DataIndex + DataBlockLength) > LongDescriptorOffset)\r
+ {\r
+ RK610_HDMI_ERR("EDID -> V Descriptor Overflow\n");\r
+ return EDID_V_DESCR_OVERFLOW;\r
+ }\r
+\r
+ i = 0; // num of short video descriptors in current data block\r
+\r
+ switch (TagCode)\r
+ {\r
+ case VIDEO_D_BLOCK:\r
+ while ((i < DataBlockLength) && (i < MAX_V_DESCRIPTORS)) // each SVD is 1 byte long\r
+ {\r
+ g_edid.VideoDescriptor[V_DescriptorIndex++] = Data[DataIndex++];\r
+ i++;\r
+ }\r
+ DataIndex += DataBlockLength - i; // if there are more STDs than MAX_V_DESCRIPTORS, skip the last ones. Update DataIndex\r
+\r
+ RK610_RK610_DBG(&client->dev,"EDID -> Short Descriptor Video Block\n");\r
+ break;\r
+\r
+ case AUDIO_D_BLOCK:\r
+ while (i < DataBlockLength/3) // each SAD is 3 bytes long\r
+ {\r
+ j = 0;\r
+ while (j < AUDIO_DESCR_SIZE) // 3\r
+ {\r
+ g_edid.AudioDescriptor[A_DescriptorIndex][j++] = Data[DataIndex++];\r
+ }\r
+ A_DescriptorIndex++;\r
+ i++;\r
+ }\r
+ RK610_HDMI_DBG("EDID -> Short Descriptor Audio Block\n");\r
+ break;\r
+\r
+ case SPKR_ALLOC_D_BLOCK:\r
+ g_edid.SpkrAlloc[i++] = Data[DataIndex++]; // although 3 bytes are assigned to Speaker Allocation, only\r
+ DataIndex += 2; // the first one carries information, so the next two are ignored by this code.\r
+ RK610_HDMI_DBG("EDID -> Short Descriptor Speaker Allocation Block\n");\r
+ break;\r
+\r
+ case USE_EXTENDED_TAG:\r
+ ExtendedTagCode = Data[DataIndex++];\r
+\r
+ switch (ExtendedTagCode)\r
+ {\r
+ case VIDEO_CAPABILITY_D_BLOCK:\r
+ RK610_HDMI_DBG("EDID -> Short Descriptor Video Capability Block\n");\r
+\r
+ // TO BE ADDED HERE: Save "video capability" parameters in g_edid data structure\r
+ // Need to modify that structure definition\r
+ // In the meantime: just increment DataIndex by 1\r
+ DataIndex += 1; // replace with reading and saving the proper data per CEA-861 sec. 7.5.6 while incrementing DataIndex\r
+ break;\r
+\r
+ case COLORIMETRY_D_BLOCK:\r
+ g_edid.ColorimetrySupportFlags = Data[DataIndex++] & BITS_1_0;\r
+ g_edid.MetadataProfile = Data[DataIndex++] & BITS_2_1_0;\r
+\r
+ RK610_HDMI_DBG("EDID -> Short Descriptor Colorimetry Block\n");\r
+ break;\r
+ }\r
+ break;\r
+\r
+ case VENDOR_SPEC_D_BLOCK:\r
+ VSDB_BaseOffset = DataIndex - 1;\r
+\r
+ if ((Data[DataIndex++] == 0x03) && // check if sink is HDMI compatible\r
+ (Data[DataIndex++] == 0x0C) &&\r
+ (Data[DataIndex++] == 0x00))\r
+\r
+ g_edid.RK610_HDMI_Sink = TRUE;\r
+ else\r
+ g_edid.RK610_HDMI_Sink = FALSE;\r
+\r
+ g_edid.CEC_A_B = Data[DataIndex++]; // CEC Physical address\r
+ g_edid.CEC_C_D = Data[DataIndex++];\r
+\r
+#ifdef DEV_SUPPORT_CEC\r
+ // Take the Address that was passed in the EDID and use this API\r
+ // to set the physical address for CEC.\r
+ {\r
+ word phyAddr;\r
+ phyAddr = (word)g_edid.CEC_C_D; // Low-order nibbles\r
+ phyAddr |= ((word)g_edid.CEC_A_B << 8); // Hi-order nibbles\r
+ // Is the new PA different from the current PA?\r
+ if (phyAddr != SI_CecGetDevicePA ())\r
+ {\r
+ // Yes! So change the PA\r
+ SI_CecSetDevicePA (phyAddr);\r
+ }\r
+ }\r
+#endif\r
+\r
+ if ((DataIndex + 7) > VSDB_BaseOffset + DataBlockLength) // Offset of 3D_Present bit in VSDB\r
+ g_edid._3D_Supported = FALSE;\r
+ else if (Data[DataIndex + 7] >> 7)\r
+ g_edid._3D_Supported = TRUE;\r
+ else\r
+ g_edid._3D_Supported = FALSE;\r
+\r
+ DataIndex += DataBlockLength - RK610_HDMI_SIGNATURE_LEN - CEC_PHYS_ADDR_LEN; // Point to start of next block\r
+ RK610_HDMI_DBG("EDID -> Short Descriptor Vendor Block\n");\r
+ break;\r
+\r
+ default:\r
+ RK610_HDMI_DBG("EDID -> Unknown Tag Code\n");\r
+ return EDID_UNKNOWN_TAG_CODE;\r
+\r
+ } // End, Switch statement\r
+ } // End, while (DataIndex < LongDescriptorOffset) statement\r
+\r
+ return EDID_SHORT_DESCRIPTORS_OK;\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+// Function Name: Parse861LongDescriptors()\r
+// Function Description: Parse CEA-861 extension long descriptors of the EDID block\r
+// passed as a parameter and printf() them to the screen.\r
+//\r
+// Accepts: A pointer to the EDID block being parsed\r
+// Returns: An error code if no long descriptors found; EDID_PARSED_OK if descriptors found.\r
+// Globals: none\r
+//------------------------------------------------------------------------------\r
+byte Parse861LongDescriptors (byte *Data)\r
+{\r
+ byte LongDescriptorsOffset;\r
+ byte DescriptorNum = 1;\r
+\r
+ LongDescriptorsOffset = Data[LONG_DESCR_PTR_IDX]; // EDID block offset 2 holds the offset\r
+\r
+ if (!LongDescriptorsOffset) // per CEA-861-D, table 27\r
+ {\r
+ TPI_DEBUG_PRINT(("EDID -> No Detailed Descriptors\n"));\r
+ return EDID_NO_DETAILED_DESCRIPTORS;\r
+ }\r
+\r
+ // of the 1st 18-byte descriptor\r
+ while (LongDescriptorsOffset + LONG_DESCR_LEN < EDID_BLOCK_SIZE)\r
+ {\r
+ TPI_EDID_PRINT(("Parse Results - CEA-861 Long Descriptor #%d:\n", (int) DescriptorNum));\r
+ TPI_EDID_PRINT(("===============================================================\n"));\r
+\r
+#if (CONF__TPI_EDID_PRINT == ENABLE)\r
+ if (!ParseDetailedTiming(Data, LongDescriptorsOffset, EDID_BLOCK_2_3))\r
+ break;\r
+#endif\r
+ LongDescriptorsOffset += LONG_DESCR_LEN;\r
+ DescriptorNum++;\r
+ }\r
+\r
+ return EDID_LONG_DESCRIPTORS_OK;\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+// Function Name: Parse861Extensions()\r
+// Function Description: Parse CEA-861 extensions from EDID ROM (EDID blocks beyond\r
+// block #0). Save short descriptors in global structure\r
+// g_edid. printf() long descriptors to the screen.\r
+//\r
+// Accepts: The number of extensions in the EDID being parsed\r
+// Returns: EDID_PARSED_OK if EDID parsed correctly. Error code if failed.\r
+// Globals: EDID data\r
+// NOTE: Fields that are not supported by the 9022/4 (such as deep color) were not parsed.\r
+//------------------------------------------------------------------------------\r
+byte Parse861Extensions (struct i2c_client *client,byte NumOfExtensions)\r
+{\r
+ byte i,j,k;\r
+ \r
+ byte ErrCode;\r
+ \r
+// byte V_DescriptorIndex = 0;\r
+// byte A_DescriptorIndex = 0;\r
+ \r
+ byte Block = 0;\r
+ \r
+ g_edid.HDMI_Sink = FALSE;\r
+\r
+ do\r
+ {\r
+ Block++;\r
+ HDMI_DBG("\n");\r
+ \r
+ for (j=0, i=0; j<128; j++)\r
+ {\r
+ k = edid_buf[j];\r
+ HDMI_DBG("%2.2X ", (int) k);\r
+ i++;\r
+ \r
+ if (i == 0x10)\r
+ {\r
+ HDMI_DBG("\n");\r
+ i = 0;\r
+ }\r
+ }\r
+ HDMI_DBG("\n");\r
+ RK610_read_edid_block(client,Block, edid_buf);\r
+ if ((NumOfExtensions > 1) && (Block == 1))\r
+ {\r
+ continue;\r
+ }\r
+ \r
+ ErrCode = Parse861ShortDescriptors(edid_buf);\r
+ if (ErrCode != EDID_SHORT_DESCRIPTORS_OK)\r
+ {\r
+ return ErrCode;\r
+ }\r
+ \r
+ ErrCode = Parse861LongDescriptors(edid_buf);\r
+ if (ErrCode != EDID_LONG_DESCRIPTORS_OK)\r
+ {\r
+ return ErrCode;\r
+ }\r
+ \r
+ } while (Block < NumOfExtensions);\r
+\r
+ return EDID_OK;\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+// Function Name: ParseEDID()\r
+// Function Description: Extract sink properties from its EDID file and save them in\r
+// global structure g_edid.\r
+//\r
+// Accepts: none\r
+// Returns: TRUE or FLASE\r
+// Globals: EDID data\r
+// NOTE: Fields that are not supported by the 9022/4 (such as deep color) were not parsed.\r
+//------------------------------------------------------------------------------\r
+static byte ParseEDID (byte *pEdid, byte *numExt)\r
+{\r
+ if (!CheckEDID_Header(pEdid))\r
+ {\r
+ // first 8 bytes of EDID must be {0, FF, FF, FF, FF, FF, FF, 0}\r
+ HDMI_ERR("EDID -> Incorrect Header\n");\r
+ return EDID_INCORRECT_HEADER;\r
+ }\r
+\r
+ if (!DoEDID_Checksum(pEdid))\r
+ {\r
+ // non-zero EDID checksum\r
+ HDMI_ERR("EDID -> Checksum Error\n");\r
+ return EDID_CHECKSUM_ERROR;\r
+ }\r
+\r
+ *numExt = pEdid[NUM_OF_EXTEN_ADDR]; // read # of extensions from offset 0x7E of block 0\r
+ HDMI_DBG("EDID -> 861 Extensions = %d\n", (int) *numExt);\r
+\r
+ if (!(*numExt))\r
+ {\r
+ // No extensions to worry about\r
+ HDMI_DBG("EDID -> EDID_NO_861_EXTENSIONS\n");\r
+ return EDID_NO_861_EXTENSIONS;\r
+ }\r
+ return EDID_OK;\r
+}\r
+#endif\r
+\r
+//------------------------------------------------------------------------------\r
+// Function Name: CheckEDID_Header()\r
+// Function Description: Checks if EDID header is correct per VESA E-EDID standard\r
+//\r
+// Accepts: Pointer to 1st EDID block\r
+// Returns: TRUE or FLASE\r
+// Globals: EDID data\r
+//------------------------------------------------------------------------------\r
+byte CheckEDID_Header (byte *Block)\r
+{\r
+ byte i = 0;\r
+\r
+ if (Block[i]) // byte 0 must be 0\r
+ return FALSE;\r
+\r
+ for (i = 1; i < 1 + EDID_HDR_NO_OF_FF; i++)\r
+ {\r
+ if(Block[i] != 0xFF) // bytes [1..6] must be 0xFF\r
+ return FALSE;\r
+ }\r
+\r
+ if (Block[i]) // byte 7 must be 0\r
+ return FALSE;\r
+\r
+ return TRUE;\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+// Function Name: DoEDID_Checksum()\r
+// Function Description: Calculte checksum of the 128 byte block pointed to by the\r
+// pointer passed as parameter\r
+//\r
+// Accepts: Pointer to a 128 byte block whose checksum needs to be calculated\r
+// Returns: TRUE or FLASE\r
+// Globals: EDID data\r
+//------------------------------------------------------------------------------\r
+byte DoEDID_Checksum (byte *Block)\r
+{\r
+ byte i;\r
+ byte CheckSum = 0;\r
+\r
+ for (i = 0; i < EDID_BLOCK_SIZE; i++)\r
+ CheckSum += Block[i];\r
+\r
+ if (CheckSum)\r
+ return FALSE;\r
+\r
+ return TRUE;\r
+}\r
+//------------------------------------------------------------------------------\r
+// Function Name: Parse861ShortDescriptors()\r
+// Function Description: Parse CEA-861 extension short descriptors of the EDID block\r
+// passed as a parameter and save them in global structure g_edid.\r
+//\r
+// Accepts: A pointer to the EDID 861 Extension block being parsed.\r
+// Returns: EDID_PARSED_OK if EDID parsed correctly. Error code if failed.\r
+// Globals: EDID data\r
+// NOTE: Fields that are not supported by the 9022/4 (such as deep color) were not parsed.\r
+//------------------------------------------------------------------------------\r
+byte Parse861ShortDescriptors (struct i2c_client *client,byte *Data)\r
+{\r
+ byte LongDescriptorOffset;\r
+ byte DataBlockLength;\r
+ byte DataIndex;\r
+ byte ExtendedTagCode;\r
+ byte VSDB_BaseOffset = 0;\r
+\r
+ byte V_DescriptorIndex = 0; // static to support more than one extension\r
+ byte A_DescriptorIndex = 0; // static to support more than one extension\r
+\r
+ byte TagCode;\r
+\r
+ byte i;\r
+ byte j;\r
+\r
+ if (Data[EDID_TAG_ADDR] != EDID_EXTENSION_TAG)\r
+ {\r
+ RK610_ERR(&client->dev,"EDID -> Extension Tag Error\n");\r
+ return EDID_EXT_TAG_ERROR;\r
+ }\r
+\r
+ if (Data[EDID_REV_ADDR] != EDID_REV_THREE)\r
+ {\r
+ RK610_ERR(&client->dev,"EDID -> Revision Error\n");\r
+ return EDID_REV_ADDR_ERROR;\r
+ }\r
+\r
+ LongDescriptorOffset = Data[LONG_DESCR_PTR_IDX]; // block offset where long descriptors start\r
+\r
+ g_edid.UnderScan = ((Data[MISC_SUPPORT_IDX]) >> 7) & LSBIT; // byte #3 of CEA extension version 3\r
+ g_edid.BasicAudio = ((Data[MISC_SUPPORT_IDX]) >> 6) & LSBIT;\r
+ g_edid.YCbCr_4_4_4 = ((Data[MISC_SUPPORT_IDX]) >> 5) & LSBIT;\r
+ g_edid.YCbCr_4_2_2 = ((Data[MISC_SUPPORT_IDX]) >> 4) & LSBIT;\r
+\r
+ DataIndex = EDID_DATA_START; // 4\r
+\r
+ while (DataIndex < LongDescriptorOffset)\r
+ {\r
+ TagCode = (Data[DataIndex] >> 5) & THREE_LSBITS;\r
+ DataBlockLength = Data[DataIndex++] & FIVE_LSBITS;\r
+ if ((DataIndex + DataBlockLength) > LongDescriptorOffset)\r
+ {\r
+ RK610_ERR(&client->dev,"EDID -> V Descriptor Overflow\n");\r
+ return EDID_V_DESCR_OVERFLOW;\r
+ }\r
+\r
+ i = 0; // num of short video descriptors in current data block\r
+\r
+ switch (TagCode)\r
+ {\r
+ case VIDEO_D_BLOCK:\r
+ while ((i < DataBlockLength) && (i < MAX_V_DESCRIPTORS)) // each SVD is 1 byte long\r
+ {\r
+ g_edid.VideoDescriptor[V_DescriptorIndex++] = Data[DataIndex++];\r
+ i++;\r
+ }\r
+ DataIndex += DataBlockLength - i; // if there are more STDs than MAX_V_DESCRIPTORS, skip the last ones. Update DataIndex\r
+\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Video Block\n");\r
+ break;\r
+\r
+ case AUDIO_D_BLOCK:\r
+ while (i < DataBlockLength/3) // each SAD is 3 bytes long\r
+ {\r
+ j = 0;\r
+ while (j < AUDIO_DESCR_SIZE) // 3\r
+ {\r
+ g_edid.AudioDescriptor[A_DescriptorIndex][j++] = Data[DataIndex++];\r
+ }\r
+ A_DescriptorIndex++;\r
+ i++;\r
+ }\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Audio Block\n");\r
+ break;\r
+\r
+ case SPKR_ALLOC_D_BLOCK:\r
+ g_edid.SpkrAlloc[i++] = Data[DataIndex++]; // although 3 bytes are assigned to Speaker Allocation, only\r
+ DataIndex += 2; // the first one carries information, so the next two are ignored by this code.\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Speaker Allocation Block\n");\r
+ break;\r
+\r
+ case USE_EXTENDED_TAG:\r
+ ExtendedTagCode = Data[DataIndex++];\r
+\r
+ switch (ExtendedTagCode)\r
+ {\r
+ case VIDEO_CAPABILITY_D_BLOCK:\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Video Capability Block\n");\r
+\r
+ // TO BE ADDED HERE: Save "video capability" parameters in g_edid data structure\r
+ // Need to modify that structure definition\r
+ // In the meantime: just increment DataIndex by 1\r
+ DataIndex += 1; // replace with reading and saving the proper data per CEA-861 sec. 7.5.6 while incrementing DataIndex\r
+ break;\r
+\r
+ case COLORIMETRY_D_BLOCK:\r
+ g_edid.ColorimetrySupportFlags = Data[DataIndex++] & BITS_1_0;\r
+ g_edid.MetadataProfile = Data[DataIndex++] & BITS_2_1_0;\r
+\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Colorimetry Block\n");\r
+ break;\r
+ }\r
+ break;\r
+\r
+ case VENDOR_SPEC_D_BLOCK:\r
+ VSDB_BaseOffset = DataIndex - 1;\r
+\r
+ if ((Data[DataIndex++] == 0x03) && // check if sink is HDMI compatible\r
+ (Data[DataIndex++] == 0x0C) &&\r
+ (Data[DataIndex++] == 0x00))\r
+\r
+ g_edid.HDMI_Sink = TRUE;\r
+ else\r
+ g_edid.HDMI_Sink = FALSE;\r
+\r
+ g_edid.CEC_A_B = Data[DataIndex++]; // CEC Physical address\r
+ g_edid.CEC_C_D = Data[DataIndex++];\r
+\r
+#ifdef DEV_SUPPORT_CEC\r
+ // Take the Address that was passed in the EDID and use this API\r
+ // to set the physical address for CEC.\r
+ {\r
+ word phyAddr;\r
+ phyAddr = (word)g_edid.CEC_C_D; // Low-order nibbles\r
+ phyAddr |= ((word)g_edid.CEC_A_B << 8); // Hi-order nibbles\r
+ // Is the new PA different from the current PA?\r
+ if (phyAddr != SI_CecGetDevicePA ())\r
+ {\r
+ // Yes! So change the PA\r
+ SI_CecSetDevicePA (phyAddr);\r
+ }\r
+ }\r
+#endif\r
+\r
+ if ((DataIndex + 7) > VSDB_BaseOffset + DataBlockLength) // Offset of 3D_Present bit in VSDB\r
+ g_edid._3D_Supported = FALSE;\r
+ else if (Data[DataIndex + 7] >> 7)\r
+ g_edid._3D_Supported = TRUE;\r
+ else\r
+ g_edid._3D_Supported = FALSE;\r
+\r
+ DataIndex += DataBlockLength - HDMI_SIGNATURE_LEN - CEC_PHYS_ADDR_LEN; // Point to start of next block\r
+ RK610_DBG(&client->dev,"EDID -> Short Descriptor Vendor Block\n");\r
+ break;\r
+\r
+ default:\r
+ RK610_ERR(&client->dev,"EDID -> Unknown Tag Code\n");\r
+ return EDID_UNKNOWN_TAG_CODE;\r
+\r
+ } // End, Switch statement\r
+ } // End, while (DataIndex < LongDescriptorOffset) statement\r
+\r
+ return EDID_SHORT_DESCRIPTORS_OK;\r
+}\r
+//------------------------------------------------------------------------------\r
+// Function Name: ParseEDID()\r
+// Function Description: Extract sink properties from its EDID file and save them in\r
+// global structure g_edid.\r
+//\r
+// Accepts: none\r
+// Returns: TRUE or FLASE\r
+// Globals: EDID data\r
+// NOTE: Fields that are not supported by the 9022/4 (such as deep color) were not parsed.\r
+//------------------------------------------------------------------------------\r
+static byte ParseEDID (struct i2c_client *client,byte *pEdid, byte *numExt)\r
+{\r
+ if (!CheckEDID_Header(pEdid))\r
+ {\r
+ // first 8 bytes of EDID must be {0, FF, FF, FF, FF, FF, FF, 0}\r
+ RK610_ERR(&client->dev,"EDID -> Incorrect Header\n");\r
+ return EDID_INCORRECT_HEADER;\r
+ }\r
+\r
+ if (!DoEDID_Checksum(pEdid))\r
+ {\r
+ // non-zero EDID checksum\r
+ RK610_ERR(&client->dev,"EDID -> Checksum Error\n");\r
+ return EDID_CHECKSUM_ERROR;\r
+ }\r
+\r
+ *numExt = pEdid[NUM_OF_EXTEN_ADDR]; // read # of extensions from offset 0x7E of block 0\r
+ RK610_DBG(&client->dev,"EDID -> 861 Extensions = %d\n", (int) *numExt);\r
+\r
+ if (!(*numExt))\r
+ {\r
+ // No extensions to worry about\r
+ RK610_DBG(&client->dev,"EDID -> EDID_NO_861_EXTENSIONS\n");\r
+ return EDID_NO_861_EXTENSIONS;\r
+ }\r
+ return EDID_OK;\r
+}\r
+byte DoEdidRead (struct i2c_client *client)\r
+{\r
+ u8 NumOfExtensions=0;\r
+ u8 Result;\r
+ u8 i,j;\r
+ // If we already have valid EDID data, ship this whole thing\r
+ if (g_edid.edidDataValid == FALSE)\r
+ {\r
+ Rk610_hdmi_sys_power_up(client);\r
+ // Request access to DDC bus from the receiver\r
+ RK610_DDC_BUS_CONFIG(client);\r
+ memset(edid_buf,0,EDID_BLOCK_SIZE);\r
+ RK610_read_edid_block(client,EDID_BLOCK0, edid_buf); // read first 128 bytes of EDID ROM\r
+ RK610_DBG(&client->dev,"/************first block*******/\n");\r
+ for (j=0; j<EDID_BLOCK_SIZE; j++)\r
+ {\r
+ if(j%16==0)\r
+ printk("\n%x :",j);\r
+ printk("%2.2x ", edid_buf[j]);\r
+ }\r
+ Result = ParseEDID(client,edid_buf, &NumOfExtensions);\r
+ if(Result!=EDID_OK){\r
+ if(Result==EDID_NO_861_EXTENSIONS){\r
+ g_edid.HDMI_Sink = FALSE;\r
+ }\r
+ else{\r
+ g_edid.HDMI_Sink = TRUE;\r
+ }\r
+ }\r
+ else{\r
+ g_edid.HDMI_Sink = TRUE;\r
+ }\r
+ NumOfExtensions = edid_buf[NUM_OF_EXTEN_ADDR];\r
+ for(i=1;i<=NumOfExtensions;i++){\r
+ RK610_DBG(&client->dev,"\n/************block %d*******/\n",i);\r
+ memset(edid_buf,0,EDID_BLOCK_SIZE);\r
+ RK610_read_edid_block(client,i, edid_buf); \r
+ Parse861ShortDescriptors(client,edid_buf);\r
+ for (j=0; j<EDID_BLOCK_SIZE; j++)\r
+ {\r
+ if(j%16==0)\r
+ printk("\n%x :",j);\r
+ printk("%2.2X ", edid_buf[j]);\r
+ }\r
+ }\r
+#if 0\r
+ Result = ParseEDID(edid_buf, &NumOfExtensions);\r
+ if (Result != EDID_OK)\r
+ {\r
+ if (Result == EDID_NO_861_EXTENSIONS)\r
+ {\r
+ RK610_DBG(&client->dev,"EDID -> No 861 Extensions\n");\r
+ g_edid.HDMI_Sink = FALSE;\r
+ g_edid.YCbCr_4_4_4 = FALSE;\r
+ g_edid.YCbCr_4_2_2 = FALSE;\r
+ g_edid.CEC_A_B = 0x00;\r
+ g_edid.CEC_C_D = 0x00;\r
+ }\r
+ else\r
+ {\r
+ RK610_DBG(&client->dev,"EDID -> Parse FAILED\n");\r
+ g_edid.HDMI_Sink = TRUE;\r
+ g_edid.YCbCr_4_4_4 = FALSE;\r
+ g_edid.YCbCr_4_2_2 = FALSE;\r
+ g_edid.CEC_A_B = 0x00;\r
+ g_edid.CEC_C_D = 0x00;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ RK610_DBG(&client->dev,"EDID -> Parse OK\n");\r
+ Result = Parse861Extensions(NumOfExtensions); // Parse 861 Extensions (short and long descriptors);\r
+ if (Result != EDID_OK)\r
+ {\r
+ RK610_DBG(&client->dev,"EDID -> Extension Parse FAILED\n");\r
+ g_edid.HDMI_Sink = FALSE;\r
+ g_edid.YCbCr_4_4_4 = FALSE;\r
+ g_edid.YCbCr_4_2_2 = FALSE;\r
+ g_edid.CEC_A_B = 0x00;\r
+ g_edid.CEC_C_D = 0x00;\r
+ }\r
+ else\r
+ {\r
+ RK610_DBG(&client->dev,"EDID -> Extension Parse OK\n");\r
+ g_edid.HDMI_Sink = TRUE;\r
+ }\r
+ }\r
+#endif\r
+ RK610_DBG(&client->dev,"EDID -> NumOfExtensions = %d\n", NumOfExtensions);\r
+ RK610_DBG(&client->dev,"EDID -> g_edid.HDMI_Sink = %d\n", (int)g_edid.HDMI_Sink);\r
+ //RK610_DBG(&client->dev,"EDID -> g_edid.YCbCr_4_4_4 = %d\n", (int)g_edid.YCbCr_4_4_4);\r
+ //RK610_DBG(&client->dev,"EDID -> g_edid.YCbCr_4_2_2 = %d\n", (int)g_edid.YCbCr_4_2_2);\r
+ //RK610_DBG(&client->dev,"EDID -> g_edid.CEC_A_B = 0x%x\n", (int)g_edid.CEC_A_B);\r
+ //RK610_DBG(&client->dev,"EDID -> g_edid.CEC_C_D = 0x%x\n", (int)g_edid.CEC_C_D);\r
+\r
+ g_edid.edidDataValid = TRUE;\r
+ }\r
+ return TRUE;\r
+}\r
+static int Rk610_hdmi_Display_switch(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ int mode;\r
+ mode = (g_edid.HDMI_Sink == TRUE)? DISPLAY_HDMI:DISPLAY_DVI;\r
+ ret = Rk610_hdmi_i2c_read_p0_reg(client, 0x52, &c);\r
+ c &= ((~(1<<1))| mode<<1);\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x52, &c);\r
+ RK610_DBG(&client->dev,">>>%s mode=%d,c=%x",__func__,mode,c);\r
+ return ret;\r
+}\r
+\r
+static int Rk610_hdmi_Config_audio_informat(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ //Select configure for Audio Info\r
+ c=0x08;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x9f, &c);\r
+ //Configure the Audio info to HDMI RX.\r
+ c=0x84; //HB0\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa0, &c);\r
+ c=0x01; //HB1\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa1, &c);\r
+ c=0x0a; //HB2\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa2, &c);\r
+ //c=0x00; //PB0\r
+ //ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa3, &c);\r
+ c=0x11; //PB1\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa4, &c);\r
+ c=0x09; //PB2\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa5, &c);\r
+ c=0x00; //PB3\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa6, &c);\r
+ c=0x00; //PB4\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa7, &c);\r
+ c=0x01; //PB5\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa8, &c);\r
+ return ret;\r
+}\r
+\r
+static int Rk610_hdmi_Config_Avi_informat(struct i2c_client *client ,u8 vic)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ //Select configure for AVI Info\r
+ c = 0x06; \r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x9f, &c);\r
+\r
+ //Configure the AVI info to HDMI RX\r
+ c = 0x82; //HB0\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa0, &c);\r
+ c = 0x02; //HB1\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa1, &c);\r
+ c = 0x0d; //HB2\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa2, &c);\r
+ //c=0x00; //PB0\r
+ //ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa3, &c);\r
+ c = 0x00; //PB1\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa4, &c);\r
+ c = 0x08; //PB2\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa5, &c);\r
+ c = 0x70; //PB3\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa6, &c);\r
+ c = vic; //PB4\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa7, &c);\r
+ c = 0x40; //PB5\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0xa8, &c);\r
+ return ret;\r
+}\r
+static int Rk610_hdmi_Config_Video(struct i2c_client *client, u8 video_format)\r
+{\r
+ char vic;\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ switch(video_format){\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ vic = 0x02;\r
+ break;\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ vic = 0x11;\r
+ break;\r
+ case HDMI_1280x720p_50Hz:\r
+ vic = 0x13;\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ vic = 0x04;\r
+ break;\r
+ case HDMI_1920x1080p_50Hz:\r
+ vic = 0x1f;\r
+ break;\r
+ case HDMI_1920x1080p_60Hz:\r
+ vic = 0x10;\r
+ break;\r
+ default:\r
+ vic = 0x04;\r
+ break;\r
+ }\r
+ ret = Rk610_hdmi_Config_Avi_informat(client,vic);\r
+ return ret;\r
+}\r
+static int Rk610_hdmi_Config_Audio(struct i2c_client *client ,u8 audio_fs)\r
+{\r
+ char c=0;\r
+ int ret = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ c=0x01;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x35, &c);\r
+ c=0x3c;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x38, &c);\r
+ c=0x00;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x39, &c);\r
+ c=0x18;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x40, &c);\r
+ switch(audio_fs){\r
+ case HDMI_I2S_Fs_44100:\r
+ c=0x80;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x41, &c);\r
+ break;\r
+ case HDMI_I2S_Fs_48000:\r
+ c=0x92;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x41, &c);\r
+ break;\r
+ default:\r
+ c=0x80;\r
+ ret = Rk610_hdmi_i2c_write_p0_reg(client, 0x41, &c);\r
+ break;\r
+ }\r
+ Rk610_hdmi_Config_audio_informat(client);\r
+ return ret;\r
+}\r
+\r
+int Rk610_hdmi_Set_Video(u8 video_format)\r
+{\r
+ if(g_hw_inf.video_format !=video_format){\r
+ g_hw_inf.video_format = video_format;\r
+ g_hw_inf.config_param |= VIDEO_CHANGE;\r
+ }\r
+ return 0;\r
+}\r
+int Rk610_hdmi_Set_Audio(u8 audio_fs)\r
+{\r
+ if(g_hw_inf.audio_fs !=audio_fs){\r
+ g_hw_inf.audio_fs = audio_fs;\r
+ g_hw_inf.config_param |= AUDIO_CHANGE;\r
+ }\r
+ return 0;\r
+}\r
+static int RK610_hdmi_Driver_mode(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ c=0x8e;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe1, &c);\r
+ c=0x04;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe2, &c);\r
+ return 0;\r
+}\r
+static int RK610_hdmi_PLL_mode(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ c=0x10;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe8, &c);\r
+ c=0x2c;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe6, &c);\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xe5, &c);\r
+ return 0;\r
+}\r
+void Rk610_hdmi_event_work(struct i2c_client *client, bool *hpd)\r
+{\r
+ char c=0;\r
+ int ret=0;\r
+\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_read_p0_reg(client, 0xc1, &c);\r
+ if(c & RK610_HPD_EVENT){\r
+ RK610_DBG(&client->dev,">>>HPD EVENT\n");\r
+ /**********clear hpd event******/\r
+ c=RK610_HPD_EVENT;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xc1, &c);\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_read_p0_reg(client, 0xc8, &c);\r
+ if(c & RK610_HPD_PLUG ){\r
+ RK610_DBG(&client->dev,">>> hdmi plug \n");\r
+ DoEdidRead(client);\r
+ Rk610_hdmi_Display_switch(client);\r
+ Rk610_hdmi_pwr_mode(client,NORMAL);\r
+ *hpd=1;\r
+ }\r
+ else{\r
+ RK610_DBG(&client->dev,">>> hdmi unplug \n");\r
+ g_edid.edidDataValid = FALSE;\r
+ Rk610_hdmi_pwr_mode(client,LOWER_PWR);\r
+ *hpd=0;\r
+ }\r
+\r
+ }\r
+ if(c & RK610_EDID_EVENT){\r
+ /**********clear hpd event******/\r
+ c=RK610_EDID_EVENT;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0xc1, &c);\r
+ RK610_DBG(&client->dev,">>>EDID EVENT\n");\r
+ /*************clear edid event*********/\r
+ }\r
+}\r
+int Rk610_hdmi_Config_Done(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+\r
+ ret =Rk610_hdmi_sys_power_up(client);\r
+\r
+ if(g_hw_inf.config_param != 0){\r
+ c=0x08;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x04, &c);\r
+ c=0x01;\r
+ ret =Rk610_hdmi_i2c_write_p0_reg(client, 0x01, &c);\r
+ if(g_hw_inf.config_param & VIDEO_CHANGE){\r
+ Rk610_hdmi_Config_Video(client,g_hw_inf.video_format);\r
+ g_hw_inf.config_param &= (~VIDEO_CHANGE); \r
+ }\r
+ if(g_hw_inf.config_param & AUDIO_CHANGE){\r
+ Rk610_hdmi_Config_Audio(client,g_hw_inf.audio_fs);\r
+ g_hw_inf.config_param &= (~AUDIO_CHANGE); \r
+ }\r
+ }\r
+ ret =Rk610_hdmi_sys_power_down(client);\r
+ ret =Rk610_hdmi_sys_power_up(client);\r
+ ret =Rk610_hdmi_sys_power_down(client);\r
+\r
+ return ret;\r
+}\r
+#if 0\r
+int Rk610_hdmi_hpd(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ if(Rk610_hdmi_i2c_read_p0_reg(client, 0xc8, &c)<0){\r
+ RK610_ERR(">>>%s I2c trans err",__FUNCTION__);\r
+ return -1;\r
+ }\r
+ if()\r
+ return (c & RK610_HPD_PLUG)?1:0;\r
+}\r
+#endif\r
+static int RK610_hdmi_soft_reset(struct i2c_client *client)\r
+{\r
+ char c;\r
+ int ret;\r
+ //soft reset\r
+ c=0x00;\r
+ ret =Rk610_hdmi_i2c_read_p0_reg(client, 0xce, &c);\r
+ msleep(10);\r
+ c=0x01;\r
+ ret =Rk610_hdmi_i2c_read_p0_reg(client, 0xce, &c); \r
+ msleep(100);\r
+ return ret;\r
+}\r
+static void Rk610_hdmi_Variable_Initial(void)\r
+{\r
+ memset(&g_hw_inf,0,sizeof(struct rk610_hdmi_hw_inf));\r
+ g_edid.edidDataValid = FALSE;\r
+ g_hw_inf.edid_inf = &g_edid; \r
+ g_hw_inf.audio_fs = HDMI_I2S_DEFAULT_Fs;\r
+ g_hw_inf.video_format = HDMI_DEFAULT_RESOLUTION;\r
+ g_hw_inf.config_param = AUDIO_CHANGE | VIDEO_CHANGE;\r
+\r
+}\r
+int Rk610_hdmi_init(struct i2c_client *client)\r
+{\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ Rk610_hdmi_Variable_Initial();\r
+ RK610_hdmi_soft_reset(client);\r
+ RK610_hdmi_Driver_mode(client);\r
+ RK610_hdmi_PLL_mode(client);\r
+ Rk610_hdmi_Set_Video(g_hw_inf.video_format);\r
+ Rk610_hdmi_Set_Audio(g_hw_inf.audio_fs);\r
+ Rk610_hdmi_Config_Done(client);\r
+ \r
+ return 0;\r
+}\r
--- /dev/null
+#ifndef _RK610_HDMI_HW_H\r
+#define _RK610_HDMI_HW_H\r
+#include <linux/earlysuspend.h>\r
+\r
+#define MAX_V_DESCRIPTORS 20\r
+#define MAX_A_DESCRIPTORS 10\r
+#define MAX_SPEAKER_CONFIGURATIONS 4\r
+#define AUDIO_DESCR_SIZE 3\r
+\r
+#define EDID_BLOCK_SIZE 128\r
+#define NUM_OF_EXTEN_ADDR 0x7e\r
+#define EDID_HDR_NO_OF_FF 0x06\r
+\r
+// Data Block Tag Codes\r
+//====================================================\r
+#define AUDIO_D_BLOCK 0x01\r
+#define VIDEO_D_BLOCK 0x02\r
+#define VENDOR_SPEC_D_BLOCK 0x03\r
+#define SPKR_ALLOC_D_BLOCK 0x04\r
+#define USE_EXTENDED_TAG 0x07\r
+// Extended Data Block Tag Codes\r
+//====================================================\r
+#define COLORIMETRY_D_BLOCK 0x05\r
+\r
+#define HDMI_SIGNATURE_LEN 0x03\r
+\r
+#define CEC_PHYS_ADDR_LEN 0x02\r
+#define EDID_EXTENSION_TAG 0x02\r
+#define EDID_REV_THREE 0x03\r
+#define EDID_DATA_START 0x04\r
+\r
+#define EDID_BLOCK_0 0x00\r
+#define EDID_BLOCK_2_3 0x01\r
+\r
+#define VIDEO_CAPABILITY_D_BLOCK 0x00\r
+\r
+//#define DEV_SUPPORT_CEC \r
+#if 1\r
+#define MSBIT 0x80\r
+#define LSBIT 0x01\r
+\r
+#define TWO_LSBITS 0x03\r
+#define THREE_LSBITS 0x07\r
+#define FOUR_LSBITS 0x0F\r
+#define FIVE_LSBITS 0x1F\r
+#define SEVEN_LSBITS 0x7F\r
+#define TWO_MSBITS 0xC0\r
+#define EIGHT_BITS 0xFF\r
+#define BYTE_SIZE 0x08\r
+#define BITS_1_0 0x03\r
+#define BITS_2_1 0x06\r
+#define BITS_2_1_0 0x07\r
+#define BITS_3_2 0x0C\r
+#define BITS_4_3_2 0x1C \r
+#define BITS_5_4 0x30\r
+#define BITS_5_4_3 0x38\r
+#define BITS_6_5 0x60\r
+#define BITS_6_5_4 0x70\r
+#define BITS_7_6 0xC0\r
+\r
+#define TPI_INTERNAL_PAGE_REG 0xBC\r
+#define TPI_INDEXED_OFFSET_REG 0xBD\r
+#define TPI_INDEXED_VALUE_REG 0xBE\r
+\r
+#define EDID_TAG_ADDR 0x00\r
+#define EDID_REV_ADDR 0x01\r
+#define EDID_TAG_IDX 0x02\r
+#define LONG_DESCR_PTR_IDX 0x02\r
+#define MISC_SUPPORT_IDX 0x03\r
+\r
+#define ESTABLISHED_TIMING_INDEX 35 // Offset of Established Timing in EDID block\r
+#define NUM_OF_STANDARD_TIMINGS 8\r
+#define STANDARD_TIMING_OFFSET 38\r
+#define LONG_DESCR_LEN 18\r
+#define NUM_OF_DETAILED_DESCRIPTORS 4\r
+\r
+#define DETAILED_TIMING_OFFSET 0x36\r
+#endif\r
+enum{\r
+ EDID_BLOCK0=0,\r
+ EDID_BLOCK1,\r
+ EDID_BLOCK2,\r
+ EDID_BLOCK3,\r
+};\r
+#define RK610_SYS_FREG_CLK 11289600\r
+#define RK610_SCL_RATE (100*1000)\r
+#define RK610_DDC_CONFIG (RK610_SYS_FREG_CLK>>2)/RK610_SCL_RATE\r
+\r
+#define FALSE 0\r
+#define TRUE 1\r
+\r
+//EVENT\r
+#define RK610_HPD_EVENT 1<<7
+#define RK610_HPD_PLUG 1<<7
+#define RK610_EDID_EVENT 1<<2\r
+\r
+//output mode 0x52\r
+#define DISPLAY_DVI 0\r
+#define DISPLAY_HDMI 1\r
+\r
+//0x00\r
+#define RK610_INT_POL 1\r
+#define RK610_SYS_PWR_ON 1\r
+#define RK610_SYS_PWR_OFF 0\r
+#define RK610_PHY_CLK 0\r
+#define RK610_SYS_CLK 1\r
+\r
+#define RK610_MCLK_FS 0x01 //256fs\r
+//0x01
+// INPUT_VIDEO_FORMAT
+#define RGB_YUV444 0x00
+#define DDR_RGB444_YUV444 0x05
+#define DDR_YUV422 0x06
+
+//0x02
+//video output format
+#define RGB444 0x00
+#define YUV444 0x01
+#define YUV422 0x02
+
+//DATA WIDTH
+#define DATA_12BIT 0X00
+#define DATA_10BIT 0X01
+#define DATA_8BIT 0X03
+
+//0X04
+//1:after 0:not After 1st sof for external DE sample
+#define DE_AFTER_SOF 0
+#define DE_NOAFTER_SOF 1
+
+#define CSC_ENABLE 0
+#define CSC_DISABLE 1
+
+//0X05
+#define CLEAR_AVMUTE(x) (x)<<7
+#define SET_AVMUTE(x) (x)<<6
+#define AUDIO_MUTE(x) (x)<<1
+#define VIDEO_BLACK(x) (x)<<0 //1:black 0:normal
+
+//0x08
+#define VSYNC_POL(x) (x)<<3 //0:Negative 1:Positive
+#define HSYNC_POL(x) (x)<<2 //0:Negative 1:Positive
+#define INTER_PROGRESSIVE(x) (x)<<1 //0: progressive 1:interlace
+#define VIDEO_SET_ENABLE(x) (x)<<0 //0:disable 1: enable
+\r
+/**********CONFIG CHANGE ************/\r
+#define VIDEO_CHANGE 1<<0\r
+#define AUDIO_CHANGE 1<<1\r
+\r
+#define byte u8\r
+\r
+typedef struct edid_info\r
+{ // for storing EDID parsed data\r
+ byte edidDataValid;\r
+ byte VideoDescriptor[MAX_V_DESCRIPTORS]; // maximum number of video descriptors\r
+ byte AudioDescriptor[MAX_A_DESCRIPTORS][3]; // maximum number of audio descriptors\r
+ byte SpkrAlloc[MAX_SPEAKER_CONFIGURATIONS]; // maximum number of speaker configurations\r
+ byte UnderScan; // "1" if DTV monitor underscans IT video formats by default\r
+ byte BasicAudio; // Sink supports Basic Audio\r
+ byte YCbCr_4_4_4; // Sink supports YCbCr 4:4:4\r
+ byte YCbCr_4_2_2; // Sink supports YCbCr 4:2:2\r
+ byte HDMI_Sink; // "1" if HDMI signature found\r
+ byte CEC_A_B; // CEC Physical address. See HDMI 1.3 Table 8-6\r
+ byte CEC_C_D;\r
+ byte ColorimetrySupportFlags; // IEC 61966-2-4 colorimetry support: 1 - xvYCC601; 2 - xvYCC709 \r
+ byte MetadataProfile;\r
+ byte _3D_Supported;\r
+ \r
+} EDID_INF;\r
+enum EDID_ErrorCodes\r
+{\r
+ EDID_OK,\r
+ EDID_INCORRECT_HEADER,\r
+ EDID_CHECKSUM_ERROR,\r
+ EDID_NO_861_EXTENSIONS,\r
+ EDID_SHORT_DESCRIPTORS_OK,\r
+ EDID_LONG_DESCRIPTORS_OK,\r
+ EDID_EXT_TAG_ERROR,\r
+ EDID_REV_ADDR_ERROR,\r
+ EDID_V_DESCR_OVERFLOW,\r
+ EDID_UNKNOWN_TAG_CODE,\r
+ EDID_NO_DETAILED_DESCRIPTORS,\r
+ EDID_DDC_BUS_REQ_FAILURE,\r
+ EDID_DDC_BUS_RELEASE_FAILURE\r
+};\r
+enum PWR_MODE{\r
+ NORMAL,\r
+ LOWER_PWR,\r
+ SHUTDOWN,\r
+};\r
+struct rk610_hdmi_hw_inf{\r
+ struct i2c_client *client;\r
+ EDID_INF *edid_inf;\r
+ u8 video_format;\r
+ u8 audio_fs;\r
+ u8 config_param;\r
+};\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+extern int Rk610_hdmi_suspend(struct i2c_client *client);\r
+extern int Rk610_hdmi_resume(struct i2c_client *client);\r
+#endif\r
+extern int Rk610_hdmi_Set_Video(u8 video_format);\r
+extern int Rk610_hdmi_Set_Audio(u8 audio_fs);\r
+extern int Rk610_hdmi_Config_Done(struct i2c_client *client);\r
+extern void Rk610_hdmi_event_work(struct i2c_client *client, bool *hpd);\r
+extern int Rk610_hdmi_init(struct i2c_client *client);\r
+#endif
\ No newline at end of file
\r
mutex_lock(&hdmi->lock);\r
precent = hdmi->ops->hdmi_precent(hdmi);\r
-\r
- if(precent && hdmi->mode == DISP_ON_LCD && hdmi->display_on){\r
+ if(precent && (hdmi->mode == DISP_ON_LCD) && hdmi->display_on){\r
if(hdmi->ops->insert(hdmi) == 0){\r
- hdmi->mode = DISP_ON_HDMI;\r
+ hdmi->mode = hdmi->display_on;\r
kobject_uevent(&hdmi->dev->kobj, KOBJ_CHANGE);\r
}\r
else\r
hdmi_dbg(hdmi->dev, "insert error\n");\r
+ hdmi_set_backlight(hdmi->display_on==DISP_ON_HDMI?HDMI_DISABLE: HDMI_ENABLE);\r
+\r
+ }\r
+ else if(precent &&(hdmi->mode != hdmi->display_on)&& hdmi->display_on){\r
+ hdmi->mode = hdmi->display_on;\r
+ hdmi_set_backlight(hdmi->display_on==DISP_ON_HDMI?HDMI_DISABLE: HDMI_ENABLE); \r
}\r
- else if((!precent || !hdmi->display_on) && hdmi->mode == DISP_ON_HDMI){\r
+ else if((!precent || !hdmi->display_on) && hdmi->mode != DISP_ON_LCD){\r
if(hdmi->ops->remove(hdmi) == 0){\r
hdmi->mode = DISP_ON_LCD;\r
+ hdmi_set_backlight(HDMI_ENABLE);\r
kobject_uevent(&hdmi->dev->kobj, KOBJ_CHANGE);\r
}\r
else\r
{\r
del_timer(&hdmi->timer);\r
flush_delayed_work(&hdmi->work);\r
- if(hdmi->mode == DISP_ON_HDMI){\r
+ if(hdmi->mode != DISP_ON_LCD){\r
hdmi->ops->remove(hdmi);\r
hdmi->mode = DISP_ON_LCD;\r
}\r
int precent = hdmi->ops->hdmi_precent(hdmi);\r
\r
if((precent && hdmi->mode == DISP_ON_LCD) ||\r
- (!precent && hdmi->mode == DISP_ON_HDMI))\r
+ (!precent && hdmi->mode != DISP_ON_LCD))\r
hdmi_changed(hdmi, 100);\r
mod_timer(&hdmi->timer, jiffies + msecs_to_jiffies(200));\r
}\r
struct hdmi* hdmi = get_hdmi_struct(0);\r
if(!hdmi)\r
return 100;\r
- else if(hdmi->mode == DISP_ON_HDMI)\r
+ else if(hdmi->mode != DISP_ON_LCD)\r
return hdmi->scale;\r
else\r
return 100;\r
#define H_BP3 60
#define H_VD3 720
#define H_FP3 16
-#define V_PW3 5
-#define V_BP3 35
+#define V_PW3 6
+#define V_BP3 30
#define V_VD3 480
-#define V_FP3 5
+#define V_FP3 9
/* 1080p@50Hz Timing */
#define OUT_CLK5 148500000
#define H_VD4 1920
#define H_FP4 528
#define V_PW4 5
-#define V_BP4 35
+#define V_BP4 36
#define V_VD4 1080
-#define V_FP4 5
+#define V_FP4 4
/* 1080p@60Hz Timing */
#define OUT_CLK4 148500000
#define H_VD5 1920
#define H_FP5 88
#define V_PW5 5
-#define V_BP5 35
+#define V_BP5 36
#define V_VD5 1080
-#define V_FP5 5
+#define V_FP5 4
extern int FB_Switch_Screen( struct rk29fb_screen *screen, u32 enable );
struct rk29fb_screen hdmi_info[] = {
{
+ .hdmi_resolution = HDMI_1280x720p_50Hz,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD0,
.standby = anx7150_standby,
}, //HDMI_1280x720p_50Hz
{
+ .hdmi_resolution = HDMI_1280x720p_60Hz,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD1,
.standby = anx7150_standby,
}, //HDMI_1280x720p_60Hz
{
+ .hdmi_resolution = HDMI_720x576p_50Hz_4x3,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD2,
.standby = anx7150_standby,
}, //HDMI_720x576p_50Hz_4x3
{
+ .hdmi_resolution = HDMI_720x576p_50Hz_16x9,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD2,
.standby = anx7150_standby,
}, //HDMI_720x576p_50Hz_16x9
{
+ .hdmi_resolution = HDMI_720x480p_60Hz_4x3,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD3,
.standby = anx7150_standby,
}, //HDMI_720x480p_60Hz_4x3
{
+ .hdmi_resolution = HDMI_720x480p_60Hz_16x9,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD3,
.standby = anx7150_standby,
}, //HDMI_720x480p_60Hz_16x9
{
+ .hdmi_resolution = HDMI_1920x1080p_50Hz,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD4,
.upper_margin = V_BP4,
.lower_margin = V_FP4,
.vsync_len = V_PW4,
- .pin_hsync = 0,
- .pin_vsync = 0,
+ .pin_hsync = 1,
+ .pin_vsync = 1,
.pin_den = 0,
.pin_dclk = DCLK_POL,
.swap_rb = SWAP_RB,
.standby = anx7150_standby,
}, //HDMI_1920x1080p_50Hz
{
+ .hdmi_resolution = HDMI_1920x1080p_60Hz,
.type = OUT_TYPE,
.face = OUT_FACE,
.x_res = H_VD5,
.upper_margin = V_BP5,
.lower_margin = V_FP5,
.vsync_len = V_PW5,
- .pin_hsync = 0,
- .pin_vsync = 0,
+ .pin_hsync = 1,
+ .pin_vsync = 1,
.pin_den = 0,
.pin_dclk = DCLK_POL,
.swap_rb = SWAP_RB,
#include <linux/hdmi.h>
#endif
+
#include <mach/iomux.h>
#include <mach/gpio.h>
#include "./display/screen/screen.h"
+#ifdef CONFIG_MFD_RK610
+#include "./display/lcd/rk610_lcd.h"
+#endif
#define ANDROID_USE_THREE_BUFS 0 //android use three buffers to accelerate UI display in rgb plane
#define CURSOR_BUF_SIZE 256 //RK2818 cursor need 256B buf
int rk29_cursor_buf[CURSOR_BUF_SIZE];
#endif
};
-
+#ifdef CONFIG_BACKLIGHT_RK29_BL
+/* drivers/video/backlight/rk29_backlight.c */
+extern void rk29_backlight_set(bool on);
+#else
+void rk29_backlight_set(bool on)
+{
+ /* please add backlight switching-related code here or on your backlight driver
+ parameter: on=1 ==> open spk
+ on=0 ==> close spk
+ */
+}
+#endif
typedef enum _TRSP_MODE
{
TRSP_CLOSE = 0,
if(inf->cur_screen->standby) inf->cur_screen->standby(1);
// operate the display_on pin to power down the lcd
-
+#ifdef CONFIG_HDMI_DUAL_DISP
+ inf->panel1_info.sscreen_get(&inf->panel1_info,inf->panel2_info.hdmi_resolution);
+ inf->panel1_info.sscreen_set(&inf->panel1_info,enable);
+#else
if(enable && mach_info->io_disable)mach_info->io_disable(); //close lcd out
else if (mach_info->io_enable)mach_info->io_enable(); //open lcd out
-
+#endif
load_screen(inf->fb0, 0);
mcu_refresh(inf);
fb0_set_par(inf->fb0);
LcdMskReg(inf, DSP_CTRL1, m_BLACK_MODE, v_BLACK_MODE(0));
LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
rk29fb_notify(inf, enable ? RK29FB_EVENT_HDMI_ON : RK29FB_EVENT_HDMI_OFF);
return 0;
}
#else
set_lcd_info(&inf->panel1_info, mach_info->lcd_info);
#endif
+
inf->cur_screen = &inf->panel1_info;
screen = inf->cur_screen;
if(SCREEN_NULL==screen->type)
goto release_irq;
}
}
-
+ #ifdef CONFIG_MFD_RK610
+ rk610_lcd_scaler_set_param(&inf->panel1_info,0);
+ #endif
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
fb0_set_par(inf->fb0);
if (fb_prepare_logo(inf->fb0, FB_ROTATE_UR)) {
--- /dev/null
+#ifndef _LINUX_DISPLAY_RK_H
+#define _LINUX_DISPLAY_RK_H
+
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/list.h>
+
+struct rk_display_device;
+
+enum rk_display_priority {
+ DISPLAY_PRIORITY_TV = 0,
+ DISPLAY_PRIORITY_YPbPr,
+ DISPLAY_PRIORITY_VGA,
+ DISPLAY_PRIORITY_HDMI,
+ DISPLAY_PRIORITY_LCD,
+};
+
+/* This structure defines all the properties of a Display. */
+struct rk_display_driver {
+ void (*suspend)(struct rk_display_device *, pm_message_t state);
+ void (*resume)(struct rk_display_device *);
+ int (*probe)(struct rk_display_device *, void *);
+ int (*remove)(struct rk_display_device *);
+};
+
+struct rk_display_ops {
+ int (*setenable)(struct rk_display_device *, int enable);
+ int (*getenable)(struct rk_display_device *);
+ int (*getstatus)(struct rk_display_device *);
+ int (*getmodelist)(struct rk_display_device *, struct list_head **modelist);
+ int (*setmode)(struct rk_display_device *, struct fb_videomode *mode);
+ int (*getmode)(struct rk_display_device *, struct fb_videomode *mode);
+};
+
+struct rk_display_device {
+ struct module *owner; /* Owner module */
+ struct rk_display_driver *driver;
+ struct device *parent; /* This is the parent */
+ struct device *dev; /* This is this display device */
+ struct mutex lock;
+ void *priv_data;
+ char type[16];
+ char *name;
+ int idx;
+ struct rk_display_ops *ops;
+ int priority;
+ struct list_head list;
+};
+
+struct rk_display_devicelist {
+ struct list_head list;
+ struct rk_display_device *dev;
+};
+
+extern struct rk_display_device *rk_display_device_register(struct rk_display_driver *driver,
+ struct device *dev, void *devdata);
+extern void rk_display_device_unregister(struct rk_display_device *dev);
+
+extern void rk_display_device_enable(struct rk_display_device *ddev);
+
+extern void rk_display_device_enable_other(struct rk_display_device *ddev);
+extern void rk_display_device_disable_other(struct rk_display_device *ddev);
+
+
+extern void rk_display_device_select(int priority);
+
+#define to_rk_display_device(obj) container_of(obj, struct rk_display_device, class_dev)
+
+#endif
#define HDMI_720x480p_60Hz_16x9 7\r
\r
/* HDMI default resolution */\r
-#define HDMI_DEFAULT_RESOLUTION HDMI_1920x1080p_50Hz\r
+#define HDMI_DEFAULT_RESOLUTION HDMI_1920x1080p_50Hz\r
/* I2S Fs */\r
#define HDMI_I2S_Fs_44100 0\r
#define HDMI_I2S_Fs_48000 2\r
--- /dev/null
+#ifndef __RK610_CONTROL_H_
+#define __RK610_CONTROL_H_
+
+#define INVALID_GPIO -1
+#define RK610_DEBUG 1
+
+#if RK610_DEBUG
+#define RK610_DBG(dev, format, arg...) \
+do{\
+ dev_printk(KERN_INFO , dev , format , ## arg);\
+}while(0)
+#else
+#define RK610_DBG(dev, format, arg...)
+#endif
+#define RK610_ERR(dev, format, arg...) \
+do{\
+ dev_printk(KERN_ERR , dev , format , ## arg);\
+}while(0)
+
+#define RK610_CONTROL_REG_C_PLL_CON0 0x00
+#define RK610_CONTROL_REG_C_PLL_CON1 0x01
+#define RK610_CONTROL_REG_C_PLL_CON2 0x02
+#define RK610_CONTROL_REG_C_PLL_CON3 0x03
+#define RK610_CONTROL_REG_C_PLL_CON4 0x04
+#define RK610_CONTROL_REG_C_PLL_CON5 0x05
+ #define C_PLL_DISABLE_FRAC 1 << 0
+ #define C_PLL_BYPSS_ENABLE 1 << 1
+ #define C_PLL_POWER_ON 1 << 2
+ #define C_PLL_LOCLED 1 << 7
+
+#define RK610_CONTROL_REG_TVE_CON 0x29
+ #define TVE_CONTROL_VDAC_R_BYPASS_ENABLE 1 << 7
+ #define TVE_CONTROL_VDAC_R_BYPASS_DISABLE 0 << 7
+ #define TVE_CONTROL_CVBS_3_CHANNEL_ENALBE 1 << 6
+ #define TVE_CONTROL_CVBS_3_CHANNEL_DISALBE 0 << 5
+enum {
+ INPUT_DATA_FORMAT_RGB888 = 0,
+ INPUT_DATA_FORMAT_RGB666,
+ INPUT_DATA_FORMAT_RGB565,
+ INPUT_DATA_FORMAT_YUV
+};
+ #define RGB2CCIR_INPUT_DATA_FORMAT(n) n << 4
+
+ #define RGB2CCIR_RGB_SWAP_ENABLE 1 << 3
+ #define RGB2CCIR_RGB_SWAP_DISABLE 0 << 3
+
+ #define RGB2CCIR_INPUT_INTERLACE 1 << 2
+ #define RGB2CCIR_INPUT_PROGRESSIVE 0 << 2
+
+ #define RGB2CCIR_CVBS_PAL 0 << 1
+ #define RGB2CCIR_CVBS_NTSC 1 << 1
+
+ #define RGB2CCIR_DISABLE 0
+ #define RGB2CCIR_ENABLE 1
+
+#define RK610_CONTROL_REG_CCIR_RESET 0x2a
+
+#define RK610_CONTROL_REG_CLOCK_CON0 0x2b
+#define RK610_CONTROL_REG_CLOCK_CON1 0x2c
+ #define CLOCK_CON1_I2S_CLK_CODEC_PLL 1 << 5
+ #define CLOCK_CON1_I2S_DVIDER_MASK 0x1F
+#define RK610_CONTROL_REG_CODEC_CON 0x2d
+ #define CODEC_CON_BIT_HDMI_BLCK_INTERANL 1<<4
+ #define CODEC_CON_BIT_DAC_LRCL_OUTPUT_DISABLE 1<<3
+ #define CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE 1<<2
+ #define CODEC_CON_BIT_INTERAL_CODEC_DISABLE 1<<0
+
+#define RK610_CONTROL_REG_I2C_CON 0x2e
+
+/********************************************************************
+** ½á¹¹¶¨Òå *
+********************************************************************/
+/* RK610µÄ¼Ä´æÆ÷½á¹¹ */
+/* CODEC PLL REG */
+#define C_PLL_CON0 0x00
+#define C_PLL_CON1 0x01
+#define C_PLL_CON2 0x02
+#define C_PLL_CON3 0x03
+#define C_PLL_CON4 0x04
+#define C_PLL_CON5 0x05
+
+/* SCALER PLL REG */
+#define S_PLL_CON0 0x06
+#define S_PLL_CON1 0x07
+#define S_PLL_CON2 0x08
+
+/* LVDS REG */
+#define LVDS_CON0 0x09
+#define LVDS_CON1 0x0a
+
+/* LCD1 REG */
+#define LCD1_CON 0x0b
+
+/* SCALER REG */
+#define SCL_CON0 0x0c
+#define SCL_CON1 0x0d
+#define SCL_CON2 0x0e
+#define SCL_CON3 0x0f
+#define SCL_CON4 0x10
+#define SCL_CON5 0x11
+#define SCL_CON6 0x12
+#define SCL_CON7 0x13
+#define SCL_CON8 0x14
+#define SCL_CON9 0x15
+#define SCL_CON10 0x16
+#define SCL_CON11 0x17
+#define SCL_CON12 0x18
+#define SCL_CON13 0x19
+#define SCL_CON14 0x1a
+#define SCL_CON15 0x1b
+#define SCL_CON16 0x1c
+#define SCL_CON17 0x1d
+#define SCL_CON18 0x1e
+#define SCL_CON19 0x1f
+#define SCL_CON20 0x20
+#define SCL_CON21 0x21
+#define SCL_CON22 0x22
+#define SCL_CON23 0x23
+#define SCL_CON24 0x24
+#define SCL_CON25 0x25
+#define SCL_CON26 0x26
+#define SCL_CON27 0x27
+#define SCL_CON28 0x28
+
+/* TVE REG */
+#define TVE_CON 0x29
+
+/* CCIR REG */
+#define CCIR_RESET 0X2a
+
+/* CLOCK REG */
+#define CLOCK_CON0 0X2b
+#define CLOCK_CON1 0X2c
+
+/* CODEC REG */
+#define CODEC_CON 0x2e
+#define I2C_CON 0x2f
+
+
+extern int rk610_control_send_byte(const char reg, const char data);
+
+#endif /*end of __RK610_CONTROL_H_*/
select SND_SOC_RT5621 if I2C
select SND_SOC_RT5631 if I2C
select SND_SOC_RT5625 if I2C
+ select SND_SOC_RK610 if I2C
select SND_SOC_WM8903 if I2C
select SND_SOC_WM8904 if I2C
select SND_SOC_WM8915 if I2C
tristate
# depends on RK1000_CONTROL
+config SND_SOC_RK610
+ tristate
+ depends on MFD_RK610
+
# Amp
config SND_SOC_LM4857
tristate
snd-soc-wm-hubs-objs := wm_hubs.o
snd-soc-rk1000-objs := rk1000_codec.o
snd-soc-jz4740-codec-objs := jz4740.o
+snd-soc-rk610-objs := rk610_codec.o
# Amp
snd-soc-lm4857-objs := lm4857.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o
-
+obj-$(CONFIG_SND_SOC_RK610) += snd-soc-rk610.o
# Amp
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
--- /dev/null
+/*
+ * rk610.c -- RK610 ALSA SoC audio driver
+ *
+ * Copyright (C) 2009 rockchip lhh
+ *
+ *
+ * Based on RK610.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <mach/gpio.h>
+#include <mach/iomux.h>
+
+#include "rk610_codec.h"
+
+#define RK610_SPK_CTRL_PIN RK29_PIN6_PB6
+
+
+/*
+ * Debug
+ */
+#if 0
+#define DBG(x...) printk(KERN_ERR x)
+#else
+#define DBG(x...)
+#endif
+
+#define err(format, arg...) \
+ printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
+
+#define OUT_CAPLESS (0) //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö
+
+static u32 gVolReg = 0x00; ///0x0f; //ÓÃÓڼǼÒôÁ¿¼Ä´æÆ÷
+//static u32 gCodecVol = 0x0f;
+static u8 gR0AReg = 0; //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk
+static u8 gR0BReg = 0; //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation
+//static u8 gR1314Reg = 0; //ÓÃÓڼǼR13,R14¼Ä´æÆ÷µÄÖµ£¬ÓÃÓÚFMÒôÁ¿Îª0ʱ
+
+/*
+ * rk610 register cache
+ * We can't read the RK610 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u16 rk610_codec_reg[] = {
+ 0x0005, 0x0004, 0x00fd, 0x00f3, /* 0 */
+ 0x0003, 0x0000, 0x0000, 0x0000, /* 4 */
+ 0x0000, 0x0005, 0x0000, 0x0000, /* 8 */
+ 0x0097, 0x0097, 0x0097, 0x0097, /* 12 */
+ 0x0097, 0x0097, 0x00cc, 0x0000, /* 16 */
+ 0x0000, 0x00f1, 0x0090, 0x00ff, /* 20 */
+ 0x00ff, 0x00ff, 0x009c, 0x0000, /* 24 */
+ 0x0000, 0x00ff, 0x00ff, 0x00ff, /* 28 */
+};
+
+static struct snd_soc_codec *rk610_codec_codec;
+/* codec private data */
+struct rk610_codec_priv {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ enum snd_soc_control_type control_type;
+#endif
+ unsigned int sysclk;
+ struct snd_soc_codec codec;
+ struct snd_pcm_hw_constraint_list *sysclk_constraints;
+ u16 reg_cache[RK610_CODEC_NUM_REG];
+};
+
+extern int rk610_control_init_codec(void);
+extern int rk610_codec_pll_set(unsigned int rate);
+
+/*
+ * read rk610 register cache
+ */
+static inline unsigned int rk610_codec_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg > RK610_CACHE_REGNUM)
+ return -1;
+ return cache[reg];
+}
+
+static unsigned int rk610_codec_read(struct snd_soc_codec *codec, unsigned int r)
+{
+ struct i2c_msg xfer[1];
+ u8 reg = r;
+ int ret;
+ struct i2c_client *client = codec->control_data;
+
+ /* Read register */
+ xfer[0].addr = (client->addr& 0x60)|(reg);
+ xfer[0].flags = I2C_M_RD;
+ xfer[0].len = 1;
+ xfer[0].buf = ®
+ xfer[0].scl_rate = 100000;
+ ret = i2c_transfer(client->adapter, xfer, 1);
+ if (ret != 1) {
+ dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
+ return 0;
+ }
+
+ return reg;
+}
+/*
+ * write rk610 register cache
+ */
+static inline void rk610_codec_write_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg > RK610_CACHE_REGNUM)
+ return;
+ cache[reg] = value;
+}
+
+static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 data[2];
+ struct i2c_client *i2c;
+ DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value);
+ data[0] = value & 0x00ff;
+ rk610_codec_write_reg_cache (codec, reg, value);
+ i2c = (struct i2c_client *)codec->control_data;
+ i2c->addr = (i2c->addr & 0x60)|reg;
+
+ if (codec->hw_write(codec->control_data, data, 1) == 1){
+// DBG("================%s %d Run OK================\n",__FUNCTION__,__LINE__);
+ return 0;
+ }else{
+ DBG("================%s %d Run EIO================\n",__FUNCTION__,__LINE__);
+ return -EIO;
+ }
+}
+
+void rk610_codec_reg_read(void)
+{
+ struct snd_soc_codec *codec = rk610_codec_codec;
+ int i;
+ unsigned int data;
+
+ for (i=0; i<=0x1f; i++){
+ data = rk610_codec_read(codec, i);
+ DBG("reg[0x%x]=0x%x\n",i,data);
+ }
+}
+
+static const struct snd_kcontrol_new rk610_codec_snd_controls[] = {
+SOC_DOUBLE_R("Capture Volume", ACCELCODEC_R0C, ACCELCODEC_R0D, 0, 15, 0),
+SOC_DOUBLE_R("Capture Switch", ACCELCODEC_R0C, ACCELCODEC_R0D, 7, 1, 1),
+SOC_DOUBLE_R("PCM Volume", ACCELCODEC_R0D, ACCELCODEC_R0E, 0, 7, 0),
+//SOC_SINGLE("Left ADC Capture Volume", ACCELCODEC_R17, 0, 63, 0),
+//SOC_SINGLE("Right ADC Capture Volume", ACCELCODEC_R18, 0, 63, 0),
+};
+
+/* Left Mixer */
+static const struct snd_kcontrol_new rk610_codec_left_mixer_controls[] = {
+SOC_DAPM_SINGLE("Left Playback Switch", ACCELCODEC_R15, 6, 1, 0),
+SOC_DAPM_SINGLE("Left Bypass Switch", ACCELCODEC_R15, 2, 1, 0),
+};
+
+/* Right Mixer */
+static const struct snd_kcontrol_new rk610_codec_right_mixer_controls[] = {
+SOC_DAPM_SINGLE("Right Playback Switch", ACCELCODEC_R15, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Bypass Switch", ACCELCODEC_R15, 3, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget rk610_codec_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
+ &rk610_codec_left_mixer_controls[0],
+ ARRAY_SIZE(rk610_codec_left_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
+ &rk610_codec_right_mixer_controls[0],
+ ARRAY_SIZE(rk610_codec_right_mixer_controls)),
+
+ //SND_SOC_DAPM_PGA("Right Out 1", ACCELCODEC_R1E, 0, 0, NULL, 0),
+ //SND_SOC_DAPM_PGA("Left Out 1", ACCELCODEC_R1E, 1, 0, NULL, 0),
+ //SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ACCELCODEC_R1F, 1, 0),
+ //SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ACCELCODEC_R1F, 2, 0),
+
+ SND_SOC_DAPM_ADC("ADC", "Capture", ACCELCODEC_R1D, 6, 1),
+ SND_SOC_DAPM_ADC("ADC BUFF", "Capture BUFF", ACCELCODEC_R1D, 2, 0),
+
+
+ SND_SOC_DAPM_OUTPUT("LOUT1"),
+ SND_SOC_DAPM_OUTPUT("ROUT1"),
+
+ SND_SOC_DAPM_INPUT("LINPUT1"),
+ SND_SOC_DAPM_INPUT("RINPUT1"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* left mixer */
+ {"Left Mixer", "Left Playback Switch", "Left DAC"},
+ {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
+ {"Right Mixer", "Right Playback Switch", "Right DAC"},
+ {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
+
+ /* left out 1 */
+ {"Left Out 1", NULL, "Left Mixer"},
+ {"LOUT1", NULL, "Left Out 1"},
+
+
+ /* right out 1 */
+ {"Right Out 1", NULL, "Right Mixer"},
+ {"ROUT1", NULL, "Right Out 1"},
+
+ /* Left Line Mux */
+ {"Left Line Mux", "Line 1", "LINPUT1"},
+ {"Left Line Mux", "PGA", "Left PGA Mux"},
+ {"Left Line Mux", "Differential", "Differential Mux"},
+
+ /* Right Line Mux */
+ {"Right Line Mux", "Line 1", "RINPUT1"},
+ {"Right Line Mux", "PGA", "Right PGA Mux"},
+ {"Right Line Mux", "Differential", "Differential Mux"},
+
+ /* Left PGA Mux */
+ {"Left PGA Mux", "Line 1", "LINPUT1"},
+ {"Left PGA Mux", "Line 2", "LINPUT2"},
+ {"Left PGA Mux", "Line 3", "LINPUT3"},
+ {"Left PGA Mux", "Differential", "Differential Mux"},
+
+ /* Right PGA Mux */
+ {"Right PGA Mux", "Line 1", "RINPUT1"},
+ {"Right PGA Mux", "Differential", "Differential Mux"},
+
+ /* Differential Mux */
+ {"Differential Mux", "Line 1", "LINPUT1"},
+ {"Differential Mux", "Line 1", "RINPUT1"},
+
+ /* Left ADC Mux */
+ {"Left ADC Mux", "Stereo", "Left PGA Mux"},
+ {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
+ {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
+
+ /* Right ADC Mux */
+ {"Right ADC Mux", "Stereo", "Right PGA Mux"},
+ {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
+ {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
+
+ /* ADC */
+ {"Left ADC", NULL, "Left ADC Mux"},
+ {"Right ADC", NULL, "Right ADC Mux"},
+
+ /* terminator */
+// {NULL, NULL, NULL},
+};
+
+struct _coeff_div {
+ u32 mclk;
+ u32 rate;
+ u16 fs;
+ u8 sr:5;
+ u8 usb:1;
+ u8 bclk;
+};
+
+/* codec hifi mclk clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+ /* 8k */
+ {12288000, 8000, 1536, 0x6, 0x0,ASC_BCLKDIV_16},
+ {11289600, 8000, 1408, 0x16, 0x0,ASC_BCLKDIV_16},
+ {18432000, 8000, 2304, 0x7, 0x0,ASC_BCLKDIV_16},
+ {16934400, 8000, 2112, 0x17, 0x0,ASC_BCLKDIV_16},
+ {8192000, 8000, 1024, 0x0, 0x0,ASC_BCLKDIV_16},
+ {12000000, 8000, 1500, 0x6, 0x1,ASC_BCLKDIV_16},
+
+ /* 11.025k */
+ {11289600, 11025, 1024, 0x18, 0x0,ASC_BCLKDIV_16},
+ {16934400, 11025, 1536, 0x19, 0x0,ASC_BCLKDIV_16},
+ {12000000, 11025, 1088, 0x19, 0x1,ASC_BCLKDIV_16},
+
+ /* 12k */
+ {12288000, 12000, 1024, 0x8, 0x0,ASC_BCLKDIV_16},
+ {18432000, 12000, 1536, 0x9, 0x0,ASC_BCLKDIV_16},
+ {12000000, 12000, 1000, 0x8, 0x1,ASC_BCLKDIV_16},
+
+ /* 16k */
+ {12288000, 16000, 768, 0xa, 0x0,ASC_BCLKDIV_8},
+ {18432000, 16000, 1152, 0xb, 0x0,ASC_BCLKDIV_8},
+ {12000000, 16000, 750, 0xa, 0x1,ASC_BCLKDIV_8},
+
+ /* 22.05k */
+ {11289600, 22050, 512, 0x1a, 0x0,ASC_BCLKDIV_8},
+ {16934400, 22050, 768, 0x1b, 0x0,ASC_BCLKDIV_8},
+ {12000000, 22050, 544, 0x1b, 0x1,ASC_BCLKDIV_8},
+
+ /* 24k */
+ {12288000, 24000, 512, 0x1c, 0x0,ASC_BCLKDIV_8},
+ {18432000, 24000, 768, 0x1d, 0x0,ASC_BCLKDIV_8},
+ {12000000, 24000, 500, 0x1c, 0x1,ASC_BCLKDIV_8},
+
+ /* 32k */
+ {12288000, 32000, 384, 0xc, 0x0,ASC_BCLKDIV_8},
+ {18432000, 32000, 576, 0xd, 0x0,ASC_BCLKDIV_8},
+ {12000000, 32000, 375, 0xa, 0x1,ASC_BCLKDIV_8},
+
+ /* 44.1k */
+ {11289600, 44100, 256, 0x10, 0x0,ASC_BCLKDIV_4},
+ {16934400, 44100, 384, 0x11, 0x0,ASC_BCLKDIV_8},
+ {12000000, 44100, 272, 0x11, 0x1,ASC_BCLKDIV_8},
+
+ /* 48k */
+ {12288000, 48000, 256, 0x0, 0x0,ASC_BCLKDIV_4},
+ {18432000, 48000, 384, 0x1, 0x0,ASC_BCLKDIV_4},
+ {12000000, 48000, 250, 0x0, 0x1,ASC_BCLKDIV_4},
+
+ /* 88.2k */
+ {11289600, 88200, 128, 0x1e, 0x0,ASC_BCLKDIV_4},
+ {16934400, 88200, 192, 0x1f, 0x0,ASC_BCLKDIV_4},
+ {12000000, 88200, 136, 0x1f, 0x1,ASC_BCLKDIV_4},
+
+ /* 96k */
+ {12288000, 96000, 128, 0xe, 0x0,ASC_BCLKDIV_4},
+ {18432000, 96000, 192, 0xf, 0x0,ASC_BCLKDIV_4},
+ {12000000, 96000, 125, 0xe, 0x1,ASC_BCLKDIV_4},
+};
+
+static inline int get_coeff(int mclk, int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+/* The set of rates we can generate from the above for each SYSCLK */
+
+static unsigned int rates_12288[] = {
+ 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12288 = {
+ .count = ARRAY_SIZE(rates_12288),
+ .list = rates_12288,
+};
+
+static unsigned int rates_112896[] = {
+ 8000, 11025, 22050, 44100,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_112896 = {
+ .count = ARRAY_SIZE(rates_112896),
+ .list = rates_112896,
+};
+
+static unsigned int rates_12[] = {
+ 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
+ 48000, 88235, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12 = {
+ .count = ARRAY_SIZE(rates_12),
+ .list = rates_12,
+};
+
+/*
+ * Note that this should be called from init rather than from hw_params.
+ */
+static int rk610_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
+#else
+ struct rk610_codec_priv *rk610_codec = codec->private_data;
+#endif
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+
+// if(rk610_codec_pll_set(freq))
+// return -EINVAL;
+
+ switch (freq) {
+ case 11289600:
+ case 18432000:
+ case 22579200:
+ case 36864000:
+ rk610_codec->sysclk_constraints = &constraints_112896;
+ rk610_codec->sysclk = freq;
+ break;
+
+ case 12288000:
+ case 16934400:
+ case 24576000:
+ case 33868800:
+ rk610_codec->sysclk_constraints = &constraints_12288;
+ rk610_codec->sysclk = freq;
+ break;
+
+ case 12000000:
+ case 24000000:
+ rk610_codec->sysclk_constraints = &constraints_12;
+ rk610_codec->sysclk = freq;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iface = 0x0040;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ iface = 0x0000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ DBG("Enter::%s----%d iface=%x\n",__FUNCTION__,__LINE__,iface);
+ rk610_codec_write(codec, ACCELCODEC_R09, iface);
+ return 0;
+}
+
+static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
+#else
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct rk610_codec_priv *rk610_codec = codec->private_data;
+#endif
+ u16 iface = rk610_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
+ u16 srate = rk610_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180;
+ int coeff;
+
+ /*by Vincent Hsiung for EQ Vol Change*/
+ #define HW_PARAMS_FLAG_EQVOL_ON 0x21
+ #define HW_PARAMS_FLAG_EQVOL_OFF 0x22
+ if (params->flags == HW_PARAMS_FLAG_EQVOL_ON)
+ {
+ u16 r17 = rk610_codec_read_reg_cache(codec, ACCELCODEC_R17);
+ u16 r18 = rk610_codec_read_reg_cache(codec, ACCELCODEC_R18);
+
+ r17 &= (~0x3f); //6db
+ r18 &= (~0x3f); //6db
+
+ rk610_codec_write(codec, ACCELCODEC_R17, r17);
+ rk610_codec_write(codec, ACCELCODEC_R18, r18);
+
+ return 0;
+ }
+ else if (params->flags == HW_PARAMS_FLAG_EQVOL_OFF)
+ {
+ u16 r17 = rk610_codec_read_reg_cache(codec, ACCELCODEC_R17);
+ u16 r18 = rk610_codec_read_reg_cache(codec, ACCELCODEC_R18);
+
+ r17 &= (~0x3f);
+ r17 |= 0x0f; //0db
+
+ r18 &= (~0x3f);
+ r18 |= 0x0f; //0db
+
+ rk610_codec_write(codec, ACCELCODEC_R17, r17);
+ rk610_codec_write(codec, ACCELCODEC_R18, r18);
+ return 0;
+ }
+
+ coeff = get_coeff(rk610_codec->sysclk, params_rate(params));
+ DBG("Enter::%s----%d rk610_codec->sysclk=%d coeff = %d\n",__FUNCTION__,__LINE__,rk610_codec->sysclk, coeff);
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x000c;
+ break;
+ }
+ DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
+
+// rk610_codec_write(codec,ACCELCODEC_R0C, 0x17);
+ rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
+ //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬
+ //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô
+ rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00
+
+ /* set iface & srate */
+ #ifdef CONFIG_SND_RK29_CODEC_SOC_MASTER
+ iface |= ASC_INVERT_BCLK;//·×ªBCLK master״̬ËͳöµÄÉÙÁ˰ë¸öʱÖÓ£¬µ¼ÖÂδµ½×î´óÒôÁ¿µÄʱºòÆÆÒô¡¢
+ #endif
+ rk610_codec_write(codec, ACCELCODEC_R09, iface);
+ if (coeff >= 0){
+ rk610_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk);
+ rk610_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE);
+ }
+ rk610_codec_write(codec,ACCELCODEC_R0B, gR0BReg);
+
+ return 0;
+}
+
+void PhaseOut(struct snd_soc_codec *codec,u32 nStep, u32 us)
+{
+ DBG("%s[%d]\n",__FUNCTION__,__LINE__);
+ rk610_codec_write(codec,ACCELCODEC_R17, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL
+ rk610_codec_write(codec,ACCELCODEC_R18, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR
+ udelay(us);
+}
+
+void PhaseIn(struct snd_soc_codec *codec,u32 nStep, u32 us)
+{
+ DBG("%s[%d]\n",__FUNCTION__,__LINE__);
+ rk610_codec_write(codec,ACCELCODEC_R17, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL
+ rk610_codec_write(codec,ACCELCODEC_R18, gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR
+ udelay(us);
+}
+
+static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
+
+ if (mute)
+ {
+ PhaseOut(codec,1, 5000);
+ rk610_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM
+ rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
+ //add for standby
+ if(!dai->capture_active)
+ {
+ rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
+ rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
+ rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
+ }
+ }
+ else
+ {
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down
+ rk610_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE);
+
+ #if OUT_CAPLESS
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
+ #else
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
+ #endif
+
+ PhaseIn(codec,1, 5000);
+ //if(gCodecVol != 0)
+ //{
+ rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
+ //}
+ rk610_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM
+#if 0
+ /*disable speaker */
+ gpio_set_value(RK29_PIN6_PB6, GPIO_LOW);
+#endif
+ rk610_codec_reg_read();
+ }
+
+ return 0;
+}
+
+static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level);
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ /* VREF, VMID=2x50k, digital enabled */
+ // rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ printk("rk610 standby\n");
+ rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
+ rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
+ rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ printk("rk610 power off\n");
+ rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
+ rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
+ rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
+ break;
+ }
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ codec->dapm.bias_level = level;
+#else
+ codec->bias_level = level;
+#endif
+ return 0;
+}
+
+#define RK610_CODEC_RATES SNDRV_PCM_RATE_8000_96000
+
+#define RK610_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops rk610_codec_ops = {
+ .hw_params = rk610_codec_pcm_hw_params,
+ .set_fmt = rk610_codec_set_dai_fmt,
+ .set_sysclk = rk610_codec_set_dai_sysclk,
+ .digital_mute = rk610_codec_mute,
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static struct snd_soc_dai_driver rk610_codec_dai =
+#else
+struct snd_soc_dai rk610_codec_dai =
+#endif
+{
+ .name = "rk610_codec_xx",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RK610_CODEC_RATES,
+ .formats = RK610_CODEC_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RK610_CODEC_RATES,
+ .formats = RK610_CODEC_FORMATS,
+ },
+ .ops = &rk610_codec_ops,
+ .symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(rk610_codec_dai);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static int rk610_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+#else
+static int rk610_codec_suspend(struct platform_device *pdev, pm_message_t state)
+#endif
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+#endif
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ rk610_codec_reg_read();
+
+ return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static int rk610_codec_resume(struct snd_soc_codec *codec)
+#else
+static int rk610_codec_resume(struct platform_device *pdev)
+#endif
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+#endif
+ int i;
+ u8 data[2];
+ struct i2c_client *i2c;
+ u16 *cache = codec->reg_cache;
+
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ /* Sync reg_cache with the hardware */
+ for (i = 0; i < RK610_CODEC_NUM_REG; i++) {
+ data[0] = cache[i] & 0x00ff;
+ i2c = (struct i2c_client *)codec->control_data;
+ i2c->addr = (i2c->addr & 0x60)|i;
+ codec->hw_write(codec->control_data, data, 1);
+ }
+
+ rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+#if 1
+#define USE_MIC_IN
+#define USE_LPF 1
+void rk610_codec_reg_set(void)
+{
+ struct snd_soc_codec *codec = rk610_codec_codec;
+ unsigned int digital_gain;
+
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0xFF);
+ rk610_codec_write(codec,ACCELCODEC_R1E, 0xFF);
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0xFF);
+
+#if USE_LPF
+ // Route R-LPF->R-Mixer, L-LPF->L-Mixer
+ rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);
+#else
+ // Route RDAC->R-Mixer, LDAC->L->Mixer
+ rk610_codec_write(codec,ACCELCODEC_R15, 0x0C);
+#endif
+ // With Cap Output, VMID ramp up slow
+ rk610_codec_write(codec,ACCELCODEC_R1A, 0x14);
+ mdelay(10);
+
+ rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB); //LIL
+ rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB); //LIR
+ rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|ASC_INPUT_VOL_0DB); //MIC
+#ifdef USE_MIC_IN
+ rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB); //Select MIC input
+ rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); //0x00); //use default value
+#else
+ rk610_codec_write(codec,ACCELCODEC_R12, 0x4c); //Select Line input
+#endif
+ // Diable route PGA->R/L Mixer, PGA gain 0db.
+ rk610_codec_write(codec,ACCELCODEC_R13, 0x05 | 0 << 3);
+ rk610_codec_write(codec,ACCELCODEC_R14, 0x05 | 0 << 3);
+
+ //2soft mute
+ rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
+
+ //2set default SR and clk
+ rk610_codec_write(codec,ACCELCODEC_R0A, ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE);
+ gR0AReg = ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE;
+ //2Config audio interface
+ rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_MASTER_MODE|ASC_NORMAL_BCLK);
+ rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_DISABLE|ASC_SCRAMBLE_DISABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_4);
+ //2volume,input,output
+ digital_gain = 0xE42;
+ rk610_codec_write(codec,ACCELCODEC_R05, (digital_gain >> 8) & 0xFF);
+ rk610_codec_write(codec,ACCELCODEC_R06, digital_gain & 0xFF);
+ rk610_codec_write(codec,ACCELCODEC_R07, (digital_gain >> 8) & 0xFF);
+ rk610_codec_write(codec,ACCELCODEC_R08, digital_gain & 0xFF);
+// rk610_codec_write(codec,ACCELCODEC_R05, 0x0e);
+// rk610_codec_write(codec,ACCELCODEC_R06, 0x42);
+// rk610_codec_write(codec,ACCELCODEC_R07, 0x0e);
+// rk610_codec_write(codec,ACCELCODEC_R08, 0x42);
+
+ rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_ENABLE|ASC_INT_ENABLE);
+ gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE; //ASC_DEC_DISABLE|ASC_INT_ENABLE;
+
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0x30);
+ rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);
+ #if OUT_CAPLESS
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
+ #else
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
+ #endif
+}
+#else
+void rk610_codec_reg_set(void)
+{
+ struct snd_soc_codec *codec = rk610_codec_codec;
+ int reg;
+ int i;
+ unsigned int data;
+
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0x00);
+ rk610_codec_write(codec,ACCELCODEC_R17, 0xFF); //AOL
+ rk610_codec_write(codec,ACCELCODEC_R18, 0xFF); //AOR
+ rk610_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM
+
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0xDF);
+ mdelay(10);
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x5F);
+ rk610_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM
+ rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);//rk610_codec_write(codec,ACCELCODEC_R15, 0xCD);//by Vincent Hsiung
+ rk610_codec_write(codec,ACCELCODEC_R1A, 0x1C);
+ mdelay(100);
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09);
+ rk610_codec_write(codec,ACCELCODEC_R1E, 0x00);
+ mdelay(10);
+ rk610_codec_write(codec,ACCELCODEC_R1A, 0x14);
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0xFE);
+ rk610_codec_write(codec,ACCELCODEC_R17, 0xBF); //AOL
+ rk610_codec_write(codec,ACCELCODEC_R18, 0xBF); //AOR
+ rk610_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0xDF);
+
+ //2soft mute
+ rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute
+
+ //2set default SR and clk
+ rk610_codec_write(codec,ACCELCODEC_R0A, ASC_USB_MODE|FREQ48kHz|ASC_CLKNODIV|ASC_CLK_DISABLE);
+ gR0AReg = ASC_USB_MODE|FREQ48kHz|ASC_CLKNODIV|ASC_CLK_DISABLE;
+ //2Config audio interface
+ rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_MASTER_MODE|ASC_NORMAL_BCLK);
+ rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_DISABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_8); //BCLK div 8
+ //2volume,input,outpu
+ rk610_codec_write(codec,ACCELCODEC_R05, 0x0e);
+ rk610_codec_write(codec,ACCELCODEC_R06, 0x42);
+ rk610_codec_write(codec,ACCELCODEC_R07, 0x0e);
+ rk610_codec_write(codec,ACCELCODEC_R08, 0x42);
+
+ rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB|ASC_INPUT_MUTE); //LIL
+ rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB); //LIR
+ rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|ASC_INPUT_VOL_0DB); //MIC
+ rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB); //mic input and boost 20dB
+ rk610_codec_write(codec,ACCELCODEC_R13, ASC_LPGAMX_DISABLE|ASC_ALMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0);
+ rk610_codec_write(codec,ACCELCODEC_R14, ASC_RPGAMX_DISABLE|ASC_ARMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0);
+ gR1314Reg = ASC_RPGAMX_DISABLE|ASC_ARMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0;
+
+ //2other
+ rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00
+ gR0BReg = ASC_DEC_DISABLE|ASC_INT_DISABLE;
+ rk610_codec_write(codec,ACCELCODEC_R15, \
+ 0x01|ASC_RLPFMX_DISABLE|ASC_LLPFMX_DISABLE|ASC_LDAMX_DISABLE|ASC_RDAMX_DISABLE|ASC_LSCF_ACTIVE|ASC_RSCF_ACTIVE); //0x3c
+ rk610_codec_write(codec,ACCELCODEC_R1B, 0x32);
+ rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); ///0x00); //use default value
+
+ ///dac mode
+ rk610_codec_write(codec,ACCELCODEC_R17, 0xBF); //AOL ÒôÁ¿×îµÍ
+ rk610_codec_write(codec,ACCELCODEC_R18, 0xBF); //AOR
+
+ //2power down useless module
+ rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a|ASC_PDSDL_ENABLE|ASC_PDBSTL_ENABLE|ASC_PDPGAL_ENABLE); //setup Vmid and Vref, other module power down
+ rk610_codec_write(codec,ACCELCODEC_R1E, 0x40|ASC_PDASDML_ENABLE);
+ #if OUT_CAPLESS
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE);
+ #else
+ rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
+ #endif
+
+ //2other
+ rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE);
+ gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE; //ASC_DEC_DISABLE|ASC_INT_ENABLE;
+ rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);//rk610_codec_write(codec,ACCELCODEC_R15, 0xCD);//by Vincent Hsiung
+ rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB); //LIL
+ rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB); //LIR
+ rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|ASC_INPUT_VOL_0DB); //MIC
+// rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB); //mic input and boost 20dB
+ rk610_codec_write(codec,ACCELCODEC_R12, 0x4c); //line input and boost 20dB
+ rk610_codec_write(codec,ACCELCODEC_R13, 0x00);
+ rk610_codec_write(codec,ACCELCODEC_R14, 0x00);
+ gR1314Reg = 0x00;
+ rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); //0x00); //use default value
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static int rk610_codec_probe(struct snd_soc_codec *codec)
+{
+ struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int ret;
+
+ rk610_codec_codec = codec;
+ printk(KERN_ERR "[%s] start\n", __FUNCTION__);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, rk610_codec->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+ //For RK610, i2c write&read method is special, do not use system default method.
+ codec->write = rk610_codec_write;
+ codec->read = rk610_codec_read;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+#else
+static int rk610_codec_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+ int ret = 0;
+#endif
+ if (rk610_codec_codec == NULL) {
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ dev_err(codec->dev, "Codec device not registered\n");
+ #else
+ dev_err(&pdev->dev, "Codec device not registered\n");
+ #endif
+ return -ENODEV;
+ }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+ socdev->card->codec = rk610_codec_codec;
+ codec = rk610_codec_codec;
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+ goto pcm_err;
+ }
+#endif
+
+ snd_soc_add_controls(codec, rk610_codec_snd_controls,
+ ARRAY_SIZE(rk610_codec_snd_controls));
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+ snd_soc_dapm_new_controls(codec, rk610_codec_dapm_widgets,
+ ARRAY_SIZE(rk610_codec_dapm_widgets));
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_new_widgets(codec);
+
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to register card: %d\n", ret);
+ goto card_err;
+ }
+#else
+ snd_soc_dapm_new_controls(dapm, rk610_codec_dapm_widgets,
+ ARRAY_SIZE(rk610_codec_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+
+#endif
+
+#if defined(RK610_SPK_CTRL_PIN)
+ ret = gpio_request(RK610_SPK_CTRL_PIN, "rk610 spk_ctrl");
+ if (ret){
+ printk("rk610_control request gpio fail\n");
+ //goto err1;
+ }
+ gpio_set_value(RK610_SPK_CTRL_PIN, GPIO_HIGH);
+ gpio_direction_output(RK610_SPK_CTRL_PIN, GPIO_HIGH);
+#endif
+
+ rk610_control_init_codec();
+
+ rk610_codec_reg_set();
+ rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return ret;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
+ return ret;
+#endif
+}
+
+/* power down chip */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static int rk610_codec_remove(struct snd_soc_codec *codec)
+{
+ rk610_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+#else
+static int rk610_codec_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ printk("rk610_codec_remove\n");
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+ return 0;
+}
+#endif
+
+static struct snd_soc_codec_driver soc_codec_dev_rk610_codec = {
+ .probe = rk610_codec_probe,
+ .remove = rk610_codec_remove,
+ .suspend = rk610_codec_suspend,
+ .resume = rk610_codec_resume,
+ .set_bias_level = rk610_codec_set_bias_level,
+// .volatile_register = wm8900_volatile_register,
+ .reg_cache_size = ARRAY_SIZE(rk610_codec_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = rk610_codec_reg,
+ .dapm_widgets = rk610_codec_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rk610_codec_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+EXPORT_SYMBOL_GPL(soc_codec_dev_rk610_codec);
+
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int rk610_codec_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct rk610_codec_priv *rk610_codec;
+ int ret;
+ printk("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ %s start $$$$$$$$$$$$$$$$$$$$$$$$$$$\n", __FUNCTION__);
+ rk610_codec = kzalloc(sizeof(struct rk610_codec_priv), GFP_KERNEL);
+ if (rk610_codec == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, rk610_codec);
+ rk610_codec->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_rk610_codec, &rk610_codec_dai, 1);
+ if (ret < 0) {
+ printk("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %s: snd_soc_register_codec error!!!!\n", __FUNCTION__);
+ dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+ kfree(rk610_codec);
+ }
+ return ret;
+}
+
+
+static int rk610_codec_i2c_remove(struct i2c_client *client)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+#else
+ struct rk610_codec_priv *rk610_codec = i2c_get_clientdata(client);
+ rk610_codec_unregister(rk610_codec);
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int rk610_codec_i2c_suspend(struct i2c_client *client, pm_message_t msg)
+{
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ return 0;
+ #else
+ return snd_soc_suspend_device(&client->dev);
+ #endif
+}
+
+static int rk610_codec_i2c_resume(struct i2c_client *client)
+{
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ return 0;
+ #else
+ return snd_soc_resume_device(&client->dev);
+ #endif
+}
+#else
+#define rk610_codec_i2c_suspend NULL
+#define rk610_codec_i2c_resume NULL
+#endif
+
+static const struct i2c_device_id rk610_codec_i2c_id[] = {
+ { "rk610_i2c_codec", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rk610_codec_i2c_id);
+
+/* corgi i2c codec control layer */
+static struct i2c_driver rk610_codec_i2c_driver = {
+ .driver = {
+ .name = "RK610_CODEC",
+ .owner = THIS_MODULE,
+ },
+ .probe = rk610_codec_i2c_probe,
+ .remove = rk610_codec_i2c_remove,
+ //.suspend = rk610_codec_i2c_suspend,
+ //.resume = rk610_codec_i2c_resume,
+ .id_table = rk610_codec_i2c_id,
+};
+#endif
+
+static int __init rk610_codec_modinit(void)
+{
+ int ret;
+// DBG("[%s] start\n", __FUNCTION__);
+ ret = i2c_add_driver(&rk610_codec_i2c_driver);
+ if (ret != 0)
+ pr_err("rk610 codec: Unable to register I2C driver: %d\n", ret);
+ return ret;
+}
+module_init(rk610_codec_modinit);
+
+static void __exit rk610_codec_exit(void)
+{
+ i2c_del_driver(&rk610_codec_i2c_driver);
+}
+module_exit(rk610_codec_exit);
+
+MODULE_DESCRIPTION("ASoC RK610 CODEC driver");
+MODULE_AUTHOR("rk@rock-chips.com");
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ *
+ * Copyright (C) 2009 rockchip lhh
+ *
+ * Based on WM8750.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _RK610_CODEC_H
+#define _RK610_CODEC_H
+
+/* RK610 register space */
+
+#define ACCELCODEC_R00 0x00 //ADC High Pass Filter / DSM
+#define ACCELCODEC_R01 0x01 //DITHER power
+#define ACCELCODEC_R02 0x02 //DITHER power
+#define ACCELCODEC_R03 0x03 //DITHER power
+#define ACCELCODEC_R04 0x04 //Soft mute / sidetone gain control
+#define ACCELCODEC_R05 0x05 //Right interpolate filter volume control (MSB)
+#define ACCELCODEC_R06 0x06 //Right interpolate filter volume control (LSB)
+#define ACCELCODEC_R07 0x07 //Left interpolate filter volume control (MSB)
+#define ACCELCODEC_R08 0x08 //Left interpolate filter volume control (LSB)
+#define ACCELCODEC_R09 0x09 //Audio interface control
+#define ACCELCODEC_R0A 0x0A //Sample Rate / CLK control
+#define ACCELCODEC_R0B 0x0B //Decimation filter / Interpolate filter enable
+#define ACCELCODEC_R0C 0x0C //LIN volume
+#define ACCELCODEC_R0D 0x0D //LIP volume
+#define ACCELCODEC_R0E 0x0E //AL volume
+//#define ACCELCODEC_R0F 0x0F //RIN volume
+//#define ACCELCODEC_R10 0x10 //RIP volume
+//#define ACCELCODEC_R11 0x11 //AR volume
+#define ACCELCODEC_R12 0x12 //Input volume
+#define ACCELCODEC_R13 0x13 //Left out mix
+#define ACCELCODEC_R14 0x14 //Right out mix
+#define ACCELCODEC_R15 0x15 //LPF out mix / SCF
+#define ACCELCODEC_R16 0x16 //SCF control
+#define ACCELCODEC_R17 0x17 //LOUT (AOL) volume
+#define ACCELCODEC_R18 0x18 //ROUT (AOR) volume
+#define ACCELCODEC_R19 0x19 //MONOOUT (AOM) volume
+#define ACCELCODEC_R1A 0x1A //MONOOUT / Reference control
+#define ACCELCODEC_R1B 0x1B //Bias Current control
+#define ACCELCODEC_R1C 0x1C //ADC control
+#define ACCELCODEC_R1D 0x1D //Power Mrg 1
+#define ACCELCODEC_R1E 0x1E //Power Mrg 2
+#define ACCELCODEC_R1F 0x1F //Power Mrg 3
+
+#define RK610_CACHE_REGNUM 0x1F
+
+//ACCELCODEC_R00
+#define ASC_HPF_ENABLE (0x1) //high_pass filter
+#define ASC_HPF_DISABLE (0x0)
+
+#define ASC_DSM_MODE_ENABLE (0x1 << 1)
+#define ASC_DSM_MODE_DISABLE (0x0 << 1)
+
+#define ASC_SCRAMBLE_ENABLE (0x1 << 2)
+#define ASC_SCRAMBLE_DISABLE (0x0 << 2)
+
+#define ASC_DITHER_ENABLE (0x1 << 3)
+#define ASC_DITHER_DISABLE (0x0 << 3)
+
+#define ASC_BCLKDIV_4 (0x1 << 4)
+#define ASC_BCLKDIV_8 (0x2 << 4)
+#define ASC_BCLKDIV_16 (0x3 << 4)
+
+//ACCECODEC_R04
+#define ASC_INT_MUTE_L (0x1)
+#define ASC_INT_ACTIVE_L (0x0)
+#define ASC_INT_MUTE_R (0x1 << 1)
+#define ASC_INT_ACTIVE_R (0x0 << 1)
+
+#define ASC_SIDETONE_L_OFF (0x0 << 2)
+#define ASC_SIDETONE_L_GAIN_MAX (0x1 << 2)
+#define ASC_SIDETONE_R_OFF (0x0 << 5)
+#define ASC_SIDETONE_R_GAIN_MAX (0x1 << 5)
+
+
+//ACCELCODEC_R05
+#define ASC_INT_VOL_0DB (0x0)
+
+
+//ACCELCODEC_R09
+#define ASC_DSP_MODE (0x3)
+#define ASC_I2S_MODE (0x2)
+#define ASC_LEFT_MODE (0x1)
+//#define ASC_RIGHT_MODE (0x0)
+
+#define ASC_32BIT_MODE (0x3 << 2)
+#define ASC_24BIT_MODE (0x2 << 2)
+#define ASC_20BIT_MODE (0x1 << 2)
+#define ASC_16BIT_MODE (0x0 << 2)
+
+#define ASC_INVERT_LRCLK (0x1 << 4)
+#define ASC_NORMAL_LRCLK (0x0 << 4)
+
+#define ASC_LRSWAP_ENABLE (0x1 << 5)
+#define ASC_LRSWAP_DISABLE (0x0 << 5)
+
+#define ASC_MASTER_MODE (0x1 << 6)
+#define ASC_SLAVE_MODE (0x0 << 6)
+
+#define ASC_INVERT_BCLK (0x1 << 7)
+#define ASC_NORMAL_BCLK (0x0 << 7)
+
+//ACCELCODEC_R0A
+#define ASC_USB_MODE (0x1)
+#define ASC_NORMAL_MODE (0x0)
+
+#define FREQ96kHz (0x0e << 1)
+#define FREQ48kHz (0x00 << 1)
+#define FREQ441kHz (0x11 << 1)
+#define FREQ32kHz (0x0c << 1)
+#define FREQ24kHz (0x1c << 1)
+#define FREQ2205kHz (0x1B << 1)
+#define FREQ16kHz (0x0a << 1)
+#define FREQ12kHz (0x08 << 1)
+#define FREQ11025kHz (0x19 << 1)
+//#define FREQ9k6Hz 0x09
+#define FREQ8kHz (0x06<<1)
+
+#define ASC_CLKDIV2 (0x1 << 6)
+#define ASC_CLKNODIV (0x0 << 6)
+
+#define ASC_CLK_ENABLE (0x1 << 7)
+#define ASC_CLK_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R0B
+#define ASC_DEC_ENABLE (0x1) //decimation filter enable
+#define ASC_DEC_DISABLE (0x0)
+#define ASC_INT_ENABLE (0x1 << 1) //interpolate filter enable
+#define ASC_INT_DISABLE (0x0 << 1)
+
+//Input
+#define ASC_INPUT_MUTE (0x1 << 7)
+#define ASC_INPUT_ACTIVE (0x0 << 7)
+#define ASC_INPUT_VOL_0DB (0x0)
+
+//ACCELCODEC_R12
+#define ASC_LINE_INPUT (0)
+#define ASC_MIC_INPUT (1 << 7)
+
+#define ASC_MIC_BOOST_0DB (0)
+#define ASC_MIC_BOOST_20DB (1 << 5)
+
+//ACCELCODEC_R13
+#define ASC_LPGAMXVOL_0DB (0x5)
+#define ASC_LPGAMX_ENABLE (0x1 << 3) //the left channel PGA output is directly fed into the left mixer
+#define ASC_LPGAMX_DISABLE (0x0 << 3)
+#define ASC_ALMXVOL_0DB (0x5 << 4)
+#define ASC_ALMX_ENABLE (0x1 << 7) //the left second line input is directly fed into the left mixer
+#define ASC_ALMX_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R14
+#define ASC_RPGAMXVOL_0DB (0x5)
+#define ASC_RPGAMX_ENABLE (0x1 << 3) //the right channel PGA output is directly fed into the right mixer
+#define ASC_RPGAMX_DISABLE (0x0 << 3)
+#define ASC_ARMXVOL_0DB (0x5 << 4)
+#define ASC_ARMX_ENABLE (0x1 << 7) //)the right second line input is directly fed into the right mixer
+#define ASC_ARMX_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R15
+#define ASC_LDAMX_ENABLE (0x1 << 2) //the left differential signal from DAC is directly fed into the left mixer
+#define ASC_LDAMX_DISABLE (0x0 << 2)
+#define ASC_RDAMX_ENABLE (0x1 << 3) //the right differential signal from DAC is directly fed into the right mixer
+#define ASC_RDAMX_DISABLE (0x0 << 3)
+#define ASC_LSCF_MUTE (0x1 << 4) //the left channel LPF is mute
+#define ASC_LSCF_ACTIVE (0x0 << 4)
+#define ASC_RSCF_MUTE (0x1 << 5) //the right channel LPF is mute
+#define ASC_RSCF_ACTIVE (0x0 << 5)
+#define ASC_LLPFMX_ENABLE (0x1 << 6) //the left channel LPF output is fed into the left into the mixer
+#define ASC_LLPFMX_DISABLE (0x0 << 6)
+#define ASC_RLPFMX_ENABLE (0x1 << 7) //the right channel LPF output is fed into the right into the mixer.
+#define ASC_RLPFMX_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R17/R18
+#define ASC_OUTPUT_MUTE (0x1 << 6)
+#define ASC_OUTPUT_ACTIVE (0x0 << 6)
+#define ASC_CROSSZERO_EN (0x1 << 7)
+#define ASC_OUTPUT_VOL_0DB (0x0F)
+//ACCELCODEC_R19
+#define ASC_MONO_OUTPUT_MUTE (0x1 << 7)
+#define ASC_MONO_OUTPUT_ACTIVE (0x0 << 7)
+#define ASC_MONO_CROSSZERO_EN (0x1 << 6)
+
+//ACCELCODEC_R1A
+#define ASC_VMDSCL_SLOWEST (0x0 << 2)
+#define ASC_VMDSCL_SLOW (0x1 << 2)
+#define ASC_VMDSCL_FAST (0x2 << 2)
+#define ASC_VMDSCL_FASTEST (0x3 << 2)
+
+#define ASC_MICBIAS_09 (0x1 << 4)
+#define ASC_MICBIAS_06 (0x0 << 4)
+
+#define ASC_L2M_ENABLE (0x1 << 5) //the right channel LPF output is fed to mono PA
+#define ASC_L2M_DISABLE (0x0 << 5)
+#define ASC_R2M_ENABLE (0x1 << 6) //the left channel LPF output is fed to mono PA
+#define ASC_R2M_DISABLE (0x0 << 6)
+#define ASC_CAPLESS_ENABLE (0x1 << 7) //the capless connection is enable
+#define ASC_CAPLESS_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R1C
+#define ASC_DITH_0_DIV (0x0 << 3) //the amplitude setting of the ASDM dither(div=vdd/48)
+#define ASC_DITH_2_DIV (0x1 << 3)
+#define ASC_DITH_4_DIV (0x2 << 3)
+#define ASC_DITH_8_DIV (0x3 << 3)
+
+#define ASC_DITH_ENABLE (0x1 << 5) //the ASDM dither is enabled
+#define ASC_DITH_DISABLE (0x0 << 5)
+
+#define ASC_DEM_ENABLE (0x1 << 7) //the ASDM DEM is enabled
+#define ASC_DEM_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R1D
+#define ASC_PDVMID_ENABLE (0x1) //the VMID reference is powered down. VMID is connected to GND
+#define ASC_PDVMID_DISABLE (0x0)
+#define ASC_PDSDL_ENABLE (0x1 << 2) //the PGA S2D buffer is power down
+#define ASC_PDSDL_DISABLE (0x0 << 2)
+#define ASC_PDBSTL_ENABLE (0x1 << 4) //the micphone input Op-Amp is power down
+#define ASC_PDBSTL_DISABLE (0x0 << 4)
+#define ASC_PDPGAL_ENABLE (0x1 << 6) //the PGA is power down
+#define ASC_PDPGAL_DISABLE (0x0 << 6)
+#define ASC_PDREF_ENABLE (0x1 << 7) //reference generator is power down
+#define ASC_PDREF_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R1E
+#define ASC_PDPAR_ENABLE (0x1) //the right channel PA is power down
+#define ASC_PDPAR_DISABLE (0x0)
+#define ASC_PDPAL_ENABLE (0x1 << 1) //the left channel power amplifier is power down
+#define ASC_PDPAL_DISABLE (0x0 << 1)
+#define ASC_PDMIXR_ENABLE (0x1 << 2) //the right mixer is power down
+#define ASC_PDMIXR_DISABLE (0x0 << 2)
+#define ASC_PDMIXL_ENABLE (0x1 << 3) //the left mixer is power down
+#define ASC_PDMIXL_DISABLE (0x0 << 3)
+#define ASC_PDLPFR_ENABLE (0x1 << 4) //the right RC LPF is power down
+#define ASC_PDLPFR_DISABLE (0x0 << 4)
+#define ASC_PDLPFL_ENABLE (0x1 << 5) //the left channel RC LPF is power down
+#define ASC_PDLPFL_DISABLE (0x0 << 5)
+#define ASC_PDASDML_ENABLE (0x1 << 7) //the ASDM is power down
+#define ASC_PDASDML_DISABLE (0x0 << 7)
+
+//ACCELCODEC_R1F
+#define ASC_PDSCFR_ENABLE (0x1 << 1) //the right channel DAC is power down
+#define ASC_PDSCFR_DISABLE (0x0 << 1)
+#define ASC_PDSCFL_ENABLE (0x1 << 2) //the left channel DAC is power down
+#define ASC_PDSCFL_DISABLE (0x0 << 2)
+#define ASC_PDMICB_ENABLE (0x1 << 4) //the micbias is power down
+#define ASC_PDMICB_DISABLE (0x0 << 4)
+#define ASC_PDIB_ENABLE (0x1 << 5) //the left channel LPF is power down
+#define ASC_PDIB_DISABLE (0x0 << 5)
+#define ASC_PDMIXM_ENABLE (0x1 << 6) //the mon mixer is power down
+#define ASC_PDMIXM_DISABLE (0x0 << 6)
+#define ASC_PDPAM_ENABLE (0x1 << 7) //the mono PA is power down.
+#define ASC_PDPAM_DISABLE (0x0 << 7)
+
+#define LINE_2_MIXER_GAIN (0x5) //left and right PA gain
+#define RK610_CODEC_NUM_REG 0x20
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37))
+extern struct snd_soc_dai rk610_codec_dai;
+extern struct snd_soc_codec_device soc_codec_dev_rk610_codec;
+#endif
+
+#endif
endchoice
endif
+config SND_RK29_SOC_SPDIF
+ bool "Soc RK29 SPDIF support"
+ depends on SND_RK29_SOC
+ depends on SND_RK29_SOC_I2S
+ help
+ This supports the use of SPDIF interface on rk29 processors
config SND_RK29_SOC_WM8988
tristate "SoC I2S Audio support for rockchip - WM8988"
depends on SND_RK29_SOC
help
Say Y if you want to add support for SoC audio on rockchip
with the RK1000.
+config SND_RK29_SOC_HDMI
+ tristate "SoC I2S Audio support for rockchip - HDMI"
+ depends on SND_RK29_SOC && HDMI_ITV
+ select SND_RK29_SOC_I2S
+ help
+ Say Y if you want to add support for SoC audio on rockchip
+ with the HDMI.
+config SND_RK29_SOC_RK610
+ tristate "SoC I2S Audio support for rockchip - RK610"
+ depends on SND_RK29_SOC && MFD_RK610 && I2C_RK29
+ select SND_RK29_SOC_I2S
+ select SND_SOC_RK610
+ help
+ Say Y if you want to add support for SoC audio on rockchip
+ with the RK610(JETTA).
-if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_RT5621 || SND_RK29_SOC_RT5631 || SND_RK29_SOC_RT5625 || SND_RK29_SOC_CS42L52 || SND_RK29_SOC_AIC3111
+if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_RT5621 || SND_RK29_SOC_RT5631 || SND_RK29_SOC_RT5625 || SND_RK29_SOC_CS42L52 || SND_RK29_SOC_AIC3111 || SND_RK29_SOC_HDMI || SND_RK29_SOC_RK610
choice
bool "Set i2s type"
default SND_RK29_CODEC_SOC_SLAVE
ifdef CONFIG_ARCH_RK30
snd-soc-rockchip-i2s-objs := rk30_i2s.o
endif
+snd-soc-rockchip-spdif-objs := rk29_spdif.o
obj-$(CONFIG_SND_RK29_SOC) += snd-soc-rockchip.o
obj-$(CONFIG_SND_RK29_SOC_I2S) += snd-soc-rockchip-i2s.o
+obj-$(CONFIG_SND_RK29_SOC_SPDIF) += snd-soc-rockchip-spdif.o
# ROCKCHIP Machine Support
snd-soc-wm8900-objs := rk29_wm8900.o
snd-soc-wm8988-objs := rk29_wm8988.o
snd-soc-rk1000-objs := rk29_rk1000codec.o
snd-soc-wm8994-objs := rk29_wm8994.o
+snd-soc-hdmi-objs := rk29_hdmi.o
+snd-soc-rk610-objs := rk29_jetta_codec.o
obj-$(CONFIG_SND_RK29_SOC_WM8994) += snd-soc-wm8994.o
obj-$(CONFIG_SND_RK29_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_RK29_SOC_RK1000) += snd-soc-rk1000.o
obj-$(CONFIG_SND_RK29_SOC_CS42L52) += snd-soc-cs42l52.o
obj-$(CONFIG_SND_RK29_SOC_AIC3111) += snd-soc-aic3111.o
+obj-$(CONFIG_SND_RK29_SOC_HDMI) += snd-soc-hdmi.o
+obj-$(CONFIG_SND_RK29_SOC_RK610) += snd-soc-rk610.o
\ No newline at end of file
--- /dev/null
+/*
+ * rk29_wm8988.c -- SoC audio for rockchip
+ *
+ * Driver for rockchip wm8988 audio
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/rk29_iomap.h>
+#include "../codecs/rk610_codec.h"
+#include "rk29_pcm.h"
+#include "rk29_i2s.h"
+
+#if 0
+#define DBG(x...) printk(KERN_ERR x)
+#else
+#define DBG(x...)
+#endif
+
+static int rk29_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+#else
+ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+#endif
+ int ret;
+ unsigned int pll_out = 0;
+ int div_bclk,div_mclk;
+// struct clk *general_pll;
+
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ /*by Vincent Hsiung for EQ Vol Change*/
+ #define HW_PARAMS_FLAG_EQVOL_ON 0x21
+ #define HW_PARAMS_FLAG_EQVOL_OFF 0x22
+ if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
+ {
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent
+ #else
+ ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent
+ #endif
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ }
+ else
+ {
+ /* set codec DAI configuration */
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ ret = codec_dai->driver->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ #else
+ ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ #endif
+ #endif
+ #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ ret = codec_dai->driver->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
+ #else
+ ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
+ #endif
+ #endif
+ if (ret < 0)
+ return ret;
+ /* set cpu DAI configuration */
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ ret = cpu_dai->driver->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ #else
+ ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ #endif
+ #endif
+ #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ ret = cpu_dai->driver->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ #else
+ ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ #endif
+ #endif
+ if (ret < 0)
+ return ret;
+ }
+
+ switch(params_rate(params)) {
+ case 8000:
+ case 16000:
+ case 24000:
+ case 32000:
+ case 48000:
+ case 96000:
+ pll_out = 12288000;
+ break;
+ case 11025:
+ case 22050:
+ case 44100:
+ case 88200:
+ pll_out = 11289600;
+ break;
+ case 176400:
+ pll_out = 11289600*2;
+ break;
+ case 192000:
+ pll_out = 12288000*2;
+ break;
+ default:
+ DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
+ return -EINVAL;
+ break;
+ }
+ DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
+ snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
+
+// #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
+// snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
+// #endif
+ #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
+ div_bclk = 63;
+ div_mclk = pll_out/(params_rate(params)*64) - 1;
+
+ DBG("func is%s,pll_out=%ld,div_mclk=%ld div_bclk=%ld\n",
+ __FUNCTION__,pll_out,div_mclk, div_bclk);
+ snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
+ snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
+ snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
+// DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
+ #endif
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget rk29_dapm_widgets[] = {
+ SND_SOC_DAPM_LINE("Audio Out", NULL),
+ SND_SOC_DAPM_LINE("Line in", NULL),
+ SND_SOC_DAPM_MIC("Micn", NULL),
+ SND_SOC_DAPM_MIC("Micp", NULL),
+};
+
+static const struct snd_soc_dapm_route audio_map[]= {
+
+ {"Audio Out", NULL, "LOUT1"},
+ {"Audio Out", NULL, "ROUT1"},
+ {"Line in", NULL, "RINPUT1"},
+ {"Line in", NULL, "LINPUT1"},
+// {"Micn", NULL, "RINPUT2"},
+// {"Micp", NULL, "LINPUT2"},
+};
+
+/*
+ * Logic for a RK610 codec as connected on a rockchip board.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static int rk29_RK610_codec_init(struct snd_soc_pcm_runtime *rtd) {
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ /* Add specific widgets */
+ snd_soc_dapm_new_controls(dapm, rk29_dapm_widgets,
+ ARRAY_SIZE(rk29_dapm_widgets));
+
+ /* Set up specific audio path audio_mapnects */
+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ snd_soc_dapm_sync(dapm);
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+
+ return 0;
+}
+#else
+static int rk29_RK610_codec_init(struct snd_soc_codec *codec) {
+// struct snd_soc_dai *codec_dai = &codec->dai[0];
+ int ret;
+
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+
+// ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+// 11289600, SND_SOC_CLOCK_IN);
+// if (ret < 0) {
+// printk(KERN_ERR "Failed to set WM8988 SYSCLK: %d\n", ret);
+// return ret;
+// }
+
+ /* Add specific widgets */
+ snd_soc_dapm_new_controls(codec, rk29_dapm_widgets,
+ ARRAY_SIZE(rk29_dapm_widgets));
+
+ /* Set up specific audio path audio_mapnects */
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+ snd_soc_dapm_sync(codec);
+
+ return 0;
+}
+#endif
+static struct snd_soc_ops rk29_ops = {
+ .hw_params = rk29_hw_params,
+};
+
+static struct snd_soc_dai_link rk29_dai = {
+ .name = "RK610",
+ .stream_name = "RK610 CODEC PCM",
+ .codec_name = "RK610_CODEC.1-0060",
+ .platform_name = "rockchip-audio",
+#if defined(CONFIG_SND_RK29_SOC_I2S_8CH)
+ .cpu_dai_name = "rk29_i2s.0",
+#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
+ .cpu_dai_name = "rk29_i2s.1",
+#endif
+ .codec_dai_name = "rk610_codec_xx",
+ .init = rk29_RK610_codec_init,
+ .ops = &rk29_ops,
+};
+static struct snd_soc_card snd_soc_card_rk29 = {
+ .name = "RK29_RK610",
+ .dai_link = &rk29_dai,
+ .num_links = 1,
+};
+
+static struct platform_device *rk29_snd_device;
+
+static int __init audio_card_init(void)
+{
+ int ret =0;
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ printk(KERN_ERR "[%s] start\n", __FUNCTION__);
+ rk29_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!rk29_snd_device) {
+ printk("[%s] platform device allocation failed\n", __FUNCTION__);
+ ret = -ENOMEM;
+ return ret;
+ }
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+ platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29);
+ #else
+ platform_set_drvdata(rk29_snd_device, &rk29_snd_devdata);
+ rk29_snd_devdata.dev = &rk29_snd_device->dev;
+ #endif
+ ret = platform_device_add(rk29_snd_device);
+ DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+ if (ret) {
+ DBG("platform device add failed\n");
+ platform_device_put(rk29_snd_device);
+ }
+ return ret;
+}
+static void __exit audio_card_exit(void)
+{
+ platform_device_unregister(rk29_snd_device);
+}
+
+module_init(audio_card_init);
+module_exit(audio_card_exit);
+/* Module information */
+MODULE_AUTHOR("rockchip");
+MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
+MODULE_LICENSE("GPL");