rk2928 rk610 rk616 lvds:indepent from screen config file
authoryxj <yxj@rock-chips.com>
Fri, 31 May 2013 04:23:48 +0000 (12:23 +0800)
committeryxj <yxj@rock-chips.com>
Fri, 14 Jun 2013 04:58:16 +0000 (12:58 +0800)
drivers/mfd/rk610-core.c
drivers/video/rockchip/transmitter/rk2928_lvds.c
drivers/video/rockchip/transmitter/rk610_lcd.c
drivers/video/rockchip/transmitter/rk616_lvds.c
include/linux/mfd/rk610_core.h
include/linux/rk_screen.h

index f9011f89e70953c570dbbead973ec113531a333a..e511a1c29492ff4e3b26a08c85c8ccc66e29c23d 100755 (executable)
@@ -4,20 +4,23 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <asm/gpio.h>
+#include <linux/mfd/core.h>
 #include <linux/mfd/rk610_core.h>
 #include <linux/clk.h>
 #include <mach/iomux.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
-#if defined(CONFIG_ARCH_RK3066B)
-#define RK610_RESET_PIN   RK30_PIN2_PC5
-#elif defined(CONFIG_ARCH_RK30)
-#define RK610_RESET_PIN   RK30_PIN0_PC6
-#else
-#define RK610_RESET_PIN   RK29_PIN6_PC1
+#if defined(CONFIG_DEBUG_FS)
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+
 #endif
 
+
+
 /*
  * Debug
  */
 #endif
 
 static struct i2c_client *rk610_control_client = NULL;
-#ifdef CONFIG_RK610_LVDS
-extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);
-#else
-int rk610_lcd_init(struct rk610_core_info *rk610_core_info){}
-#endif
+
+
+static struct mfd_cell rk610_devs[] = {
+       {
+               .name = "rk610-lcd",
+               .id = 0,
+       },
+};
+
 int rk610_control_send_byte(const char reg, const char data)
 {
        int ret;
@@ -157,7 +164,7 @@ void rk610_control_init_codec(void)
     DBG("[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
 }
 #endif
-#ifdef 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;
@@ -167,43 +174,58 @@ 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++)
+#if defined(CONFIG_DEBUG_FS)
+static int rk610_reg_show(struct seq_file *s, void *v)
+{
+       char reg = 0;
+       u8 val = 0;
+       struct rk610_core_info *core_info = s->private;
+       if(!core_info)
        {
-               rk610_read_p0_reg(client, i,  &val);
-               if(i%16==0)
-                       size += sprintf(buf+size,"\n>>>rk610_ctl %x:",i);
-               size += sprintf(buf+size," %2x",val);
+               dev_err(core_info->dev,"no mfd rk610!\n");
+               return 0;
        }
 
-       return size;
+       for(reg=C_PLL_CON0;reg<= I2C_CON;reg++)
+       {
+               rk610_read_p0_reg(core_info->client, reg,  &val);
+               if(reg%8==0)
+                       seq_printf(s,"\n0x%02x:",reg);
+               seq_printf(s," %02x",val);
+       }
+       seq_printf(s,"\n");
+
+       return 0;
+}
+
+static ssize_t rk610_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{ 
+       struct rk610_core_info *core_info = file->f_path.dentry->d_inode->i_private;
+       u32 reg,val;
+       
+       char kbuf[25];
+       if (copy_from_user(kbuf, buf, count))
+               return -EFAULT;
+       sscanf(kbuf, "%x%x", &reg,&val);
+       rk610_write_p0_reg(core_info->client, reg,  (u8*)&val);
+       return count;
 }
-static ssize_t rk610_store_reg_attrs(struct device *dev,
-                                               struct device_attribute *attr,
-                                               const char *buf, size_t size)
+
+static int rk610_reg_open(struct inode *inode, struct file *file)
 {
-       struct i2c_client *client=NULL;
-       static char val=0,reg=0;
-       client = rk610_control_client;
-       DBG("/**********rk610 reg config******/");
-
-       sscanf(buf, "%x%x", &val,&reg);
-       DBG("reg=%x val=%x\n",reg,val);
-       rk610_write_p0_reg(client, reg,  &val);
-       DBG("val=%x\n",val);
-       return size;
+       struct rk610_core_info *core_info = inode->i_private;
+       return single_open(file,rk610_reg_show,core_info);
 }
 
