📄 hifb.c
字号:
unsigned long origin; RECT_t layer_rc; if (copy_from_user(&origin, argp, sizeof(origin))< 0) { return -EFAULT; } par->screen_startx = (origin >> 16) & 0x0fff; par->screen_starty = origin & 0x0fff; layer_rc.x = par->screen_startx; layer_rc.y = par->screen_starty; layer_rc.w = info->var.xres; layer_rc.h = info->var.yres; VOU_LayerSetRect(par->which_layer, layer_rc); break; } default: HI3510FB_TRACE("the command:%d is supported!\n", cmd); return -EINVAL; } return 0;}/****************************************************************************** Function : hi3510fb_open Description : open the framebuffer and enable the layer Data Accessed : Data Updated : Output : None struct fb_info *info Return : return 0 Others : 0******************************************************************************/static int hi3510fb_open (struct fb_info *info, int user){ hi3510fb_par *par = (hi3510fb_par *)info->par; int cnt = atomic_read(&par->ref_count); if( !cnt ) { VOU_LayerEnable(par->which_layer); } atomic_inc(&par->ref_count); return 0;}/****************************************************************************** Function : hi3510fb_release Description : open the framebuffer and enable the layer Data Accessed : Data Updated : Output : None struct fb_info *info Return : return 0 if succeed, otherwise return -EINVAL Others : 0******************************************************************************/static int hi3510fb_release (struct fb_info *info, int user){ hi3510fb_par *par = (hi3510fb_par *)info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) return -EINVAL; if (cnt == 1) { VOU_LayerDisable(par->which_layer); } atomic_dec(&par->ref_count); return 0;}static struct fb_ops gsthi3510fb_ops = { .owner = THIS_MODULE, .fb_open = hi3510fb_open, .fb_release = hi3510fb_release, .fb_check_var = hi3510fb_check_var, .fb_set_par = hi3510fb_set_par, .fb_pan_display = hi3510fb_pan_display, .fb_ioctl = hi3510fb_ioctl,};/****************************************************************************** Function : hi3510fb_overlay_probe Description : initialze the framebuffer for the overlay and set the register . Data Accessed : Data Updated : Output : None Input : int which_layer unsigned long vram_size Return : 0 if success; otherwise return error code Others : 0******************************************************************************/static int __init hi3510fb_overlay_probe(int which_layer, unsigned long vram_size) { int ret = 0; struct fb_info * info = NULL; hil_mmb_t * phil_mmb = NULL; RECT_t layer_rc; hi3510fb_par* par; info = framebuffer_alloc(sizeof(hi3510fb_par), NULL); if (!info) { HI3510FB_ERR("failed to malloc the fb_info!\n"); return -ENOMEM; } par = (hi3510fb_par*)(info + 1); info->par = (void*)par; par->which_layer = which_layer; par->alpha0 = par->alpha1 = HI3510FB_DEF_ALPHA; HI3510FB_FB_INFO(which_layer) = info; /*initialize the fix screen info*/ phil_mmb = hil_mmb_alloc(HI3510FB_NAME, vram_size, 0, 0, NULL); if (phil_mmb == NULL) { HI3510FB_ERR("failed to malloc the video memory, size: %ld !\n", vram_size); ret = -ENOMEM; goto ERR; } info->fix = gsthi3510fb_def_fix; info->fix.smem_start = hil_mmb_phys(phil_mmb); info->fix.smem_len = vram_size; info->fix.mmio_len = HI3510FB_2D_BASE_SIZE; info->fix.mmio_start = HI3510FB_2D_BASE_ADDR; if (which_layer == HI3510FB_OVLAYER_1) { strcat(info->fix.id,":ovl1"); } else { strcat(info->fix.id,":ovl2"); } info->screen_base = hil_mmb_map2kern(phil_mmb); if (!info->screen_base) { HI3510FB_ERR("failed to call hil_mmb_map2kern video memory, " "size:0x%x, start: 0x%lx\n", info->fix.smem_len, info->fix.smem_start); ret = -EIO; goto ERR; } memset(info->screen_base, 0x00, info->fix.smem_len); info->screen_size = info->fix.smem_len; info->var = gsthi3510fb_def_var; info->fbops = &gsthi3510fb_ops; info->flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_XPAN; /*malloc the color map only to avoid sememnt fault for FBIOGET_CMAP*/ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { ret = -ENOMEM; goto ERR; } if (register_framebuffer(info) < 0) { HI3510FB_ERR("failed to register_framebuffer!\n"); ret = -EINVAL; goto ERR; } /*set the register*/ VOU_LayerDefaultSetting(which_layer); VOU_LayerSetAddrAndStride(which_layer, info->fix.smem_start, 0, HI3510FB_DEF_STRIDE, 0); VOU_LayerSetDataType(which_layer, HI3510FB_DEF_PIXEL_FORMAT); layer_rc.x = HI3510FB_DEF_XSTART; layer_rc.y = HI3510FB_DEF_YSTART; layer_rc.w = HI3510FB_DEF_WIDTH; layer_rc.h = HI3510FB_DEF_HEIGHT; VOU_LayerSetRect(which_layer, layer_rc); VOU_LayerSetAlpha(which_layer, HI3510FB_DEF_ALPHA, HI3510FB_DEF_ALPHA);// VOU_LayerEnable(which_layer); HI3510FB_TRACE("succeed in registering the fb%d: %s frame buffer device\n", info->node, info->fix.id); return 0;ERR: hi3510fb_overlay_cleanup(which_layer, FALSE); return ret;}/****************************************************************************** Function : hi3510fb_overlay_cleanup Description : releae the resource for certain framebuffer Data Accessed : Data Updated : Output : None Input : int which_layer int need_unregister Return : static Others : 0******************************************************************************/static void __exit hi3510fb_overlay_cleanup(int which_layer, int need_unregister){ struct fb_info* info = NULL; hil_mmb_t* phil_mmb = NULL; struct fb_cmap* cmap = NULL; HI3510FB_TRACE("start to cleanup the ovelay:%d!\n", which_layer); info = HI3510FB_FB_INFO(which_layer); if (info != NULL) { cmap = &info->cmap; if (cmap->len != 0); { fb_dealloc_cmap(cmap); } if (info->fix.smem_start != 0) { phil_mmb = hil_mmb_getby_phys(info->fix.smem_start); hil_mmb_free(phil_mmb); } if (need_unregister) { unregister_framebuffer(info); } framebuffer_release(info); HI3510FB_FB_INFO(which_layer) = NULL; } HI3510FB_TRACE("end with cleanup the ovelay:%d!\n", which_layer); }/****************************************************************************** Function : hi3510fb_get_vram_size Description : parse the parameter string and get the size. if the parameter is invalid, the size is default value. Data Accessed : Data Updated : Output : None Input : const char* pstr the string for the vram size Return : the video memory size Others : 0******************************************************************************/static unsigned long hi3510fb_get_vram_size(const char* pstr){ int str_is_valid = TRUE; unsigned long vram_size = 0; const char* ptr = pstr; if (ptr==NULL || *ptr=='\0') { return HI3510FB_DEF_VRAM_SIZE; } /*check if the string is valid*/ while (*ptr != '\0') { if (!isdigit(*ptr)) { str_is_valid = FALSE; break; } *ptr++; } if (str_is_valid) { vram_size = simple_strtoul(pstr, NULL, 0); /*make the size PAGE_SIZE align*/ vram_size = (vram_size+PAGE_SIZE-1) & PAGE_MASK; } if (0 == vram_size) { vram_size = HI3510FB_DEF_VRAM_SIZE; } return vram_size;}/****************************************************************************** Function : hi3510fb_setup Description : get the video memory size from kernel parameter. the kernel parameter should be: "video=hi3510fb:vram1_size:xxx,vram2_size:xxx" Data Accessed : Data Updated : Output : None Input : unsigned long* pvram1_size memory size of overlayer 1 unsigned long* pvram2_size memory size of overlayer 1 Return : NA Others : 0******************************************************************************/static void hi3510fb_setup(unsigned long* pvram1_size, unsigned long* pvram2_size){ char* pszoptions = NULL; char* pszthis_opt = NULL;#ifdef MODULE /*video="hi3510fb:vram1_size:xxx,vram2_size2:xxx"*/ pszoptions = video + sizeof(HI3510FB_NAME);#else fb_get_options(HI3510FB_NAME, &pszoptions);#endif *pvram1_size = *pvram2_size = HI3510FB_DEF_VRAM_SIZE; if (pszoptions == NULL) { return; } HI3510FB_TRACE("option string is: %s!\n", pszoptions); /*parse the string and get the vram size from the option string*/ while ((pszthis_opt = strsep(&pszoptions, ",")) != NULL) { if (!*pszthis_opt) { continue; } if (!strncmp(HI3510FB_OVL1_OPT_NAME, pszthis_opt, HI3510FB_OVL_OPT_NAME_LEN)) { pszthis_opt += HI3510FB_OVL_OPT_NAME_LEN; *pvram1_size = hi3510fb_get_vram_size(pszthis_opt); } else if (!strncmp(HI3510FB_OVL2_OPT_NAME, pszthis_opt, HI3510FB_OVL_OPT_NAME_LEN)) { pszthis_opt += HI3510FB_OVL_OPT_NAME_LEN; *pvram2_size = hi3510fb_get_vram_size(pszthis_opt); } } HI3510FB_TRACE("ovleray1 vram_size:%ld, ovleray2 vram_size:%ld !\n", *pvram1_size, *pvram2_size);}/****************************************************************************** Function : hi3510fb_init Description : initialize framebuffer. the function is called when loading the moudel Data Accessed : Data Updated : Output : None Input : void Return : 0, if success; otherwise, return error code Others : 0******************************************************************************/static int __init hi3510fb_init(void){ int ret1 = -1, ret2 = -1; unsigned long vram1_size = 0, vram2_size = 0; VOU_Init(); hi3510fb_setup(&vram1_size, &vram2_size); if (vram1_size >= HI3510FB_MIN_VRAM_SIZE) { ret1 = hi3510fb_overlay_probe(HI3510FB_OVLAYER_1, vram1_size); } if (vram2_size >= HI3510FB_MIN_VRAM_SIZE) { ret2 = hi3510fb_overlay_probe(HI3510FB_OVLAYER_2, vram2_size); } /*if failed to initialize both the overlay, exit*/ if (ret1<0 && ret2<0) { HI3510FB_TRACE("failed to initialize the fb!\n"); return -EINVAL; } return 0;}/****************************************************************************** Function : hi3510fb_cleanup Description : cleanup the resource when exiting the framebuffer module Data Accessed : Data Updated : Output : None Input : void Return : static Others : 0******************************************************************************/static void __exit hi3510fb_cleanup(void){ hi3510fb_overlay_cleanup(HI3510FB_OVLAYER_1, TRUE); hi3510fb_overlay_cleanup(HI3510FB_OVLAYER_2, TRUE);}#ifdef MODULEmodule_init(hi3510fb_init);module_exit(hi3510fb_cleanup);MODULE_LICENSE("GPL");#elsesubsys_initcall(hi3510fb_init);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -