rk30fb: add interface to enable/disable fb
authoryxj <yxj@rock-chips.com>
Fri, 13 Apr 2012 08:53:39 +0000 (16:53 +0800)
committeryxj <yxj@rock-chips.com>
Fri, 13 Apr 2012 08:53:39 +0000 (16:53 +0800)
the path is sys/class/graphics/fbx/xxx

drivers/video/rockchip/chips/rk30_lcdc.c
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h

index def25b9dfa92b82ca687e375999ca9b8fa94c7c5..1d6ac665e0bdb672e7ccfac65bf1dfce6f64f91b 100644 (file)
@@ -190,7 +190,6 @@ static int rk30_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscre
               v_VERPRD(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
        LcdWrReg(lcdc_dev, DSP_VACT_ST_END,  v_VAEP(screen->vsync_len + screen->upper_margin+y_res)|
               v_VASP(screen->vsync_len + screen->upper_margin));
-       LcdMskReg(lcdc_dev,SYS_CTRL1, m_W1_EN, v_W1_EN(1));  //default,enable win1 for ui display
        // let above to take effect
        LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
                                                         
@@ -242,6 +241,7 @@ static int win0_open(struct rk30_lcdc_device *lcdc_dev,bool open)
 {
        LcdMskReg(lcdc_dev, SYS_CTRL1, m_W0_EN, v_W0_EN(open));
        LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
+       lcdc_dev->driver.layer_par[0]->state = open;
        printk(KERN_INFO "lcdc%d win0 %s\n",lcdc_dev->id,open?"open":"closed");
        return 0;
 }
@@ -249,6 +249,7 @@ static int win1_open(struct rk30_lcdc_device *lcdc_dev,bool open)
 {
        LcdMskReg(lcdc_dev, SYS_CTRL1, m_W1_EN, v_W1_EN(open));
        LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
+       lcdc_dev->driver.layer_par[1]->state = open;
        printk(KERN_INFO "lcdc%d win1 %s\n",lcdc_dev->id,open?"open":"closed");
        return 0;
 }
@@ -549,7 +550,30 @@ int rk30_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, uns
                default:
                        break;
        }
-               
+
+       return 0;
+}
+static int rk30_lcdc_get_layer_state(struct rk_lcdc_device_driver *dev_drv,int layer_id)
+{
+       struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
+       struct layer_par *par = dev_drv->layer_par[layer_id];
+
+       if(layer_id == 0)
+       {
+               par->state = LcdReadBit(lcdc_dev,SYS_CTRL1,m_W0_EN);
+       }
+       else if( layer_id == 1)
+       {
+               par->state = LcdReadBit(lcdc_dev,SYS_CTRL1,m_W1_EN);
+       }
+
+       return par->state;
+       
+}
+
+static int rk30_get_disp_info(struct rk_lcdc_device_driver *dev_drv,int layer_id)
+{
+       struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
        return 0;
 }
 
@@ -607,6 +631,8 @@ static struct rk_lcdc_device_driver lcdc_driver = {
        .blank                  = rk30_lcdc_blank,
        .pan_display            = rk30_lcdc_pan_display,
        .load_screen            = rk30_load_screen,
+       .get_layer_state        = rk30_lcdc_get_layer_state,
+       .get_disp_info          = rk30_get_disp_info,
 };
 #ifdef CONFIG_PM
 static int rk30_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
index 480115c1976140917574619bc3cdfff591b8088e..145ddfc84524eb2c633473057538289723f1785f 100644 (file)
@@ -110,7 +110,14 @@ static int rk_fb_open(struct fb_info *info,int user)
     int layer_id;
     CHK_SUSPEND(dev_drv);
     layer_id = get_fb_layer_id(&info->fix);
-    dev_drv->open(dev_drv,layer_id,1);
+    if(dev_drv->layer_par[layer_id]->state)
+    {
+       return 0;    // if this layer aready opened ,no need to reopen
+    }
+    else
+    {
+       dev_drv->open(dev_drv,layer_id,1);
+    }
     
     return 0;
     