-static struct device_attribute rk610_attrs[] = {
-       __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
+static const struct file_operations rk610_reg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = rk610_reg_open,
+       .read           = seq_read,
+       .write          = rk610_reg_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
 };
 #endif
 
@@ -248,14 +270,25 @@ static int rk610_control_probe(struct i2c_client *client,
        }
 
        rk610_control_client = client;
-       msleep(100);
        if(core_info->pdata->rk610_power_on_init)
                core_info->pdata->rk610_power_on_init();
        core_info->client = client;
-       rk610_lcd_init(core_info);
-#ifdef RK610_DEBUG
-       device_create_file(&(client->dev), &rk610_attrs[0]);
+       core_info->dev = &client->dev;
+       i2c_set_clientdata(client,core_info);
+       ret = mfd_add_devices(&client->dev, -1,
+                                     rk610_devs, ARRAY_SIZE(rk610_devs),
+                                     NULL,0);
+       
+#if defined(CONFIG_DEBUG_FS)
+       core_info->debugfs_dir = debugfs_create_dir("rk610", NULL);
+       if (IS_ERR(core_info->debugfs_dir))
+       {
+               dev_err(&client->dev,"failed to create debugfs dir for rk610!\n");
+       }
+       else
+               debugfs_create_file("core", S_IRUSR,core_info->debugfs_dir,core_info,&rk610_reg_fops);
 #endif
+
     return 0;
 }
 
@@ -281,7 +314,6 @@ static struct i2c_driver rk610_control_driver = {
 
 static int __init rk610_control_init(void)
 {
-       DBG("[%s] start\n", __FUNCTION__);
        return i2c_add_driver(&rk610_control_driver);
 }
 
@@ -291,7 +323,6 @@ static void __exit rk610_control_exit(void)
 }
 
 subsys_initcall_sync(rk610_control_init);
-//module_init(rk610_control_init);
 module_exit(rk610_control_exit);
 
 
index 1c130cea26ea0af9d15b16b21f219a872294970f..1686be30d1d3953012026e44e9226cfeccad6250 100644 (file)
@@ -9,7 +9,7 @@ static void rk_output_lvds(rk_screen *screen)
 {
        LVDSWrReg(m_PDN_CBG(1)|m_PD_PLL(0)|m_PDN(1)|m_OEN(0)    \
                                        |m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB)    \
-                                       |m_OUT_FORMAT(screen->hw_format)                \
+                                       |m_OUT_FORMAT(screen->lvds_format)              \
                                        |m_LCDC_SEL(screen->lcdc_id));
 
        printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
@@ -19,7 +19,7 @@ static void rk_output_lvttl(rk_screen *screen)
 {
        LVDSWrReg(m_PDN_CBG(0)|m_PD_PLL(1)|m_PDN(0)|m_OEN(1)    \
                                        |m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB)    \
-                                       |m_OUT_FORMAT(screen->hw_format)                \
+                                       |m_OUT_FORMAT(screen->lvds_format)              \
                                        |m_LCDC_SEL(screen->lcdc_id));
         printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
 }
