2 * drivers/video/rockchip/rk_fb.c
4 * Copyright (C) 2012 ROCKCHIP, Inc.
5 *Author:yzq<yzq@rock-chips.com>
6 yxj<yxj@rock-chips.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
22 #include <linux/slab.h>
23 #include <linux/delay.h>
24 #include <linux/device.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/platform_device.h>
29 #include <linux/earlysuspend.h>
30 #include <asm/div64.h>
31 #include <asm/uaccess.h>
32 #include <mach/board.h>
33 #include "../display/screen/screen.h"
34 #include<linux/rk_fb.h>
38 #define fbprintk(msg...) printk(msg);
40 #define fbprintk(msg...)
44 #define CHK_SUSPEND(inf) \
45 if(inf->in_suspend) { \
46 fbprintk(">>>>>> fb is in suspend! return! \n"); \
50 #define CHK_SUSPEND(inf)
53 static struct platform_device *g_fb_pdev;
55 static struct rk_fb_rgb def_rgb_16 = {
56 red: { offset: 11, length: 5, },
57 green: { offset: 5, length: 6, },
58 blue: { offset: 0, length: 5, },
59 transp: { offset: 0, length: 0, },
63 /***************************************************************************
64 fb0-----------lcdc0------------win1 for ui
65 fb1-----------lcdc0------------win0 for video,win0 support 3d display
66 fb2-----------lcdc1------------win1 for ui
67 fb3-----------lcdc1-------------win0 for video ,win0 support 3d display
69 defautl:we alloc three buffer,one for fb0 and fb2 display ui,one for ipp rotate
70 fb1 and fb3 are used for video play,the buffer is alloc by android,and
71 pass the phy addr to fix.smem_start by ioctl
72 ****************************************************************************/
74 int get_fb_layer_id(struct fb_fix_screeninfo *fix)
77 if(!strcmp(fix->id,"fb1")||!strcmp(fix->id,"fb3"))
81 else if(!strcmp(fix->id,"fb0")||!strcmp(fix->id,"fb2"))
87 printk(KERN_ERR "unsupported %s",fix->id);
94 /**********************************************************************
96 id: lcdc id ,0 for lcdc0 ,1 for lcdc1
97 ***********************************************************************/
98 struct rk_lcdc_device_driver * rk_get_lcdc_drv(int id)
100 struct rk_fb_inf *inf = platform_get_drvdata(g_fb_pdev);
101 return inf->lcdc_dev_drv[id];
104 static int rk_fb_open(struct fb_info *info,int user)
106 struct rk_fb_inf *inf = dev_get_drvdata(info->device);
107 struct rk_lcdc_device_driver *dev_drv = NULL;
108 struct fb_fix_screeninfo *fix = &info->fix;
110 if(!strcmp(fix->id,"fb1")){
111 dev_drv = inf->lcdc_dev_drv[0];
113 dev_drv->blank(dev_drv,1,FB_BLANK_NORMAL); //when open fb1,defautl close fb0 layer win1
114 dev_drv->blank(dev_drv,layer_id,FB_BLANK_UNBLANK); //open fb1 layer win0
123 static int rk_fb_release(struct fb_info *info,int user)
125 struct rk_fb_inf *inf = dev_get_drvdata(info->device);
126 struct fb_fix_screeninfo *fix = &info->fix;
127 if(!strcmp(fix->id,"fb1")){
134 static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
136 struct fb_fix_screeninfo *fix = &info->fix;
137 struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par;
138 struct layer_par *par = NULL;
140 u32 xoffset = var->xoffset; // offset from virtual to visible
141 u32 yoffset = var->yoffset;
142 u32 xvir = var->xres_virtual;
143 u8 data_format = var->nonstd&0xff;
144 layer_id = get_fb_layer_id(fix);
151 par = &dev_drv->layer_par[layer_id];
156 par->y_offset = (yoffset*xvir + xoffset)*4;
159 par->y_offset = (yoffset*xvir + xoffset)*3;
162 par->y_offset = (yoffset*xvir + xoffset)*2;
165 par->y_offset = yoffset*xvir + xoffset;
166 par->c_offset = par->y_offset;
169 par->y_offset = yoffset*xvir + xoffset;
170 par->c_offset = (yoffset>>1)*xvir + xoffset;
172 case YUV444 : // yuv444
173 par->y_offset = yoffset*xvir + xoffset;
174 par->c_offset = yoffset*2*xvir +(xoffset<<1);
177 printk("un supported format:0x%x\n",data_format);
181 dev_drv->pan_display(dev_drv,layer_id);
185 static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
187 struct rk_fb_inf *inf = dev_get_drvdata(info->device);
188 struct fb_fix_screeninfo *fix = &info->fix;
189 struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
191 void __user *argp = (void __user *)arg;
192 fbprintk(">>>>>> %s : cmd:0x%x \n",__FUNCTION__,cmd);
197 case FBIOPUT_FBPHYADD:
198 return info->fix.smem_start;
199 case FB1_IOCTL_SET_YUV_ADDR: //when in video mode, buff alloc by android
200 if((!strcmp(fix->id,"fb1"))||(!strcmp(fix->id,"fb3")))
202 if (copy_from_user(yuv_phy, argp, 8))
204 info->fix.smem_start = yuv_phy[0]; //four y
205 info->fix.mmio_start = yuv_phy[1]; //four uv
208 case FBIOGET_OVERLAY_STATE:
209 return inf->video_mode;
210 case FBIOGET_SCREEN_STATE:
211 case FBIOPUT_SET_CURSOR_EN:
212 case FBIOPUT_SET_CURSOR_POS:
213 case FBIOPUT_SET_CURSOR_IMG:
214 case FBIOPUT_SET_CURSOR_CMAP:
215 case FBIOPUT_GET_CURSOR_RESOLUTION:
216 case FBIOPUT_GET_CURSOR_EN:
217 case FB0_IOCTL_STOP_TIMER_FLUSH: //stop timer flush mcu panel after android is runing
220 case FBIOGET_IDLEFBUff_16OR32:
221 case FBIOSET_COMPOSE_LAYER_COUNTS:
222 case FBIOGET_COMPOSE_LAYER_COUNTS:
224 dev_drv->ioctl(dev_drv,cmd,arg,0);
230 static int rk_fb_blank(int blank_mode, struct fb_info *info)
232 struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
233 struct fb_fix_screeninfo *fix = &info->fix;
235 layer_id = get_fb_layer_id(fix);
241 dev_drv->blank(dev_drv,layer_id,blank_mode);
246 static int rk_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
250 if( 0==var->xres_virtual || 0==var->yres_virtual ||
251 0==var->xres || 0==var->yres || var->xres<16 ||
252 ((16!=var->bits_per_pixel)&&(32!=var->bits_per_pixel)) )
254 printk(">>>>>> fb_check_var fail 1!!! \n");
255 printk(">>>>>> 0==%d || 0==%d ", var->xres_virtual,var->yres_virtual);
256 printk("0==%d || 0==%d || %d<16 || ", var->xres,var->yres,var->xres<16);
257 printk("bits_per_pixel=%d \n", var->bits_per_pixel);
261 if( (var->xoffset+var->xres)>var->xres_virtual ||
262 (var->yoffset+var->yres)>var->yres_virtual*2 )
264 printk(">>>>>> fb_check_var fail 2!!! \n");
265 printk(">>>>>> (%d+%d)>%d || ", var->xoffset,var->xres,var->xres_virtual);
266 printk("(%d+%d)>%d || ", var->yoffset,var->yres,var->yres_virtual);
271 switch(var->nonstd&0x0f)
274 switch(var->bits_per_pixel)
277 var->xres_virtual = (var->xres_virtual + 0x1) & (~0x1);
278 var->xres = (var->xres + 0x1) & (~0x1);
279 var->xoffset = (var->xoffset) & (~0x1);
282 var->bits_per_pixel = 32;
285 var->nonstd &= ~0xc0; //not support I2P in this format
288 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
289 var->xres = (var->xres + 0x3) & (~0x3);
290 var->xoffset = (var->xoffset) & (~0x3);
293 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
294 var->yres_virtual = (var->yres_virtual + 0x1) & (~0x1);
295 var->xres = (var->xres + 0x3) & (~0x3);
296 var->yres = (var->yres + 0x1) & (~0x1);
297 var->xoffset = (var->xoffset) & (~0x3);
298 var->yoffset = (var->yoffset) & (~0x1);
301 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
302 var->yres_virtual = (var->yres_virtual + 0x1) & (~0x1);
303 var->xres = (var->xres + 0x3) & (~0x3);
304 var->yres = (var->yres + 0x1) & (~0x1);
305 var->xoffset = (var->xoffset) & (~0x3);
306 var->yoffset = (var->yoffset) & (~0x1);
307 var->nonstd &= ~0xc0; //not support I2P in this format
311 var->xres_virtual = (var->xres_virtual + 0x3) & (~0x3);
312 var->xres = (var->xres + 0x3) & (~0x3);
313 var->xoffset = (var->xoffset) & (~0x3);
314 var->nonstd &= ~0xc0; //not support I2P in this format
317 printk(">>>>>> fb1 var->nonstd=%d is invalid! \n", var->nonstd);
325 static int rk_fb_set_par(struct fb_info *info)
327 struct fb_var_screeninfo *var = &info->var;
328 struct fb_fix_screeninfo *fix = &info->fix;
329 struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par;
330 struct layer_par *par = NULL;
331 rk_screen *screen =dev_drv->screen;
333 u32 cblen = 0,crlen = 0;
334 u16 xsize =0,ysize = 0; //winx display window height/width --->LCDC_WINx_DSP_INFO
335 u32 xoffset = var->xoffset; // offset from virtual to visible
336 u32 yoffset = var->yoffset; //resolution
337 u16 xpos = (var->nonstd>>8) & 0xfff; //visiable pos in panel
338 u16 ypos = (var->nonstd>>20) & 0xfff;
339 u32 xvir = var->xres_virtual;
340 u32 yvir = var->yres_virtual;
341 u8 data_format = var->nonstd&0xff;
343 layer_id = get_fb_layer_id(fix);
350 par = &dev_drv->layer_par[layer_id];
352 if((!strcmp(fix->id,"fb0"))||(!strcmp(fix->id,"fb2"))) //four ui
354 xsize = screen->x_res;
355 ysize = screen->y_res;
357 else if((!strcmp(fix->id,"fb1"))||(!strcmp(fix->id,"fb3")))
359 xsize = (var->grayscale>>8) & 0xfff; //visiable size in panel ,for vide0
360 ysize = (var->grayscale>>20) & 0xfff;
363 /* calculate y_offset,c_offset,line_length,cblen and crlen */
367 case HAL_PIXEL_FORMAT_RGBA_8888 : // rgb
368 case HAL_PIXEL_FORMAT_RGBX_8888:
369 par->format = ARGB888;
370 fix->line_length = 4 * xvir;
371 par->y_offset = (yoffset*xvir + xoffset)*4;
373 case HAL_PIXEL_FORMAT_RGB_888 :
374 par->format = RGB888;
375 fix->line_length = 3 * xvir;
376 par->y_offset = (yoffset*xvir + xoffset)*3;
378 case HAL_PIXEL_FORMAT_RGB_565: //RGB565
379 par->format = RGB565;
380 fix->line_length = 2 * xvir;
381 par->y_offset = (yoffset*xvir + xoffset)*2;
383 case HAL_PIXEL_FORMAT_YCbCr_422_SP : // yuv422
384 par->format = YUV422;
385 fix->line_length = xvir;
386 cblen = crlen = (xvir*yvir)>>1;
387 par->y_offset = yoffset*xvir + xoffset;
388 par->c_offset = par->y_offset;
390 case HAL_PIXEL_FORMAT_YCrCb_NV12 : // YUV420---uvuvuv
391 par->format = YUV420;
392 fix->line_length = xvir;
393 cblen = crlen = (xvir*yvir)>>2;
394 par->y_offset = yoffset*xvir + xoffset;
395 par->c_offset = (yoffset>>1)*xvir + xoffset;
397 case HAL_PIXEL_FORMAT_YCrCb_444 : // yuv444
399 fix->line_length = xvir<<2;
400 par->y_offset = yoffset*xvir + xoffset;
401 par->c_offset = yoffset*2*xvir +(xoffset<<1);
402 cblen = crlen = (xvir*yvir);
405 printk("un supported format:0x%x\n",data_format);
409 switch(var->bits_per_pixel)
412 par->format = ARGB888;
413 fix->line_length = 4 * xvir;
414 par->y_offset = (yoffset*xvir + xoffset)*4;
417 par->format = RGB565;
418 fix->line_length = 2 * xvir;
419 par->y_offset = (yoffset*xvir + xoffset)*2;
430 par->smem_start =fix->smem_start;
431 par->cbr_start = fix->mmio_start;
432 par->xact = var->xres; //winx active window height,is a part of vir
433 par->yact = var->yres;
434 par->xvir = var->xres_virtual; // virtual resolution stride --->LCDC_WINx_VIR
435 par->yvir = var->yres_virtual;
436 dev_drv->set_par(dev_drv,layer_id);
441 static inline unsigned int chan_to_field(unsigned int chan,
442 struct fb_bitfield *bf)
445 chan >>= 16 - bf->length;
446 return chan << bf->offset;
449 static int fb_setcolreg(unsigned regno,
450 unsigned red, unsigned green, unsigned blue,
451 unsigned transp, struct fb_info *info)
455 switch (info->fix.visual) {
456 case FB_VISUAL_TRUECOLOR:
457 /* true-colour, use pseudo-palette */
459 u32 *pal = info->pseudo_palette;
460 val = chan_to_field(red, &info->var.red);
461 val |= chan_to_field(green, &info->var.green);
462 val |= chan_to_field(blue, &info->var.blue);
467 return -1; /* unknown type */
473 static struct fb_ops fb_ops = {
474 .owner = THIS_MODULE,
475 .fb_open = rk_fb_open,
476 .fb_release = rk_fb_release,
477 .fb_check_var = rk_fb_check_var,
478 .fb_set_par = rk_fb_set_par,
479 .fb_blank = rk_fb_blank,
480 .fb_ioctl = rk_fb_ioctl,
481 .fb_pan_display = rk_pan_display,
482 .fb_setcolreg = fb_setcolreg,
483 .fb_fillrect = cfb_fillrect,
484 .fb_copyarea = cfb_copyarea,
485 .fb_imageblit = cfb_imageblit,
490 static struct fb_var_screeninfo def_var = {
491 .red = {11,5,0},//default set to rgb565,the boot logo is rgb565
495 .nonstd = HAL_PIXEL_FORMAT_RGB_565, //(ypos<<20+xpos<<8+format) format
496 .grayscale = 0, //(ysize<<20+xsize<<8)
497 .activate = FB_ACTIVATE_NOW,
499 .vmode = FB_VMODE_NONINTERLACED,
502 static struct fb_fix_screeninfo def_fix = {
503 .type = FB_TYPE_PACKED_PIXELS,
508 .accel = FB_ACCEL_NONE,
509 .visual = FB_VISUAL_TRUECOLOR,
514 /*****************************************************************
515 this two function is for other module that in the kernel which
516 need show image directly through fb
517 fb_id:we have 4 fb here,default we use fb0 for ui display
518 *******************************************************************/
519 struct fb_info * rk_get_fb(int fb_id)
521 struct rk_fb_inf *inf = platform_get_drvdata(g_fb_pdev);
522 struct fb_info *fb = inf->fb[fb_id];
525 EXPORT_SYMBOL(rk_get_fb);
527 void rk_direct_fb_show(struct fb_info * fbi)
530 rk_pan_display(&fbi->var, fbi);
532 EXPORT_SYMBOL(rk_direct_fb_show);
534 static int rk_request_fb_buffer(struct fb_info *fbi,int fb_id)
536 struct resource *res;
537 struct resource *mem;
542 res = platform_get_resource_byname(g_fb_pdev, IORESOURCE_MEM, "fb0 buf");
545 dev_err(&g_fb_pdev->dev, "failed to get win0 memory \n");
548 fbi->fix.smem_start = res->start;
549 fbi->fix.smem_len = res->end - res->start + 1;
550 mem = request_mem_region(res->start, resource_size(res), g_fb_pdev->name);
551 fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
552 memset(fbi->screen_base, 0, fbi->fix.smem_len);
553 printk("fb%d:phy:%lx>>vir:%p>>len:0x%x\n",fb_id,
554 fbi->fix.smem_start,fbi->screen_base,fbi->fix.smem_len);
555 #ifdef CONFIG_FB_WORK_IPP // alloc ipp buf for rotate
556 res = platform_get_resource_byname(g_fb_pdev, IORESOURCE_MEM, "ipp buf");
559 dev_err(&g_fb_pdev->dev, "failed to get win1 ipp memory \n");
562 fbi->fix.mmio_start = res->start;
563 fbi->fix.mmio_len = res->end - res->start + 1;
567 res = platform_get_resource_byname(g_fb_pdev, IORESOURCE_MEM, "fb2 buf");
570 dev_err(&g_fb_pdev->dev, "failed to get win0 memory \n");
573 fbi->fix.smem_start = res->start;
574 fbi->fix.smem_len = res->end - res->start + 1;
575 mem = request_mem_region(res->start, resource_size(res), g_fb_pdev->name);
576 fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
577 memset(fbi->screen_base, 0, fbi->fix.smem_len);
578 printk("fb%d:phy:%lx>>vir:%p>>len:0x%x\n",fb_id,
579 fbi->fix.smem_start,fbi->screen_base,fbi->fix.smem_len);
588 static int rk_release_fb_buffer(struct fb_info *fbi)
592 printk("no need release null fb buffer!\n");
595 if(!strcmp(fbi->fix.id,"fb1")||!strcmp(fbi->fix.id,"fb3")) //buffer for fb1 and fb3 are alloc by android
597 iounmap(fbi->screen_base);
598 release_mem_region(fbi->fix.smem_start,fbi->fix.smem_len);
602 int rk_fb_register(struct rk_lcdc_device_driver *dev_drv)
604 struct rk_fb_inf *fb_inf = platform_get_drvdata(g_fb_pdev);
610 printk("null lcdc device driver?");
613 for(i=0;i<RK30_MAX_LCDC_SUPPORT;i++)
615 if(NULL==fb_inf->lcdc_dev_drv[i])
617 fb_inf->lcdc_dev_drv[i] = dev_drv;
618 fb_inf->lcdc_dev_drv[i]->id = i;
623 if(i==RK30_MAX_LCDC_SUPPORT)
625 printk("rk_fb_register lcdc out of support %d",i);
630 /************fb set,one layer one fb ***********/
631 dev_drv->fb_index_base = fb_inf->num_fb;
632 for(i=0;i<dev_drv->num_layer;i++)
634 fbi= framebuffer_alloc(0, &g_fb_pdev->dev);
637 dev_err(&g_fb_pdev->dev,">> fb framebuffer_alloc fail!");
644 sprintf(fbi->fix.id,"fb%d",fb_inf->num_fb);
645 fbi->var.xres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
646 fbi->var.yres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
647 fbi->var.bits_per_pixel = 16;
648 fbi->var.xres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
649 fbi->var.yres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
650 fbi->var.width = fb_inf->lcdc_dev_drv[lcdc_id]->screen->width;
651 fbi->var.height = fb_inf->lcdc_dev_drv[lcdc_id]->screen->height;
652 fbi->var.pixclock =fb_inf->lcdc_dev_drv[lcdc_id]->pixclock;
653 fbi->var.left_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->left_margin;
654 fbi->var.right_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->right_margin;
655 fbi->var.upper_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->upper_margin;
656 fbi->var.lower_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->lower_margin;
657 fbi->var.vsync_len = fb_inf->lcdc_dev_drv[lcdc_id]->screen->vsync_len;
658 fbi->var.hsync_len = fb_inf->lcdc_dev_drv[lcdc_id]->screen->hsync_len;
659 fbi->fbops = &fb_ops;
660 fbi->flags = FBINFO_FLAG_DEFAULT;
661 fbi->pseudo_palette = fb_inf->lcdc_dev_drv[lcdc_id]->layer_par[i].pseudo_pal;
662 rk_request_fb_buffer(fbi,fb_inf->num_fb);
663 ret = register_framebuffer(fbi);
666 printk("%s>>fb%d register_framebuffer fail!\n",__func__,fb_inf->num_fb);
669 rkfb_create_sysfs(fbi);
670 fb_inf->fb[fb_inf->num_fb] = fbi;
671 printk("%s>>>>>%s\n",__func__,fb_inf->fb[fb_inf->num_fb]->fix.id);
674 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
675 fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_set_par(fb_inf->fb[fb_inf->num_fb-2]);
676 if(fb_prepare_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR)) {
677 /* Start display and show logo on boot */
678 fb_set_cmap(&fb_inf->fb[fb_inf->num_fb-2]->cmap, fb_inf->fb[fb_inf->num_fb-2]);
679 fb_show_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR);
680 fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_blank(FB_BLANK_UNBLANK, fb_inf->fb[fb_inf->num_fb-2]);
681 fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_pan_display(&(fb_inf->fb[fb_inf->num_fb-2]->var), fb_inf->fb[fb_inf->num_fb-2]);
688 int rk_fb_unregister(struct rk_lcdc_device_driver *dev_drv)
691 struct rk_fb_inf *fb_inf = platform_get_drvdata(g_fb_pdev);
693 int fb_index_base = dev_drv->fb_index_base;
694 int fb_num = dev_drv->num_layer;
698 printk(" no need to unregister null lcdc device driver!\n");
702 for(i=fb_index_base;i<(fb_index_base+fb_num);i++)
705 unregister_framebuffer(fbi);
706 rk_release_fb_buffer(fbi);
707 framebuffer_release(fbi);
709 fb_inf->lcdc_dev_drv[dev_drv->id]= NULL;
714 int init_lcdc_device_driver(struct rk_lcdc_device_driver *def_drv,
715 struct rk_lcdc_device_driver *dev_drv,int id)
719 printk(KERN_ERR "default lcdc device driver is null!\n");
724 printk(KERN_ERR "lcdc device driver is null!\n");
727 sprintf(dev_drv->name, "lcdc%d",id);
728 dev_drv->layer_par = def_drv->layer_par;
729 dev_drv->num_layer = def_drv->num_layer;
730 dev_drv->ioctl = def_drv->ioctl;
731 dev_drv->blank = def_drv->blank;
732 dev_drv->set_par = def_drv->set_par;
733 dev_drv->pan_display = def_drv->pan_display;
734 dev_drv->suspend = def_drv->suspend;
735 dev_drv->resume = def_drv->resume;
736 dev_drv->load_screen = dev_drv->load_screen;
740 static int __devinit rk_fb_probe (struct platform_device *pdev)
742 struct rk_fb_inf *fb_inf = NULL;
743 struct rk29lcd_info *lcd_info = NULL;
746 lcd_info = pdev->dev.platform_data;
747 /* Malloc rk_fb_inf and set it to pdev for drvdata */
748 fb_inf = kzalloc(sizeof(struct rk_fb_inf), GFP_KERNEL);
751 dev_err(&pdev->dev, ">>fb inf kmalloc fail!");
754 platform_set_drvdata(pdev,fb_inf);
755 if(lcd_info->io_init)
757 printk("rk fb probe ok!\n");
761 static int __devexit rk_fb_remove(struct platform_device *pdev)
763 struct rk_fb_inf *fb_inf = platform_get_drvdata(pdev);
765 platform_set_drvdata(pdev, NULL);
769 static void rk_fb_shutdown(struct platform_device *pdev)
771 struct rk_fb_inf *fb_inf = platform_get_drvdata(pdev);
773 platform_set_drvdata(pdev, NULL);
776 static struct platform_driver rk_fb_driver = {
777 .probe = rk_fb_probe,
778 .remove = __devexit_p(rk_fb_remove),
781 .owner = THIS_MODULE,
783 .shutdown = rk_fb_shutdown,
786 static int __init rk_fb_init(void)
788 return platform_driver_register(&rk_fb_driver);
791 static void __exit rk_fb_exit(void)
793 platform_driver_unregister(&rk_fb_driver);
796 fs_initcall(rk_fb_init);
797 module_exit(rk_fb_exit);