rk30 fb: add IOCTL and sys interface for overlay control
authoryxj <yxj@rock-chips.com>
Wed, 25 Apr 2012 06:15:19 +0000 (14:15 +0800)
committeryxj <yxj@rock-chips.com>
Wed, 25 Apr 2012 06:18:19 +0000 (14:18 +0800)
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 8e1cd6ba6c970a8211e4f04944d753a98271f8d0..b18a10f0df133984e87cd07caf1c926dfd8603f8 100644 (file)
@@ -511,6 +511,7 @@ static int rk30_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,boo
 
        return 0;
 }
+
 static int rk30_lcdc_set_par(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);
@@ -588,9 +589,10 @@ int rk30_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, uns
        struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
        u32 panel_size[2];
        void __user *argp = (void __user *)arg;
+       int ret = 0;
        switch(cmd)
        {
-               case FB1_IOCTL_GET_PANEL_SIZE:    //get panel size
+               case FBIOGET_PANEL_SIZE:    //get panel size
                        panel_size[0] = lcdc_dev->screen->x_res;
                        panel_size[1] = lcdc_dev->screen->y_res;
                        if(copy_to_user(argp, panel_size, 8)) 
@@ -600,26 +602,64 @@ int rk30_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, uns
                        break;
        }
 
-       return 0;
+       return ret;
 }
 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)
+       spin_lock(&lcdc_dev->reg_lock);
+       if(lcdc_dev->clk_on)
        {
-               par->state = LcdReadBit(lcdc_dev,SYS_CTRL1,m_W1_EN);
+               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);
+               }
        }
-
+       spin_unlock(&lcdc_dev->reg_lock);
+       
        return par->state;
        
 }
 
+/***********************************
+overlay manager
+swap:1 win0 on the top of win1
+        0 win1 on the top of win0
+set  : 1 set overlay 
+        0 get overlay state
+************************************/
+static int rk30_ovl_mgr(struct rk_lcdc_device_driver *dev_drv,int swap,bool set)
+{
+       struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
+       int ovl;
+       spin_lock(&lcdc_dev->reg_lock);
+       if(lcdc_dev->clk_on)
+       {
+               if(set)  //set overlay
+               {
+                       LcdMskReg(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP,v_W0W1_POSITION_SWAP(swap));
+                       LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
+                       ovl = swap;
+               }
+               else  //get overlay
+               {
+                       ovl = LcdReadBit(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP);
+               }
+       }
+       else
+       {
+               ovl = -EPERM;
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return ovl;
+}
 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);
@@ -690,6 +730,7 @@ static struct rk_lcdc_device_driver lcdc_driver = {
        .pan_display            = rk30_lcdc_pan_display,
        .load_screen            = rk30_load_screen,
        .get_layer_state        = rk30_lcdc_get_layer_state,
+       .ovl_mgr                = rk30_ovl_mgr,
        .get_disp_info          = rk30_get_disp_info,
 };
 #ifdef CONFIG_PM