index ef51241959c269ef6bb81fe0a5dc0cb6978812d9..fe58f4422b97a6d1ee9335da5400657b7dddc8e7 100644 (file)
-#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 "rk610_lcd.h"\r
-#include <linux/mfd/rk610_core.h>\r
-#include <linux/rk_fb.h>\r
-#include "../../rockchip/hdmi/rk_hdmi.h"\r
-\r
-static struct rk610_lcd_info *g_lcd_inf = 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
-\r
-    g_lcd_inf->scl_inf.pll_pwr = ENABLE;\r
-    \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
-    \r
-    g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
-\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
-    bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-    g_lcd_inf->scl_inf.scl_pwr = ENABLE;\r
-    #if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)\r
-    if(g_lcd_inf->screen !=NULL){\r
-        den_inv = g_lcd_inf->screen->s_den_inv;\r
-        hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
-        clk_inv = g_lcd_inf->screen->s_clk_inv;\r
-    }\r
-    #endif\r
-    c= SCL_BYPASS(0) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |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
-    bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-    \r
-    g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
-    #if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)\r
-    if(g_lcd_inf->screen !=NULL){\r
-        den_inv = g_lcd_inf->screen->s_den_inv;\r
-        hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
-        clk_inv = g_lcd_inf->screen->s_clk_inv;\r
-    }\r
-    #endif\r
-    c= SCL_BYPASS(1) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(DISABLE); \r
-    rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
-}\r
-\r
-static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode)\r
-{\r
-    char c=0;\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-     if(SCREEN_LVDS == screen->type){\r
-        if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\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) | LVDS_BIASE_PWR(1); \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
-           }\r
-           else{\r
-               c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \\r
-                |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
-                |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(0); \r
-               rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
-            c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); \r
-               rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
-             \r
-           }\r
-       }else if(SCREEN_RGB == screen->type){\r
-           if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\r
-            c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0);\r
-               rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
-           }\r
-           else {\r
-            c = LCD1_OUT_ENABLE(LCD1_AS_IN);\r
-               rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
-           }\r
-       }\r
-       return 0;\r
-}\r
-#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)\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_16_9:\r
-        case HDMI_720x576p_50Hz_4_3:\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_16_9:\r
-        case HDMI_720x480p_60Hz_4_3:\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
-    return 0;\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_disable(client);       \r
-    rk610_scaler_pll_disable(client);\r
-    \r
-    return 0;\r
-}\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-static void rk610_lcd_early_suspend(struct early_suspend *h)\r
-{\r
-    struct i2c_client *client = g_lcd_inf->client;\r
-    char c;\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-    if(g_lcd_inf->screen != NULL){\r
-        rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE);\r
-    }\r
-\r
-    if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\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
-    if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\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
-}\r
-\r
-static void rk610_lcd_early_resume(struct early_suspend *h)\r
-{\r
-    struct i2c_client *client = g_lcd_inf->client;\r
-    char c;\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-\r
-    if(g_lcd_inf->screen != NULL){\r
-        rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode);\r
-    }\r
-    if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\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
-    if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\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
-}\r
-#endif\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 = g_lcd_inf->client;\r
-    if(client == NULL){\r
-        printk("%s client == NULL FAIL\n",__FUNCTION__);\r
-        return -1;\r
-    }\r
-    if(screen == NULL){\r
-        printk("%s screen == NULL FAIL\n",__FUNCTION__);\r
-        return -1;\r
-    }\r
-    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-    \r
-    g_lcd_inf->screen = screen;\r
-    \r
-#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)\r
-    if(enable == 1){\r
-        g_lcd_inf->disp_mode = LCD_OUT_SCL;\r
-        rk610_output_config(client,screen,LCD_OUT_SCL);\r
-        ret = rk610_scaler_chg(client,screen);\r
-       }\r
-       else \r
-#endif\r
-       {\r
-           g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
-           rk610_output_config(client,screen,LCD_OUT_BYPASS);\r
-           ret = rk610_lcd_scaler_bypass(client,enable);\r
-       }\r
-       return ret;\r
-}\r
-int rk610_lcd_init(struct rk610_core_info *rk610_core_info)\r
-{\r
-    if(rk610_core_info->client == NULL){\r
-        printk("%s client == NULL FAIL\n",__FUNCTION__);\r
-        return -1;\r
-    }\r
-    RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__);\r
-\r
-    g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL);\r
-    if(!g_lcd_inf)\r
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <mach/gpio.h>
+#include <mach/iomux.h>
+#include <mach/board.h>
+#include "rk610_lcd.h"
+#include <linux/mfd/rk610_core.h>
+#include <linux/rk_fb.h>
+#include "../hdmi/rk_hdmi.h"
+
+static struct rk610_lcd_info *g_lcd_inf = NULL;
+//static int rk610_scaler_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_scaler_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 void rk610_scaler_pll_enable(struct i2c_client *client)
+{
+    char c;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+
+    g_lcd_inf->scl_inf.pll_pwr = ENABLE;
+    
+    c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0);
+       rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
+}
+static void rk610_scaler_pll_disable(struct i2c_client *client)
+{
+    char c;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    
+    g_lcd_inf->scl_inf.pll_pwr = DISABLE;
+
+    c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
+       rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
+}
+static void rk610_scaler_enable(struct i2c_client *client)
+{
+    char c;
+    bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    g_lcd_inf->scl_inf.scl_pwr = ENABLE;
+    #if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+    if(g_lcd_inf->screen !=NULL){
+        den_inv = g_lcd_inf->screen->s_den_inv;
+        hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;
+        clk_inv = g_lcd_inf->screen->s_clk_inv;
+    }
+    #endif
+    c= SCL_BYPASS(0) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(ENABLE);  
+       rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
+}
+static void rk610_scaler_disable(struct i2c_client *client)
+{
+    char c;
+    bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    
+    g_lcd_inf->scl_inf.scl_pwr = DISABLE;
+    #if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+    if(g_lcd_inf->screen !=NULL){
+        den_inv = g_lcd_inf->screen->s_den_inv;
+        hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;
+        clk_inv = g_lcd_inf->screen->s_clk_inv;
+    }
+    #endif
+    c= SCL_BYPASS(1) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(DISABLE); 
+    rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
+}
+
+static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode)
+{
+    char c=0;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+     if(SCREEN_LVDS == screen->type){
+        if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){
+            c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \
+                |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \
+                |LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_BIASE_PWR(1); 
+               rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);
+            c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); 
+               rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);
+           }
+           else{
+               c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \
+                |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \
+                |LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_BIASE_PWR(0); 
+               rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);
+            c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); 
+               rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);
+             
+           }
+       }else if(SCREEN_RGB == screen->type){
+           if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){
+            c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0);
+               rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
+           }
+           else {
+            c = LCD1_OUT_ENABLE(LCD1_AS_IN);
+               rk610_scaler_write_p0_reg(client, LCD1_CON, &c);
+           }
+       }
+       return 0;
+}
+#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin )
+{
+    char c=0;
+    char M=0,N=0,OD=0;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+       /***************SET SCALER PLL FROM CLKIN ,DIV 0*/
+    if(screen->s_pixclock != 0){
+        OD = (screen->s_pixclock)&0x3;
+        N = (screen->s_pixclock >>4)&0xf;
+        M = (screen->s_pixclock >>8)&0xff;
+    }else {
+        RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n");
+    }
+    c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0);
+       rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c);
+    
+    c = S_DIV_N(N)| S_DIV_OD(OD);
+       rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c);
+    c = S_DIV_M(M);
+    rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c);
+    rk610_scaler_pll_enable(client);
+       return 0;
+}
+
+
+static int  scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act)
+   {
+    char c;
+       u32 hfactor_f,vfactor_f,scl_factor_f;
+       int  hfactor;
+       int  vfactor;
+       struct scl_hv_info  HV2;
+       hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1);
+    if(hfactor_f==4096)
+           {hfactor = 0x1000;}
+       else if(hfactor_f>(int)hfactor_f)
+               {hfactor = (int)hfactor_f+1;}
+       else
+               {hfactor = (int)hfactor_f;}
+         
+       scl_factor_f = Vin_act/Vout_act;
+       if(scl_factor_f<2)
+           {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);}
+       else
+               {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} 
+       if(vfactor_f==4096)
+           {vfactor = 0x1000;}
+       else if(vfactor_f>(int)vfactor_f)
+               {vfactor = (int)vfactor_f+1;}
+       else
+               {vfactor = (int)vfactor_f;}
+         
+    HV2.scl_h= hfactor;
+    HV2.scl_v= vfactor; 
+           /*       SCL FACTOR          */
+    c = SCL_H_FACTOR_LSB(HV2.scl_h);
+       rk610_scaler_write_p0_reg(client, SCL_CON1, &c);
+    c = SCL_H_FACTOR_MSB(HV2.scl_h);
+       rk610_scaler_write_p0_reg(client, SCL_CON2, &c);
+
+    c = SCL_V_FACTOR_LSB(HV2.scl_v);
+       rk610_scaler_write_p0_reg(client, SCL_CON3, &c);
+    c = SCL_V_FACTOR_MSB(HV2.scl_v);
+       rk610_scaler_write_p0_reg(client, SCL_CON4, &c);
+       return 0;
+   }
+
+static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen)
+{
+    switch(screen->hdmi_resolution){
+        case HDMI_1920x1080p_60Hz:
+        case HDMI_1920x1080p_50Hz:
+            rk610_scaler_pll_set(client,screen,148500000);
+            /***************set scaler factor********************/
+            scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res);
+            break;
+        case HDMI_1280x720p_60Hz:
+        case HDMI_1280x720p_50Hz:
+            rk610_scaler_pll_set(client,screen,74250000);
+            /***************set scaler factor********************/
+            scale_hv_factor(client,1280,screen->x_res,720,screen->y_res);
+        break;
+        case HDMI_720x576p_50Hz_16_9:
+        case HDMI_720x576p_50Hz_4_3:
+            rk610_scaler_pll_set(client,screen,27000000);
+            /***************set scaler factor********************/
+            scale_hv_factor(client,720,screen->x_res,576,screen->y_res);
+            break;
+        case HDMI_720x480p_60Hz_16_9:
+        case HDMI_720x480p_60Hz_4_3:
+            rk610_scaler_pll_set(client,screen,27000000);
+            /***************set scaler factor********************/
+            scale_hv_factor(client,720,screen->x_res,480,screen->y_res);
+        break;
+    default :
+        RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); 
+        return -1;
+        break;
+    }
+    return 0;
+}
+static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen)
+{
+    char c;
+    int h_st = screen->s_hsync_st;
+    int hs_end = screen->s_hsync_len;
+    int h_act_st = hs_end + screen->s_left_margin;
+    int xres = screen->x_res;
+    int h_act_end = h_act_st + xres;
+    int h_total = h_act_end + screen->s_right_margin;
+    int v_st = screen->s_vsync_st;
+    int vs_end = screen->s_vsync_len;
+    int v_act_st = vs_end + screen->s_upper_margin;
+    int yres = screen->y_res;    
+    int v_act_end = v_act_st + yres;
+    int v_total = v_act_end + screen->s_lower_margin;
+
+    /*      SCL display Frame start point   */
+    c = SCL_DSP_HST_LSB(h_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON5, &c);
+    c = SCL_DSP_HST_MSB(h_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON6, &c);
+
+    c = SCL_DSP_VST_LSB(v_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON7, &c);
+    c = SCL_DSP_VST_MSB(v_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON8, &c);
+    /*      SCL output timing       */
+
+    c = SCL_DSP_HTOTAL_LSB(h_total);
+       rk610_scaler_write_p0_reg(client, SCL_CON9, &c);
+    c = SCL_DSP_HTOTAL_MSB(h_total);
+       rk610_scaler_write_p0_reg(client, SCL_CON10, &c);
+
+    c = SCL_DSP_HS_END(hs_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON11, &c);
+
+    c = SCL_DSP_HACT_ST_LSB(h_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON12, &c);
+    c = SCL_DSP_HACT_ST_MSB(h_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON13, &c);
+
+    c = SCL_DSP_HACT_END_LSB(h_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON14, &c);
+    c = SCL_DSP_HACT_END_MSB(h_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON15, &c);
+
+    c = SCL_DSP_VTOTAL_LSB(v_total);
+       rk610_scaler_write_p0_reg(client, SCL_CON16, &c);
+    c = SCL_DSP_VTOTAL_MSB(v_total);
+       rk610_scaler_write_p0_reg(client, SCL_CON17, &c);
+
+    c = SCL_DSP_VS_END(vs_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON18, &c);
+
+    c = SCL_DSP_VACT_ST(v_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON19, &c);
+
+    c = SCL_DSP_VACT_END_LSB(v_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON20, &c);
+    c = SCL_DSP_VACT_END_MSB(v_act_end); 
+       rk610_scaler_write_p0_reg(client, SCL_CON21, &c);
+    c = SCL_H_BORD_ST_LSB(h_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON22, &c);
+    c = SCL_H_BORD_ST_MSB(h_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON23, &c);
+
+    c = SCL_H_BORD_END_LSB(h_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON24, &c);
+    c = SCL_H_BORD_END_MSB(h_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON25, &c);
+
+    c = SCL_V_BORD_ST(v_act_st);
+       rk610_scaler_write_p0_reg(client, SCL_CON26, &c);
+
+    c = SCL_V_BORD_END_LSB(v_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON27, &c);
+    c = SCL_V_BORD_END_MSB(v_act_end);
+       rk610_scaler_write_p0_reg(client, SCL_CON28, &c);
+       
+       return 0;
+}
+static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen)
+{
+
+    RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution);
+    rk610_scaler_fator_config(client,screen);
+    rk610_scaler_enable(client);
+    rk610_scaler_output_timing_config(client,screen); 
+    
+    return 0;
+
+}
+#endif
+static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale
+{
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    
+    rk610_scaler_disable(client);       
+    rk610_scaler_pll_disable(client);
+    
+    return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void rk610_lcd_early_suspend(struct early_suspend *h)
+{
+    struct i2c_client *client = g_lcd_inf->client;
+    char c;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    if(g_lcd_inf->screen != NULL){
+        rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE);
+    }
+
+    if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){
+        c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); 
+        rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
+    }
+    if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){
+        c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
+           rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
+    }
+}
+
+static void rk610_lcd_early_resume(struct early_suspend *h)
+{
+    struct i2c_client *client = g_lcd_inf->client;
+    char c;
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+
+    if(g_lcd_inf->screen != NULL){
+        rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode);
+    }
+    if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){
+        c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE);  
+           rk610_scaler_write_p0_reg(client, SCL_CON0, &c);
+    }
+    if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){
+        c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);
+           rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);
+    }
+}
+#endif
+int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale
+{
+    int ret=0;
+    struct i2c_client *client = g_lcd_inf->client;
+    if(client == NULL){
+        printk("%s client == NULL FAIL\n",__FUNCTION__);
+        return -1;
+    }
+    if(screen == NULL){
+        printk("%s screen == NULL FAIL\n",__FUNCTION__);
+        return -1;
+    }
+    RK610_DBG(&client->dev,"%s \n",__FUNCTION__);
+    
+    g_lcd_inf->screen = screen;
+    
+#if defined(CONFIG_HDMI_DUAL_DISP) || defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+    if(enable == 1){
+        g_lcd_inf->disp_mode = LCD_OUT_SCL;
+        rk610_output_config(client,screen,LCD_OUT_SCL);
+        ret = rk610_scaler_chg(client,screen);
+       }
+       else 
+#endif
+       {
+           g_lcd_inf->disp_mode = LCD_OUT_BYPASS;
+           rk610_output_config(client,screen,LCD_OUT_BYPASS);
+           ret = rk610_lcd_scaler_bypass(client,enable);
+       }
+       return ret;
+}
+int rk610_lcd_init(struct rk610_core_info *rk610_core_info)
+{
+    if(rk610_core_info->client == NULL){
+        printk("%s client == NULL FAIL\n",__FUNCTION__);
+        return -1;
+    }
+    RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__);
+
+    g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL);
+    if(!g_lcd_inf)
     {
-        dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!");\r
-        return -ENOMEM;\r
-    }\r
-    memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info));\r
-\r
-    g_lcd_inf->client= rk610_core_info->client;\r
-    \r
-    rk610_core_info->lcd_pdata = (void *)g_lcd_inf;\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-       g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend;\r
-       g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume;\r
+        dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!");
+        return -ENOMEM;
+    }
+    memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info));
+
+    g_lcd_inf->client= rk610_core_info->client;
+    
+    rk610_core_info->lcd_pdata = (void *)g_lcd_inf;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend;
+       g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume;
        g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1;
