From 03f1f5649c4ee9d01ba3d1414b48a84a967d3eca Mon Sep 17 00:00:00 2001 From: yxj Date: Fri, 13 Apr 2012 16:53:39 +0800 Subject: [PATCH] rk30fb: add interface to enable/disable fb the path is sys/class/graphics/fbx/xxx --- drivers/video/rockchip/chips/rk30_lcdc.c | 30 ++++++++++++++++++-- drivers/video/rockchip/rk_fb.c | 21 ++++++++++++-- drivers/video/rockchip/rkfb_sysfs.c | 36 ++++++++++++++++++++++++ include/linux/rk_fb.h | 1 + 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/drivers/video/rockchip/chips/rk30_lcdc.c b/drivers/video/rockchip/chips/rk30_lcdc.c index def25b9dfa92..1d6ac665e0bd 100644 --- a/drivers/video/rockchip/chips/rk30_lcdc.c +++ b/drivers/video/rockchip/chips/rk30_lcdc.c @@ -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) diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 480115c19761..145ddfc84524 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -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 */ diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 7e36b2a2e49a..915ab77538f6 100644 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -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) diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index e7c20b75d098..c68ae6dab0d3 100644 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -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); }; -- 2.34.1