int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) { int size = len*sizeof(u16); if (cmap->len != len) { fb_dealloc_cmap(cmap); if (!len) return 0; if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) goto fail; if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) goto fail; if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) goto fail; if (transp) { if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) goto fail; } else cmap->transp = NULL; } cmap->start = 0; cmap->len = len; fb_copy_cmap(fb_default_cmap(len), cmap); return 0; fail: fb_dealloc_cmap(cmap); return -ENOMEM; }
int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) { int i, start, rc = 0; u16 *red, *green, *blue, *transp; u_int hred, hgreen, hblue, htransp = 0xffff; red = cmap->red; green = cmap->green; blue = cmap->blue; transp = cmap->transp; start = cmap->start; if (start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) return -EINVAL; if (info->fbops->fb_setcmap) { rc = info->fbops->fb_setcmap(cmap, info); } else { for (i = 0; i < cmap->len; i++) { hred = *red++; hgreen = *green++; hblue = *blue++; if (transp) htransp = *transp++; if (info->fbops->fb_setcolreg(start++, hred, hgreen, hblue, htransp, info)) break; } } if (rc == 0) fb_copy_cmap(cmap, &info->cmap); return rc; }
int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_info_gen *info2 = (struct fb_info_gen *)info; struct fbgen_hwswitch *fbhw = info2->fbhw; if (con == currcon) /* current console ? */ return fb_get_cmap(cmap, kspc, fbhw->getcolreg, info); else if (fb_display[con].cmap.len) /* non default colormap ? */ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); else { int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256; fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2); } return 0; }
static int aafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { static u16 color[2] = {0x0000, 0x000f}; static struct fb_cmap aafb_cmap = {0, 2, color, color, color, NULL}; fb_copy_cmap(&aafb_cmap, cmap, kspc ? 0 : 2); return 0; }
/** * fbgen_get_cmap - get the colormap * @cmap: frame buffer colormap structure * @kspc: boolean, 0 copy local, 1 put_user() function * @con: virtual console number * @info: frame buffer info structure * * Gets the colormap for virtual console @con and places it into * @cmap for device @info. * * Returns negative errno on error, or zero for success. * */ int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_cmap *dcmap; if (con == info->currcon) dcmap = &info->cmap; else dcmap = &fb_display[con].cmap; fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2); return 0; }
static int vfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { int err; if (!fb_display[con].cmap.len) { /* no colormap allocated? */ if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0))) return err; } if (con == currcon) /* current console? */ return fb_set_cmap(cmap, kspc, vfb_setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_info_gen *info2 = (struct fb_info_gen *)info; struct fbgen_hwswitch *fbhw = info2->fbhw; int err; if (!fb_display[con].cmap.len) { /* no colormap allocated ? */ int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256; if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0))) return err; } if (con == currcon) /* current console ? */ return fb_set_cmap(cmap, kspc, fbhw->setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
static int igafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { int err; struct fb_info_iga *fb = (struct fb_info_iga*) info; if (!fb_display[con].cmap.len) { /* no colormap allocated? */ err = fb_alloc_cmap(&fb_display[con].cmap, fb->video_cmap_len,0); if (err) return err; } if (con == fb->currcon) /* current console? */ return fb_set_cmap(cmap, kspc, iga_setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { int err; if (!fb_display[con].cmap.len) { /* no colormap allocated? */ if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0))) return err; } if (con == info->currcon) { /* current console? */ err = fb_set_cmap(cmap, kspc, info); if (!err) { struct fb_info_sbusfb *fb = sbusfbinfo(info); if (fb->loadcmap) (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len); } return err; } else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_cmap *dcmap; int err = 0; if (con == info->currcon) dcmap = &info->cmap; else dcmap = &fb_display[con].cmap; /* no colormap allocated? */ if (!dcmap->len) err = fb_alloc_cmap(dcmap, 256, 0); if (!err && con == info->currcon) err = fb_set_cmap(cmap, kspc, info->fbops->fb_setcolreg, info); if (!err) fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1); return err; }
int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags) { int size = len * sizeof(u16); int ret = -ENOMEM; if (cmap->len != len) { fb_dealloc_cmap(cmap); if (!len) return 0; cmap->red = kmalloc(size, flags); if (!cmap->red) goto fail; cmap->green = kmalloc(size, flags); if (!cmap->green) goto fail; cmap->blue = kmalloc(size, flags); if (!cmap->blue) goto fail; if (transp) { cmap->transp = kmalloc(size, flags); if (!cmap->transp) goto fail; } else { cmap->transp = NULL; } } cmap->start = 0; cmap->len = len; ret = fb_copy_cmap(fb_default_cmap(len), cmap); if (ret) goto fail; return 0; fail: fb_dealloc_cmap(cmap); return ret; }
int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) { int i, start, rc = 0; u16 *red, *green, *blue, *transp; u_int hred, hgreen, hblue, htransp = 0xffff; red = cmap->red; green = cmap->green; blue = cmap->blue; transp = cmap->transp; start = cmap->start; if (start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) return -EINVAL; if (info->fbops->fb_setcmap) { rc = info->fbops->fb_setcmap(cmap, info); } else { for (i = 0; i < cmap->len; i++) { hred = *red++; hgreen = *green++; hblue = *blue++; if (transp) htransp = *transp++; if (info->fbops->fb_setcolreg(start++, hred, hgreen, hblue, htransp, info)) break; } } if (rc == 0) { fb_copy_cmap(cmap, &info->cmap); if (fbcon_decor_active(info, vc_cons[fg_console].d) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d); } return rc; }
struct fb_info* einkfb_probe(struct platform_device *dev) { einkfb_init_err_t err = einkfb_init_err_none; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_info *info = NULL; boot_milestone_write(EINK_HAL_STARTED_BOM, EINK_HAL_STARTED_BOM_SZ); if ( !(info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev)) ) goto err1; // einkfb_init_err_framebuffer_alloc einkfb_fbinfo = info; info->fbops = &einkfb_ops; /* * Get the module's variable & fixed screeninfo. */ if ( EINKFB_FAILURE == HAL_SW_INIT(&var, &fix) ) goto err2; // einkfb_init_err_hw_sw_init /* * Allocate an address space for our real, virtual, and scratch buffers. */ einkfb_blen = BPP_SIZE((var.xres * (var.yres + 1)), var.bits_per_pixel); einkfb_size = BPP_SIZE((var.xres * var.yres), var.bits_per_pixel); einkfb_mem = FB_ROUNDUP(einkfb_blen, PAGE_SIZE) * 3; einkfb_dma = HAL_NEEDS_DMA(); if ( !(einkfb = EINKFB_MALLOC_HAL(einkfb_mem, einkfb_dma ? &einkfb_phys : NULL)) ) goto err3; // einkfb_init_err_einkfb_malloc_hal /* * Clear memory to prevent kernel info from "leaking" * into userspace. */ einkfb_memset(einkfb, einkfb_white(var.bits_per_pixel), einkfb_mem); fix.smem_start = einkfb_dma ? (unsigned long)einkfb_phys.addr : (unsigned long)einkfb; fix.smem_len = (einkfb_mem/3) << 1; /* real & virtual */ info->screen_base = (char __iomem *)einkfb; info->screen_size = einkfb_mem/3; /* just real */ info->var = var; info->fix = fix; info->pseudo_palette = NULL; /* info->par */ info->par = NULL; info->flags = FBINFO_FLAG_DEFAULT; if ( fb_alloc_cmap(&info->cmap, BPP_MAX(var.bits_per_pixel), 0) < 0 ) goto err4; // einkfb_init_err_fb_alloc_cmap switch ( var.bits_per_pixel ) { case EINKFB_1BPP: fb_copy_cmap(&einkfb_1bpp_cmap, &info->cmap); break; case EINKFB_2BPP: fb_copy_cmap(&einkfb_2bpp_cmap, &info->cmap); break; case EINKFB_4BPP: fb_copy_cmap(&einkfb_4bpp_cmap, &info->cmap); break; case EINKFB_8BPP: fb_copy_cmap(&einkfb_8bpp_cmap, &info->cmap); break; } einkfb_bpp = info->var.bits_per_pixel; einkfb_xres = info->var.xres; einkfb_yres = info->var.yres; einkfb_vfb = einkfb + info->screen_size; einkfb_buf = einkfb_vfb + info->screen_size; einkfb_hw_bringup_mode_actual = HAL_HW_INIT(info, einkfb_hw_bringup_mode); einkfb_align_x = einkfb_set_byte_alignment_x(einkfb_bpp); einkfb_align_y = einkfb_set_byte_alignment_y(einkfb_bpp); if ( register_framebuffer(info) < 0 ) goto err5; // einkfb_init_err_register_framebuffer BLANK_INIT(); boot_milestone_write(EINK_HAL_LOADED_BOM, EINK_HAL_LOADED_BOM_SZ); return info; err5: err++; // err = einkfb_init_err_register_framebuffer err4: err++; // err = einkfb_init_err_fb_alloc_cmap err3: err++; // err = einkfb_init_err_einkfb_malloc_hal err2: err++; // err = einkfb_init_err_hw_sw_init err1: err++; // err = einkfb_init_err_fb_info_alloc einkfb_remove(info, err); return NULL; }