-       register_early_suspend(&g_lcd_inf->early_suspend);\r
-#endif\r
-    g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
-    g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
-    g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
-    return 0;\r
-}\r
+       register_early_suspend(&g_lcd_inf->early_suspend);
+#endif
+    g_lcd_inf->scl_inf.pll_pwr = DISABLE;
+    g_lcd_inf->scl_inf.scl_pwr = DISABLE;
+    g_lcd_inf->disp_mode = LCD_OUT_BYPASS;
+    return 0;
+}
+
+static int rk610_lcd_probe(struct platform_device *pdev)
+{
+       struct rk610_core_info *core_info = NULL;
+       rk_screen *screen = NULL;
+
+       core_info = dev_get_drvdata(pdev->dev.parent);
+       if(!core_info)
+       {
+               dev_err(&pdev->dev,"rk610 core info is null\n");
+               return -ENODEV;
+       }
+       screen = rk_fb_get_prmry_screen();
+       if(!screen)
+       {
+               dev_err(&pdev->dev,"the fb prmry screen is null!\n");
+               return -ENODEV;
+       }
+       
+#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+       screen->sscreen_set = rk610_lcd_scaler_set_param;
+#endif
+       rk610_lcd_init(core_info);
+       rk610_lcd_scaler_set_param(screen,0);
+
+       return 0;
+       
+}
+static int rk610_lcd_remove(struct platform_device *pdev)
+{
+       
+       return 0;
+}
+
+static void rk610_lcd_shutdown(struct platform_device *pdev)
+{
+       
+       return;
+}
+
+static struct platform_driver rk610_lcd_driver = {
+       .driver         = {
+               .name   = "rk610-lcd",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = rk610_lcd_probe,
+       .remove         = rk610_lcd_remove,
+       .shutdown       = rk610_lcd_shutdown,
+};
+
+static int __init rk610_lcd_module_init(void)
+{
+       return platform_driver_register(&rk610_lcd_driver);
+}
+fs_initcall(rk610_lcd_module_init);
+static void __exit rk610_lcd_exit(void)
+{
+       platform_driver_unregister(&rk610_lcd_driver);
+}
+module_exit(rk610_lcd_exit);
+
index fd1339481755fd1a3e6f51be25a5dd53d8cfd5ce..79f8743bd508cc1d7f99763b6dcc7ca142080954 100644 (file)
@@ -39,7 +39,7 @@ static int rk616_lvds_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
                                val = 0;
                                val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_PLL_PWR_DN);
                                val = (LVDS_DCLK_INV)|(LVDS_CH1_PWR_EN) |(LVDS_CH0_PWR_EN) | LVDS_HBP_ODD(odd) |