@@ -122,7 +129,14 @@ static int rk_fb_close(struct fb_info *info,int user)
        int layer_id;
        CHK_SUSPEND(dev_drv);
        layer_id = get_fb_layer_id(&info->fix);
-       dev_drv->open(dev_drv,layer_id,0);
+       if(!dev_drv->layer_par[layer_id]->state)
+       {
+               return 0;
+       }
+       else
+       {
+               dev_drv->open(dev_drv,layer_id,0);
+       }
        
        return 0;
 }
@@ -652,6 +666,8 @@ static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv,
        dev_drv->load_screen    = def_drv->load_screen;
        dev_drv->def_layer_par  = def_drv->def_layer_par;
        dev_drv->num_layer      = def_drv->num_layer;
+       dev_drv->get_layer_state= def_drv->get_layer_state;
+       dev_drv->get_disp_info  = def_drv->get_disp_info;
        init_layer_par(dev_drv);
        init_completion(&dev_drv->frame_done);
        spin_lock_init(&dev_drv->cpl_lock);
@@ -737,6 +753,7 @@ int rk_fb_register(struct rk_lcdc_device_driver *dev_drv,
         fb_inf->num_fb++;      
        }
 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
+    fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_open(fb_inf->fb[fb_inf->num_fb-2],1);
     fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_set_par(fb_inf->fb[fb_inf->num_fb-2]);
     if(fb_prepare_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR)) {
         /* Start display and show logo on boot */
index 7e36b2a2e49a5b107d1849193b55e3c196c64603..915ab77538f6bc8c55c20d1e0f47f18ecf5d6d3d 100644 (file)
@@ -59,6 +59,8 @@ static ssize_t show_disp_info(struct device *dev,
        int layer_id = get_fb_layer_id(&fbi->fix);
        if(dev_drv->get_disp_info)
                dev_drv->get_disp_info(dev_drv,layer_id);
+
+       return 0;
 }
 
 static ssize_t show_phys(struct device *dev,
@@ -78,11 +80,45 @@ static ssize_t show_virt(struct device *dev,
                fbi->screen_base,fbi->fix.smem_len);
 }
 
+static ssize_t show_fb_state(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_device_driver * dev_drv = 
+               (struct rk_lcdc_device_driver * )fbi->par;
+       int layer_id = get_fb_layer_id(&fbi->fix);
+       int state = dev_drv->get_layer_state(dev_drv,layer_id);
+       return snprintf(buf, PAGE_SIZE, "%s\n",state?"enabled":"disabled");
+       
+}
+static ssize_t set_fb_state(struct device *dev,struct device_attribute *attr,
+       const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       int state;
+       int ret;
+       ret = kstrtoint(buf, 0, &state);
+       if(ret)
+       {
+               return ret;
+       }
+       if(state)
+       {
+               fbi->fbops->fb_open(fbi,1);
+       }
+       else
+       {
+               fbi->fbops->fb_release(fbi,1);
+       }
+       return count;
+}
+
 static struct device_attribute rkfb_attrs[] = {
        __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
        __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
        __ATTR(disp_info, S_IRUGO, show_disp_info, NULL),
        __ATTR(screen_info, S_IRUGO, show_screen_info, NULL),
+       __ATTR(enable, S_IRUGO | S_IWUSR, show_fb_state, set_fb_state),
 };
 
 int rkfb_create_sysfs(struct fb_info *fbi)
index e7c20b75d0989db57c373f3ed93ad39fbf7a1351..c68ae6dab0d3618cc20ea0f1f7d50325e9c7b091 100644 (file)
@@ -210,6 +210,7 @@ struct rk_lcdc_device_driver{
        int (*pan_display)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
        int (*get_disp_info)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
        int (*load_screen)(struct rk_lcdc_device_driver *dev_drv, bool initscreen);
+       int (*get_layer_state)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
        
 };