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);
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))
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);
.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
}
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))
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:
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;
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);
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)
#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 *
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
};