-                                       (LVDS_CBG_PWR_EN) | (LVDS_CH_SEL) | (LVDS_OUT_FORMAT(screen->hw_format)) | 
+                                       (LVDS_CBG_PWR_EN) | (LVDS_CH_SEL) | (LVDS_OUT_FORMAT(screen->lvds_format)) | 
                                        (LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH1_PWR_EN << 16) | 
                                        (LVDS_CH0_PWR_EN << 16) | (LVDS_CBG_PWR_EN << 16) | (LVDS_CH_SEL << 16) | 
                                        (LVDS_OUT_FORMAT_MASK) | (LVDS_DCLK_INV << 16) | (LVDS_PLL_PWR_DN << 16) |
@@ -52,7 +52,7 @@ static int rk616_lvds_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
                        {
                                val = 0;
                                val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_CH1_PWR_EN | LVDS_PLL_PWR_DN | LVDS_CH_SEL); //use channel 0
-                               val |= (LVDS_CH0_PWR_EN) |(LVDS_CBG_PWR_EN) | (LVDS_OUT_FORMAT(screen->hw_format)) | 
+                               val |= (LVDS_CH0_PWR_EN) |(LVDS_CBG_PWR_EN) | (LVDS_OUT_FORMAT(screen->lvds_format)) | 
                                      (LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) | 
                                       (LVDS_DCLK_INV ) | (LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) | 
                                        (LVDS_CBG_PWR_EN << 16)|(LVDS_CH_SEL << 16) | (LVDS_PLL_PWR_DN << 16)| 
@@ -104,7 +104,7 @@ static int rk616_dither_cfg(struct mfd_rk616 *rk616,rk_screen *screen,bool enabl
 
 
 
-int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale
+int rk616_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale
 {
        int ret;
        struct mfd_rk616 *rk616 = g_lvds->rk616;
@@ -113,7 +113,7 @@ int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass
                printk(KERN_ERR "%s:mfd rk616 is null!\n",__func__);
                return -1;
        }
-       g_lvds->screen = screen;
+       
        ret = rk616_display_router_cfg(rk616,screen,enable);
        
        ret = rk616_dither_cfg(rk616,screen,enable);
@@ -122,6 +122,16 @@ int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass
 }
 
 
+static int rk616_lvds_init_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
+{
+       int ret ;
+       ret = rk616_display_router_cfg(rk616,screen,0);
+       
+       ret = rk616_dither_cfg(rk616,screen,0);
+       ret = rk616_lvds_cfg(rk616,screen);
+
+       return ret;
+}
 
 #if    defined(CONFIG_HAS_EARLYSUSPEND)
 static void rk616_lvds_early_suspend(struct early_suspend *h)
@@ -155,7 +165,7 @@ static int rk616_lvds_probe(struct platform_device *pdev)
 {
        struct rk616_lvds *lvds = NULL; 
        struct mfd_rk616 *rk616 = NULL;
-
+       rk_screen *screen = NULL;
        lvds = kzalloc(sizeof(struct rk616_lvds),GFP_KERNEL);
        if(!lvds)
        {
@@ -171,8 +181,19 @@ static int rk616_lvds_probe(struct platform_device *pdev)
        }
        else
                g_lvds = lvds;
-               lvds->rk616 = rk616;
-
+       lvds->rk616 = rk616;
+       
+       screen = rk_fb_get_prmry_screen();
+       if(!screen)
+       {
+               dev_err(&pdev->dev,"the fb prmry screen is null!\n");
+               return -ENODEV;
+       }
+       lvds->screen = screen;
+#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
+       screen->sscreen_set = rk616_scaler_set_param;
+#endif
+       rk616_lvds_init_cfg(rk616,screen);
 #ifdef CONFIG_HAS_EARLYSUSPEND
        lvds->early_suspend.suspend = rk616_lvds_early_suspend;
        lvds->early_suspend.resume = rk616_lvds_late_resume;
@@ -213,8 +234,7 @@ static int __init rk616_lvds_init(void)
 {
        return platform_driver_register(&rk616_lvds_driver);
 }
-subsys_initcall_sync(rk616_lvds_init);
-
+fs_initcall(rk616_lvds_init);
 static void __exit rk616_lvds_exit(void)
 {
        platform_driver_unregister(&rk616_lvds_driver);
index 48adbde9ebee8f82365bb8e4ee119761ec6d942f..13bfccd4ec20390d86b03dee0c94d630d03c2c86 100644 (file)
@@ -141,7 +141,9 @@ struct rk610_ctl_platform_data {
 };
 struct rk610_core_info{
     struct i2c_client *client;
+    struct device *dev;
     struct rk610_ctl_platform_data *pdata;
+    struct dentry *debugfs_dir;
     void *lcd_pdata;
 };
 
index 4b969b8b7caa7b961ba856aed53285e06c15aacb..6f3f0469c32235ee49530d320c2c3ef4683894a0 100644 (file)
@@ -109,7 +109,7 @@ struct rk29lcd_info {
 typedef struct rk29fb_screen {
        /* screen type & hardware connect format & out face */
        u16 type;
-       u16 hw_format;  //lvds data format
+       u16 lvds_format;  //lvds data format
        u16 face;
        u8 lcdc_id;    //which output interface the screeen connect to
        u8 screen_id; //screen number