index 0a3473d0116841f7376774e410546f9782182d5d..9fd427d51c6ab03d987f2c01d80db8b636d67750 100644 (file)
@@ -232,17 +232,19 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 }
 static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
 {
-       struct rk_fb_inf *inf = dev_get_drvdata(info->device);
        struct fb_fix_screeninfo *fix = &info->fix;
        struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
        u32 yuv_phy[2];
+       int layer_id = get_fb_layer_id(&info->fix);
+       int enable; // enable fb:1 enable;0 disable 
+       int ovl;        //overlay:0 win1 on the top of win0;1,win0 on the top of win1
        void __user *argp = (void __user *)arg;
        
        switch(cmd)
        {
                case FBIOPUT_FBPHYADD:
                        return info->fix.smem_start;
-               case FB1_IOCTL_SET_YUV_ADDR:   //when in video mode, buff alloc by android
+               case FBIOSET_YUV_ADDR:   //when in video mode, buff alloc by android
                        if((!strcmp(fix->id,"fb1"))||(!strcmp(fix->id,"fb3")))
                        {
                                if (copy_from_user(yuv_phy, argp, 8))
@@ -251,8 +253,24 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
                                info->fix.mmio_start = yuv_phy[1];  //four uv
                        }
                        break;
+               case FBIOSET_ENABLE:
+                       if (copy_from_user(&enable, argp, 1))
+                               return -EFAULT;
+                       dev_drv->open(dev_drv,layer_id,enable);
+                       break;
+               case FBIOGET_ENABLE:
+                       enable = dev_drv->get_layer_state(dev_drv,layer_id);
+                       if(copy_to_user(argp,&enable,1))
+                               return -EFAULT;
+                       break;
+               case FBIOSET_OVERLAY_STATE:
+                       if (copy_from_user(&ovl, argp, 1))
+                               return -EFAULT;
+                       dev_drv->ovl_mgr(dev_drv,ovl,1);
                case FBIOGET_OVERLAY_STATE:
-                       return inf->video_mode;
+                       ovl = dev_drv->ovl_mgr(dev_drv,0,0);
+                       if (copy_to_user(argp, &ovl, 1))
+                               return -EFAULT;
                case FBIOGET_SCREEN_STATE:
                case FBIOPUT_SET_CURSOR_EN:
                case FBIOPUT_SET_CURSOR_POS:
@@ -265,9 +283,8 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
                case FBIOGET_16OR32:
                case FBIOGET_IDLEFBUff_16OR32:
                case FBIOSET_COMPOSE_LAYER_COUNTS:
-               case FBIOGET_COMPOSE_LAYER_COUNTS:
                default:
-                       dev_drv->ioctl(dev_drv,cmd,arg,0);
+                       dev_drv->ioctl(dev_drv,cmd,arg,layer_id);
             break;
     }
     return 0;
@@ -812,6 +829,7 @@ static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv,
        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;
+       dev_drv->ovl_mgr        = def_drv->ovl_mgr;
        init_layer_par(dev_drv);
        init_completion(&dev_drv->frame_done);
        spin_lock_init(&dev_drv->cpl_lock);
index ed73d4366da68151f25860b2cbd60c8fd0fda7cf..17f8fafa746a5b7a24c5a2a64401dd5dcc08fbf1 100644 (file)
@@ -113,12 +113,52 @@ static ssize_t set_fb_state(struct device *dev,struct device_attribute *attr,
        return count;
 }
 
+static ssize_t show_overlay(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 ovl;
+       ovl =  dev_drv->ovl_mgr(dev_drv,0,0);
+       if(ovl < 0)
+       {
+               return ovl;
+       }
+
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+               ovl?"win0 on the top of win1":"win1 on the top of win0");
+       
+}
+static ssize_t set_overlay(struct device *dev,struct device_attribute *attr,
+       const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_device_driver * dev_drv = 
+               (struct rk_lcdc_device_driver * )fbi->par;
+       int ovl;
+       int ret;
+       ret = kstrtoint(buf, 0, &ovl);
+       if(ret)
+       {
+               return ret;
+       }
+       ret = dev_drv->ovl_mgr(dev_drv,ovl,1);
+       if(ret < 0)
+       {
+               return ret;
+       }
+
+       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),
+       __ATTR(overlay, S_IRUGO | S_IWUSR, show_overlay, set_overlay),
 };
 
 int rkfb_create_sysfs(struct fb_info *fbi)
index 673365dbfce6e33e11c9129dd6b392666d297d6a..bc909f9ee470a49bf54bc5832265f456893a1bc4 100644 (file)
 #define FB_WIMO_FLAG
 #endif
 #ifdef FB_WIMO_FLAG
-#define FB0_IOCTL_SET_BUF                                      0x6017
+#define FB0_IOCTL_SET_BUF                              0x6017
 #define FB0_IOCTL_COPY_CURBUF                          0x6018
 #define FB0_IOCTL_CLOSE_BUF                            0x6019
 #endif
 
-#define FB1_IOCTL_GET_PANEL_SIZE               0x5001
-#define FB1_IOCTL_SET_YUV_ADDR                 0x5002
+#define FBIOGET_PANEL_SIZE             0x5001
+#define FBIOSET_YUV_ADDR               0x5002
 //#define FB1_TOCTL_SET_MCU_DIR                        0x5003
-#define FB1_IOCTL_SET_ROTATE            0x5003
-#define FB1_IOCTL_SET_I2P_ODD_ADDR      0x5005
-#define FB1_IOCTL_SET_I2P_EVEN_ADDR     0x5006
-#define FB1_IOCTL_SET_WIN0_TOP          0x5018
+#define FBIOSET_ROTATE                 0x5003
+#define FB_IOCTL_SET_I2P_ODD_ADDR       0x5005
+#define FB_IOCTL_SET_I2P_EVEN_ADDR      0x5006
+#define FBIOSET_OVERLAY_STATE          0x5018
+#define FBIOSET_ENABLE                 0x5019  
+#define FBIOGET_ENABLE                 0x5020
 
 /********************************************************************
 **              display output interface supported by rk lcdc                       *
@@ -209,6 +211,7 @@ struct rk_lcdc_device_driver{
        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);
+       int (*ovl_mgr)(struct rk_lcdc_device_driver *dev_drv,int swap,bool set);  //overlay manager
        
 };