📄 au1200fb.c
字号:
winbpp (unsigned int winctrl1){ /* how many bytes of memory are needed for each pixel format */ switch (winctrl1 & LCD_WINCTRL1_FRM) { case LCD_WINCTRL1_FRM_1BPP: return 1; break; case LCD_WINCTRL1_FRM_2BPP: return 2; break; case LCD_WINCTRL1_FRM_4BPP: return 4; break; case LCD_WINCTRL1_FRM_8BPP: return 8; break; case LCD_WINCTRL1_FRM_12BPP: return 16; break; case LCD_WINCTRL1_FRM_16BPP655: return 16; break; case LCD_WINCTRL1_FRM_16BPP565: return 16; break; case LCD_WINCTRL1_FRM_16BPP556: return 16; break; case LCD_WINCTRL1_FRM_16BPPI1555: return 16; break; case LCD_WINCTRL1_FRM_16BPPI5551: return 16; break; case LCD_WINCTRL1_FRM_16BPPA1555: return 16; break; case LCD_WINCTRL1_FRM_16BPPA5551: return 16; break; case LCD_WINCTRL1_FRM_24BPP: return 32; break; case LCD_WINCTRL1_FRM_32BPP: return 32; break; default: return 0; break; }}static intfbinfo2index (struct fb_info *fb_info){ int i; for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { if (fb_info == (struct fb_info *)(&fb_infos[i])) return i; } printk("au1200fb: ERROR: fbinfo2index failed!\n"); return -1;}static void au1200_detect(void){ /* * This function should detect the current video mode settings * and store it as the default video mode * Yeh, well, we're not going to change any settings so we're * always stuck with the default ... */}static int au1200_encode_fix(struct fb_fix_screeninfo *fix, const void *_par, struct fb_info_gen *_info){ struct au1200fb_info *info = (struct au1200fb_info *) _info; struct au1200fb_par *par = (struct au1200fb_par *) _par; //struct fb_var_screeninfo *var = &par->var; int plane; plane = fbinfo2index(info); memset(fix, 0, sizeof(struct fb_fix_screeninfo)); fix->smem_start = info->fb_phys; fix->smem_len = info->fb_size; fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; fix->visual = (par->var.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; fix->ywrapstep = 0; fix->xpanstep = 1; fix->ypanstep = 1;// FIX!!!! why doesn't par->line_length work???? it does for au1100 fix->line_length = fb_pars[plane].line_length; //par->line_length;//printk("par -> lline _ length %d\n", par->line_length); return 0;}static void set_color_bitfields(struct fb_var_screeninfo *var, int plane){ if (var->bits_per_pixel == 8) { var->red.offset = 0; var->red.length = 8; var->green.offset = 0; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 0; var->transp.length = 0; } else if (var->bits_per_pixel == 16) { /* FIX!!! How does CCO affect this ? */ /* FIX!!! Not exactly sure how many of these work with FB */ switch (win->w[plane].mode_winctrl1 & LCD_WINCTRL1_FRM) { case LCD_WINCTRL1_FRM_16BPP655: var->red.offset = 10; var->red.length = 6; var->green.offset = 5; var->green.length = 5; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_16BPP565: var->red.offset = 11; var->red.length = 5; var->green.offset = 5; var->green.length = 6; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_16BPP556: var->red.offset = 11; var->red.length = 5; var->green.offset = 6; var->green.length = 5; var->blue.offset = 0; var->blue.length = 6; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_16BPPI1555: var->red.offset = 10; var->red.length = 5; var->green.offset = 5; var->green.length = 5; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_16BPPI5551: var->red.offset = 11; var->red.length = 5; var->green.offset = 6; var->green.length = 5; var->blue.offset = 1; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_16BPPA1555: var->red.offset = 10; var->red.length = 5; var->green.offset = 5; var->green.length = 5; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 15; var->transp.length = 1; break; case LCD_WINCTRL1_FRM_16BPPA5551: var->red.offset = 11; var->red.length = 5; var->green.offset = 6; var->green.length = 5; var->blue.offset = 1; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 1; break; default: printk("ERROR: Invalid PIXEL FORMAT!!!\n"); break; } } else if (var->bits_per_pixel == 32) { switch (win->w[plane].mode_winctrl1 & LCD_WINCTRL1_FRM) { case LCD_WINCTRL1_FRM_24BPP: var->red.offset = 16; var->red.length = 8; var->green.offset = 8; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 0; var->transp.length = 0; break; case LCD_WINCTRL1_FRM_32BPP: var->red.offset = 16; var->red.length = 8; var->green.offset = 8; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 24; var->transp.length = 8; break; } } var->red.msb_right = 0; var->green.msb_right = 0; var->blue.msb_right = 0; var->transp.msb_right = 0;#if 0printk("set_color_bitfields(a=%d, r=%d..%d, g=%d..%d, b=%d..%d)\n", var->transp.offset, var->red.offset+var->red.length-1, var->red.offset, var->green.offset+var->green.length-1, var->green.offset, var->blue.offset+var->blue.length-1, var->blue.offset);#endif}static int au1200_decode_var(const struct fb_var_screeninfo *var, void *_par, struct fb_info_gen *_info){ struct au1200fb_par *par = (struct au1200fb_par *)_par; int plane, bpp; plane = fbinfo2index((struct fb_info *)_info);//printk("au1200_decode_var on plane %d\n", plane); /* * Don't allow setting any of these yet: xres and yres don't * make sense for LCD panels. */ if (var->xres != win->w[plane].xres || var->yres != win->w[plane].yres || var->xres != win->w[plane].xres || var->yres != win->w[plane].yres) { return -EINVAL; } bpp = winbpp(win->w[plane].mode_winctrl1); if(var->bits_per_pixel != bpp) { //return -EINVAL; on au1200, pixel format is independent of panel pixel printk("WARNING: bits_per_pizel != panel->bpp\n"); } memset(par, 0, sizeof(struct au1200fb_par)); par->var = *var; /* FIXME */ switch (var->bits_per_pixel) { case 8: par->var.bits_per_pixel = 8; break; case 16: par->var.bits_per_pixel = 16; break; case 24: case 32: par->var.bits_per_pixel = 32; break; default: printk("color depth %d bpp not supported\n", var->bits_per_pixel); return -EINVAL; } set_color_bitfields(&par->var, plane); /* FIX!!! what is this for 24/32bpp? */ par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16; return 0;}static int au1200_encode_var(struct fb_var_screeninfo *var, const void *par, struct fb_info_gen *_info){ *var = ((struct au1200fb_par *)par)->var; return 0;}static void au1200_get_par(void *_par, struct fb_info_gen *_info){ int index; index = fbinfo2index((struct fb_info *)_info); *(struct au1200fb_par *)_par = fb_pars[index]; //current_par;}static void au1200_set_par(const void *par, struct fb_info_gen *info){ /* nothing to do: we don't change any settings */}static int au1200_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info){ struct au1200fb_info* i = (struct au1200fb_info*)info;// printk("au1200_getcolreg...%d what does this actually do for >=16bpp\n", regno); if (regno > 255) return 1; *red = i->palette[regno].red; *green = i->palette[regno].green; *blue = i->palette[regno].blue; *transp = 0; return 0;}static int au1200_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){ struct au1200fb_info* i = (struct au1200fb_info *)info; u32 rgbcol; int plane, bpp; plane = fbinfo2index((struct fb_info *)info); bpp = winbpp(win->w[plane].mode_winctrl1);// printk("au1200_setcolreg...%d what does this actually do for >=16bpp\n", regno); if (regno > 255) return 1; i->palette[regno].red = red; i->palette[regno].green = green; i->palette[regno].blue = blue; switch(bpp) {#ifdef FBCON_HAS_CFB8 case 8: red >>= 10; green >>= 10; blue >>= 10; panel_reg->lcd_pallettebase[regno] = (blue&0x1f) | ((green&0x3f)<<5) | ((red&0x1f)<<11); break;#endif#ifdef FBCON_HAS_CFB16/* FIX!!!! depends upon pixel format */ case 16: i->fbcon_cmap16[regno] = ((red & 0xf800) >> 0) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); break;#endif#ifdef FBCON_HAS_CFB32 case 32: i->fbcon_cmap32[regno] = (((u32 )transp & 0xff00) << 16) | (((u32 )red & 0xff00) << 8) | (((u32 )green & 0xff00)) | (((u32 )blue & 0xff00) >> 8); break;#endif default: printk("unsupported au1200_setcolreg(%d)\n", bpp); break; } return 0;}static int au1200_blank(int blank_mode, struct fb_info_gen *_info){ struct au1200fb_info *fb_info = (struct au1200fb_info *)_info; int plane; /* Short-circuit screen blanking */ if (fb_info->noblanking) return 0; plane = fbinfo2index((struct fb_info *)_info); switch (blank_mode) { case VESA_NO_BLANKING: /* turn on panel */// printk("turn on panel\n"); if (panel->device_init) panel->device_init(); lcd->screen |= LCD_SCREEN_SEN; break; case VESA_VSYNC_SUSPEND: case VESA_HSYNC_SUSPEND: case VESA_POWERDOWN: /* turn off panel */// printk("turn off panel\n"); if (panel->device_shutdown) panel->device_shutdown(); lcd->screen &= ~LCD_SCREEN_SEN; while ((lcd->intstatus & LCD_INT_SD) == 0) ; lcd->intstatus = LCD_INT_SD; break; default: break; } return 0;}static void au1200_set_disp(const void *unused, struct display *disp, struct fb_info_gen *info){ struct au1200fb_info *fb_info; int plane; fb_info = (struct au1200fb_info *)info; disp->screen_base = (char *)fb_info->fb_virt_start; switch (disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: disp->dispsw = &fbcon_cfb8; if (fb_info->nohwcursor) fbcon_cfb8.cursor = au1200_nocursor; break;#endif#ifdef FBCON_HAS_CFB16 case 16: disp->dispsw = &fbcon_cfb16; disp->dispsw_data = fb_info->fbcon_cmap16; if (fb_info->nohwcursor) fbcon_cfb16.cursor = au1200_nocursor; break;#endif#ifdef FBCON_HAS_CFB32 case 32: disp->dispsw = &fbcon_cfb32; disp->dispsw_data = fb_info->fbcon_cmap32; if (fb_info->nohwcursor) fbcon_cfb32.cursor = au1200_nocursor; break;#endif default: disp->dispsw = &fbcon_dummy; disp->dispsw_data = NULL; break; }}static intau1200fb_mmap(struct fb_info *_fb, struct file *file, struct vm_area_struct *vma){ unsigned int len; unsigned long start=0, off; struct au1200fb_info *fb_info = (struct au1200fb_info *)_fb; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { return -EINVAL; } start = fb_info->fb_phys & PAGE_MASK; len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info->fb_size); off = vma->vm_pgoff << PAGE_SHIFT; if ((vma->vm_end - vma->vm_start + off) > len) { return -EINVAL; } off += start; vma->vm_pgoff = off >> PAGE_SHIFT; pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK; pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* This is an IO map - tell maydump to skip this VMA */ vma->vm_flags |= VM_IO; if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { return -EAGAIN; } fb_info->mmaped = 1; return 0;}int au1200_pan_display(const struct fb_var_screeninfo *var, struct fb_info_gen *info){ return 0;}static int au1200fb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, int con, struct fb_info *info){ int plane; plane = fbinfo2index(info);// printk("au1200fb: ioctl %d on plane %d\n", cmd, plane); if (cmd == 0x46FF) { au1200_lcd_getset_t iodata; if (copy_from_user(&iodata, (void *) arg, sizeof(au1200_lcd_getset_t))) return -EFAULT; switch (iodata.subcmd) { case AU1200_LCD_GET_WINENABLE: iodata.winenable.enable = (lcd->winenable & (1<<plane)) ? 1 : 0; break; case AU1200_LCD_SET_WINENABLE: { u32 winenable; winenable = lcd->winenable; winenable &= ~(1<<plane); winenable |= (iodata.winenable.enable) ? (1<<plane) : 0; lcd->winenable = winenable; } break; case AU1200_LCD_GET_WINLOCATION: iodata.winlocation.x = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21; iodata.winlocation.y = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10; break; case AU1200_LCD_SET_WINLOCATION: au1200_setlocation(plane, iodata.winlocation.x, iodata.winlocation.y); break; case AU1200_LCD_GET_WINSIZE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -