int s3cfb_open_fifo(int id, int ch, int (*do_priv) (void *), void *param) { struct s3cfb_global *fbdev = get_fimd_global(id); struct s3cfb_window *win = fbdev->fb[id]->par; dev_dbg(fbdev->dev, "[fb%d] open fifo\n", win->id); if (win->path == DATA_PATH_DMA) { dev_err(fbdev->dev, "WIN%d is busy.\n", id); return -EFAULT; } win->local_channel = ch; if (do_priv) { if (do_priv(param)) { dev_err(fbdev->dev, "failed to run for " "private fifo open\n"); s3cfb_enable_window(fbdev, id); return -EFAULT; } } s3cfb_set_window_control(fbdev, id); s3cfb_enable_window(fbdev, id); s3cfb_enable_localpath(fbdev, id); return 0; }
/* new function to open fifo */ int s3cfb_open_fifo(int id, int ch, int (*do_priv)(void *), void *param) { struct s3cfb_window *win = ctrl->fb[id]->par; dev_dbg(ctrl->dev, "[fb%d] open fifo\n", win->id); win->path = DATA_PATH_FIFO; win->local_channel = ch; s3cfb_set_vsync_interrupt(ctrl, 1); s3cfb_wait_for_vsync(); s3cfb_set_vsync_interrupt(ctrl, 0); if (do_priv) { if (do_priv(param)) { dev_err(ctrl->dev, "failed to run for private fifo open\n"); s3cfb_enable_window(id); return -EFAULT; } } s3cfb_set_window_control(ctrl, id); s3cfb_enable_window(id); return 0; }
int s3cfb_close_fifo(int id, int (*do_priv) (void *), void *param) { struct s3cfb_global *fbdev = get_fimd_global(id); struct s3cfb_window *win = fbdev->fb[id]->par; win->path = DATA_PATH_DMA; dev_dbg(fbdev->dev, "[fb%d] close fifo\n", win->id); if (do_priv) { s3cfb_display_off(fbdev); if (do_priv(param)) { dev_err(fbdev->dev, "failed to run for" "private fifo close\n"); s3cfb_enable_window(fbdev, id); s3cfb_display_on(fbdev); return -EFAULT; } s3cfb_disable_window(fbdev, id); s3cfb_disable_localpath(fbdev, id); s3cfb_display_on(fbdev); } else { s3cfb_disable_window(fbdev, id); s3cfb_disable_localpath(fbdev, id); } return 0; }
static int s3cfb_sysfs_store_win_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct s3c_platform_fb *pdata = to_fb_plat(dev); char temp[4] = { 0, }; const char *p = buf; int id, to; while (*p != '\0') { if (!isspace(*p)) strncat(temp, p, 1); p++; } if (strlen(temp) != 2) return -EINVAL; id = simple_strtoul(temp, NULL, 10) / 10; to = simple_strtoul(temp, NULL, 10) % 10; if (id < 0 || id > pdata->nr_wins) return -EINVAL; if (to != 0 && to != 1) return -EINVAL; if (to == 0) s3cfb_disable_window(id); else s3cfb_enable_window(id); return len; }
/* new function to close fifo */ int s3cfb_close_fifo(int id, int (*do_priv)(void *), void *param, int sleep) { struct s3cfb_window *win = ctrl->fb[id]->par; dev_dbg(ctrl->dev, "[fb%d] close fifo\n", win->id); if (sleep) win->path = DATA_PATH_FIFO; else win->path = DATA_PATH_DMA; s3cfb_set_vsync_interrupt(ctrl, 1); s3cfb_wait_for_vsync(); s3cfb_set_vsync_interrupt(ctrl, 0); s3cfb_display_off(ctrl); s3cfb_check_line_count(ctrl); s3cfb_disable_window(id); if (do_priv) { if (do_priv(param)) { dev_err(ctrl->dev, "failed to run for private fifo close\n"); s3cfb_enable_window(id); s3cfb_display_on(ctrl); return -EFAULT; } } s3cfb_display_on(ctrl); return 0; }
static int s3cfb_blank(int blank_mode, struct fb_info *fb) { struct s3cfb_window *win = fb->par; dev_dbg(ctrl->dev, "change blank mode\n"); switch (blank_mode) { case FB_BLANK_UNBLANK: if (fb->fix.smem_start) s3cfb_enable_window(win->id); else dev_info(ctrl->dev, "[fb%d] no allocated memory for unblank\n", win->id); break; case FB_BLANK_POWERDOWN: s3cfb_disable_window(win->id); break; default: dev_dbg(ctrl->dev, "unsupported blank mode\n"); return -EINVAL; } return 0; }
/* for backward compatibilities */ void s3cfb_enable_local(int id, int in_yuv, int ch) { struct s3cfb_window *win = ctrl->fb[id]->par; win->path = DATA_PATH_FIFO; win->local_channel = ch; s3cfb_set_vsync_interrupt(ctrl, 1); s3cfb_wait_for_vsync(); s3cfb_set_vsync_interrupt(ctrl, 0); s3cfb_set_window_control(ctrl, id); s3cfb_enable_window(id); }
int s3cfb_resume(struct platform_device *pdev) { struct s3c_platform_fb *pdata = to_fb_plat(&pdev->dev); struct fb_info *fb; struct s3cfb_window *win; int i; dev_dbg(ctrl->dev, "wake up from suspend\n"); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); if (ctrl->lcd->init_ldi) ctrl->lcd->init_ldi(); clk_enable(ctrl->clock); s3cfb_init_global(); s3cfb_set_clock(ctrl); s3cfb_display_on(ctrl); for (i = 0; i < pdata->nr_wins; i++) { fb = ctrl->fb[i]; win = fb->par; if (win->path == DATA_PATH_FIFO && win->resume_fifo) { if (win->resume_fifo()) dev_info(ctrl->dev, "failed to run the resume for fifo\n"); } else { if (win->enabled) { s3cfb_check_var(&fb->var, fb); s3cfb_set_par(fb); s3cfb_enable_window(win->id); } } } return 0; }
int s3cfb_resume(struct platform_device *pdev) { struct s3c_platform_fb *pdata = to_fb_plat(&pdev->dev); struct fb_info *fb; struct s3cfb_window *win; int i; dev_dbg(fbdev->dev, "wake up from suspend\n"); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); #if defined(CONFIG_FB_S3C_TL2796) if (pdata->backlight_on) pdata->backlight_on(pdev); #elif defined (CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UT10GM) || defined(CONFIG_FB_S3C_UT7GM) || defined(CONFIG_FB_URBETTER_SERIAL) || defined(CONFIG_FB_S3C_UTAUO104) if (pdata->backlight_on) pdata->backlight_on(pdev); #endif if (pdata->lcd_on) pdata->lcd_on(pdev); if (fbdev->lcd->init_ldi) fbdev->lcd->init_ldi(); if (pdata->backlight_off) pdata->backlight_off(pdev); if (pdata->lcd_off) pdata->lcd_off(pdev); if (fbdev->lcd->deinit_ldi) fbdev->lcd->deinit_ldi(); if (atomic_read(&fbdev->enabled_win) > 0) { pdata->clk_on(pdev, &fbdev->clock); s3cfb_init_global(); s3cfb_set_clock(fbdev); for (i = 0; i < pdata->nr_wins; i++) { fb = fbdev->fb[i]; win = fb->par; if (win->owner == DMA_MEM_FIMD) { s3cfb_set_win_params(win->id); if (win->enabled) { if (win->power_state == FB_BLANK_NORMAL) s3cfb_win_map_on(fbdev, win->id, 0x0); s3cfb_enable_window(win->id); } } } s3cfb_display_on(fbdev); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); if (fbdev->lcd->init_ldi) fbdev->lcd->init_ldi(); } return 0; }
void s3cfb_late_resume(struct early_suspend *h) { struct s3cfb_global *info = container_of(h,struct s3cfb_global,early_suspend); struct s3c_platform_fb *pdata = to_fb_plat(info->dev); struct fb_info *fb; struct s3cfb_window *win; int i, j; struct platform_device *pdev = to_platform_device(info->dev); printk("s3cfb_late_resume is called\n"); //urbetter if (pdata->backlight_off) pdata->backlight_off(pdev); #ifdef ENABLE_SMDKV210_REGULATOR //urbetter /* ldo6 regulator on */ regulator_enable(lcd_regulator); #endif dev_dbg(info->dev, "wake up from suspend\n"); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); #if defined(CONFIG_FB_S3C_DUMMYLCD) max8698_ldo_enable_direct(MAX8698_LDO4); #endif #if defined (CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UT10GM) || defined(CONFIG_FB_S3C_UT7GM) || defined(CONFIG_FB_URBETTER_SERIAL) || defined(CONFIG_FB_S3C_UTAUO104) if (info->lcd->init_ldi) fbdev->lcd->init_ldi(); else printk("no init_ldi\n"); #endif if (pdata->clk_on) pdata->clk_on(pdev, &fbdev->clock); s3cfb_init_global(); s3cfb_set_clock(info); s3cfb_display_on(info); for (i = pdata->default_win; i < pdata->nr_wins + pdata->default_win; i++) { j = i % pdata->nr_wins; fb = info->fb[j]; win = fb->par; if ((win->path == DATA_PATH_DMA) && (win->enabled)) { s3cfb_set_par(fb); s3cfb_enable_window(win->id); } } #if 1 // enable VSYNC s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); #endif /* Reset the LDI chip */ if (pdata->lcd_on) pdata->lcd_on(pdev); #if defined(CONFIG_FB_S3C_TL2796) tl2796_ldi_init(); tl2796_ldi_enable(); #elif defined (CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UT10GM) || defined(CONFIG_FB_S3C_UT7GM) || defined(CONFIG_FB_URBETTER_SERIAL) || defined(CONFIG_FB_S3C_UTAUO104) if (info->lcd->init_ldi) fbdev->lcd->init_ldi(); else printk("no init_ldi\n"); #endif if (pdata->backlight_on) pdata->backlight_on(pdev); return ; }
static int s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata; struct resource *res; int ret = 0; #ifdef ENABLE_SMDKV210_REGULATOR //urbetter /* ldo6 regulator on */ printk("\t %s \n", __func__); lcd_regulator = regulator_get(NULL, "vddlcd"); if (IS_ERR(lcd_regulator)) { printk(KERN_ERR "failed to get resource %s\n", "vddlcd"); return PTR_ERR(lcd_regulator); } regulator_enable(lcd_regulator); #endif /* initialzing global structure */ fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); if (!fbdev) { dev_err(fbdev->dev, "failed to allocate for " "global fb structure\n"); goto err_global; } fbdev->dev = &pdev->dev; s3cfb_set_lcd_info(fbdev); /* gpio */ pdata = to_fb_plat(&pdev->dev); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->clk_on) pdata->clk_on(pdev, &fbdev->clock); /* io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(fbdev->dev, "failed to get io memory region\n"); ret = -EINVAL; goto err_io; } /* request mem region */ res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { dev_err(fbdev->dev, "failed to request io memory region\n"); ret = -EINVAL; goto err_io; } /* ioremap for register block */ fbdev->regs = ioremap(res->start, res->end - res->start + 1); if (!fbdev->regs) { dev_err(fbdev->dev, "failed to remap io region\n"); ret = -EINVAL; goto err_io; } /* irq */ fbdev->irq = platform_get_irq(pdev, 0); if (request_irq(fbdev->irq, s3cfb_irq_frame, IRQF_SHARED, pdev->name, fbdev)) { dev_err(fbdev->dev, "request_irq failed\n"); ret = -EINVAL; goto err_irq; } #if 1 // added by jamie (2009.08.18) // enable VSYNC s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); #endif #ifdef CONFIG_FB_S3C_TRACE_UNDERRUN if (request_irq(platform_get_irq(pdev, 1), s3cfb_irq_fifo, IRQF_DISABLED, pdev->name, fbdev)) { dev_err(fbdev->dev, "request_irq failed\n"); ret = -EINVAL; goto err_irq; } s3cfb_set_fifo_interrupt(fbdev, 1); dev_info(fbdev->dev, "fifo underrun trace\n"); #endif /* init global */ s3cfb_init_global(); /* prepare memory */ if (s3cfb_alloc_framebuffer()) goto err_alloc; if (s3cfb_register_framebuffer()) goto err_alloc; s3cfb_set_clock(fbdev); s3cfb_enable_window(pdata->default_win); s3cfb_update_power_state(pdata->default_win, FB_BLANK_UNBLANK); s3cfb_display_on(fbdev); #ifdef CONFIG_FB_S3C_LCD_INIT /* panel control */ #if defined(CONFIG_FB_S3C_TL2796) if (pdata->backlight_on) pdata->backlight_on(pdev); #elif defined(CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UT10GM) || defined(CONFIG_FB_S3C_UT7GM) || defined(CONFIG_FB_URBETTER_SERIAL) || defined(CONFIG_FB_S3C_UTAUO104) if (pdata->backlight_on) pdata->backlight_on(pdev); #endif if (pdata->lcd_on) pdata->lcd_on(pdev); //urbetter+ for backlight. //FIXME: not here. if (fbdev->lcd->init_ldi) fbdev->lcd->init_ldi(); #endif #ifdef CONFIG_HAS_WAKELOCK #ifdef CONFIG_HAS_EARLYSUSPEND fbdev->early_suspend.suspend = s3cfb_early_suspend; fbdev->early_suspend.resume = s3cfb_late_resume; fbdev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; //if, is in USER_SLEEP status and no active auto expiring wake lock //if (has_wake_lock(WAKE_LOCK_SUSPEND) == 0 && get_suspend_state() == PM_SUSPEND_ON) register_early_suspend(&fbdev->early_suspend); #endif #endif ret = device_create_file(&(pdev->dev), &dev_attr_win_power); if (ret < 0) dev_err(fbdev->dev, "failed to add sysfs entries\n"); dev_info(fbdev->dev, "registered successfully\n"); return 0; err_alloc: free_irq(fbdev->irq, fbdev); err_irq: iounmap(fbdev->regs); err_io: if (pdata->clk_off) pdata->clk_off(pdev, &fbdev->clock); err_global: return ret; }
static int s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata = NULL; struct resource *res = NULL; struct s3cfb_global *fbdev[2]; int ret = 0; int i = 0; u32 reg; #ifdef CONFIG_EXYNOS_DEV_PD /* to use the runtime PM helper functions */ pm_runtime_enable(&pdev->dev); /* enable the power domain */ pm_runtime_get_sync(&pdev->dev); #endif fbfimd = kzalloc(sizeof(struct s3cfb_fimd_desc), GFP_KERNEL); if (FIMD_MAX == 2) fbfimd->dual = 1; else fbfimd->dual = 0; for (i = 0; i < FIMD_MAX; i++) { /* global structure */ fbfimd->fbdev[i] = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); fbdev[i] = fbfimd->fbdev[i]; if (!fbdev[i]) { dev_err(fbdev[i]->dev, "failed to allocate for \ global fb structure fimd[%d]!\n", i); ret = -ENOMEM; goto err0; } fbdev[i]->dev = &pdev->dev; #if defined(CONFIG_MACH_SMDK4X12) || defined(CONFIG_FB_S5P_AMS369FG06) s3cfb_set_lcd_info(fbdev[i]); #endif /* platform_data*/ pdata = to_fb_plat(&pdev->dev); if (pdata->lcd) fbdev[i]->lcd = (struct s3cfb_lcd *)pdata->lcd; if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->clk_on) pdata->clk_on(pdev, &fbdev[i]->clock); /* io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) { dev_err(fbdev[i]->dev, "failed to get io memory region\n"); ret = -EINVAL; goto err1; } res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { dev_err(fbdev[i]->dev, "failed to request io memory region\n"); ret = -EINVAL; goto err1; } fbdev[i]->regs = ioremap(res->start, res->end - res->start + 1); fbdev[i]->regs_org = fbdev[i]->regs; if (!fbdev[i]->regs) { dev_err(fbdev[i]->dev, "failed to remap io region\n"); ret = -EINVAL; goto err1; } /* irq */ fbdev[i]->irq = platform_get_irq(pdev, 0); if (request_irq(fbdev[i]->irq, s3cfb_irq_frame, IRQF_SHARED, pdev->name, fbdev[i])) { dev_err(fbdev[i]->dev, "request_irq failed\n"); ret = -EINVAL; goto err2; } #ifdef CONFIG_FB_S5P_TRACE_UNDERRUN if (request_irq(platform_get_irq(pdev, 1), s3cfb_irq_fifo, IRQF_DISABLED, pdev->name, fbdev[i])) { dev_err(fbdev[i]->dev, "request_irq failed\n"); ret = -EINVAL; goto err2; } s3cfb_set_fifo_interrupt(fbdev[i], 1); dev_info(fbdev[i]->dev, "fifo underrun trace\n"); #endif #ifdef CONFIG_FB_S5P_MDNIE /* only FIMD0 is supported */ if (i == 0) s3c_mdnie_setup(); #endif /* hw setting */ s3cfb_init_global(fbdev[i]); fbdev[i]->system_state = POWER_ON; /* alloc fb_info */ if (s3cfb_alloc_framebuffer(fbdev[i], i)) { dev_err(fbdev[i]->dev, "alloc error fimd[%d]\n", i); ret = -ENOMEM; goto err3; } /* register fb_info */ if (s3cfb_register_framebuffer(fbdev[i])) { dev_err(fbdev[i]->dev, "register error fimd[%d]\n", i); return -EINVAL; goto err3; } /* enable display */ s3cfb_set_clock(fbdev[i]); #ifdef CONFIG_FB_S5P_MDNIE /* only FIMD0 is supported */ if (i == 0) { reg = readl(S3C_VA_SYS + 0x0210); reg &= ~(1<<13); reg &= ~(1<<12); reg &= ~(3<<10); reg |= (1<<0); reg &= ~(1<<1); writel(reg, S3C_VA_SYS + 0x0210); writel(3, fbdev[i]->regs + 0x27c); s3c_mdnie_init_global(fbdev[i]); s3c_mdnie_start(fbdev[i]); } #endif s3cfb_enable_window(fbdev[0], pdata->default_win); s3cfb_update_power_state(fbdev[i], pdata->default_win, FB_BLANK_UNBLANK); /* Set alpha value width to 8-bit */ s3cfb_set_alpha_value_width(fbdev[i], i); #ifndef CONFIG_MACH_JENGA s3cfb_display_on(fbdev[i]); #endif #if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) #ifdef CONFIG_BUSFREQ_OPP /* To lock bus frequency in OPP mode */ fbdev[i]->bus_dev = dev_get("exynos-busfreq"); #endif #endif #ifdef CONFIG_HAS_WAKELOCK #ifdef CONFIG_HAS_EARLYSUSPEND fbdev[i]->early_suspend.suspend = s3cfb_early_suspend; fbdev[i]->early_suspend.resume = s3cfb_late_resume; fbdev[i]->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; register_early_suspend(&fbdev[i]->early_suspend); #endif #endif ret = device_create_file(fbdev[i]->dev, &dev_attr_fimd_dump); if (ret < 0) dev_err(fbdev[0]->dev, "failed to add sysfs entries\n"); ret = device_create_file(fbdev[i]->dev, &dev_attr_ielcd_dump); if (ret < 0) dev_err(fbdev[0]->dev, "failed to add sysfs entries\n"); }
static int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) { struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev); struct fb_var_screeninfo *var = &fb->var; struct s3cfb_window *win = fb->par, *win_temp; struct s3cfb_lcd *lcd = ctrl->lcd; int ret = 0, i; union { struct s3cfb_user_window user_window; struct s3cfb_user_plane_alpha user_alpha; struct s3cfb_user_chroma user_chroma; int vsync; } p; switch (cmd) { case FBIO_WAITFORVSYNC: s3cfb_wait_for_vsync(); break; case S3CFB_WIN_ON: s3cfb_enable_window(win->id); break; case S3CFB_WIN_OFF: s3cfb_disable_window(win->id); break; case S3CFB_WIN_OFF_ALL: for (i = 0; i < pdata->nr_wins; i++) { win_temp = ctrl->fb[i]->par; s3cfb_disable_window(win_temp->id); } break; case S3CFB_WIN_POSITION: if (copy_from_user(&p.user_window, (struct s3cfb_user_window __user *) arg, sizeof(p.user_window))) ret = -EFAULT; else { if (p.user_window.x < 0) p.user_window.x = 0; if (p.user_window.y < 0) p.user_window.y = 0; if (p.user_window.x + var->xres > lcd->width) win->x = lcd->width - var->xres; else win->x = p.user_window.x; if (p.user_window.y + var->yres > lcd->height) win->y = lcd->height - var->yres; else win->y = p.user_window.y; s3cfb_set_window_position(ctrl, win->id); } break; case S3CFB_WIN_SET_PLANE_ALPHA: if (copy_from_user(&p.user_alpha, (struct s3cfb_user_plane_alpha __user *) arg, sizeof(p.user_alpha))) ret = -EFAULT; else { win->alpha.mode = PLANE_BLENDING; win->alpha.channel = p.user_alpha.channel; win->alpha.value = S3CFB_AVALUE(p.user_alpha.red, p.user_alpha.green, p.user_alpha.blue); s3cfb_set_alpha_blending(ctrl, win->id); } break; case S3CFB_WIN_SET_CHROMA: if (copy_from_user(&p.user_chroma, (struct s3cfb_user_chroma __user *) arg, sizeof(p.user_chroma))) ret = -EFAULT; else { win->chroma.enabled = p.user_chroma.enabled; win->chroma.key = S3CFB_CHROMA(p.user_chroma.red, p.user_chroma.green, p.user_chroma.blue); s3cfb_set_chroma_key(ctrl, win->id); } break; case S3CFB_SET_VSYNC_INT: if (get_user(p.vsync, (int __user *) arg)) ret = -EFAULT; else { if (p.vsync) s3cfb_set_global_interrupt(ctrl, 1); s3cfb_set_vsync_interrupt(ctrl, p.vsync); } break; } return ret; }
int s3cfb_direct_ioctl(int id, unsigned int cmd, unsigned long arg) { struct s3cfb_global *fbdev = get_fimd_global(id); struct fb_info *fb = fbdev->fb[id]; struct fb_var_screeninfo *var = &fb->var; struct fb_fix_screeninfo *fix = &fb->fix; struct s3cfb_window *win = fb->par; struct s3cfb_lcd *lcd = fbdev->lcd; struct s3cfb_user_window user_win; void *argp = (void *)arg; int ret = 0; switch (cmd) { case FBIOGET_FSCREENINFO: ret = memcpy(argp, &fb->fix, sizeof(fb->fix)) ? 0 : -EFAULT; break; case FBIOGET_VSCREENINFO: ret = memcpy(argp, &fb->var, sizeof(fb->var)) ? 0 : -EFAULT; break; case FBIOPUT_VSCREENINFO: ret = s3cfb_check_var((struct fb_var_screeninfo *)argp, fb); if (ret) { dev_err(fbdev->dev, "invalid vscreeninfo\n"); break; } ret = memcpy(&fb->var, (struct fb_var_screeninfo *)argp, sizeof(fb->var)) ? 0 : -EFAULT; if (ret) { dev_err(fbdev->dev, "failed to put new vscreeninfo\n"); break; } fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; fix->smem_len = fix->line_length * var->yres_virtual; s3cfb_set_win_params(fbdev, id); break; case S3CFB_WIN_POSITION: ret = memcpy(&user_win, (struct s3cfb_user_window __user *)arg, sizeof(user_win)) ? 0 : -EFAULT; if (ret) { dev_err(fbdev->dev, "failed to S3CFB_WIN_POSITION\n"); break; } if (user_win.x < 0) user_win.x = 0; if (user_win.y < 0) user_win.y = 0; if (user_win.x + var->xres > lcd->width) win->x = lcd->width - var->xres; else win->x = user_win.x; if (user_win.y + var->yres > lcd->height) win->y = lcd->height - var->yres; else win->y = user_win.y; s3cfb_set_window_position(fbdev, win->id); break; case S3CFB_GET_LCD_WIDTH: ret = memcpy(argp, &lcd->width, sizeof(int)) ? 0 : -EFAULT; if (ret) { dev_err(fbdev->dev, "failed to S3CFB_GET_LCD_WIDTH\n"); break; } break; case S3CFB_GET_LCD_HEIGHT: ret = memcpy(argp, &lcd->height, sizeof(int)) ? 0 : -EFAULT; if (ret) { dev_err(fbdev->dev, "failed to S3CFB_GET_LCD_HEIGHT\n"); break; } break; case S3CFB_SET_WRITEBACK: if ((u32)argp == 1) fbdev->output = OUTPUT_WB_RGB; else fbdev->output = OUTPUT_RGB; s3cfb_set_output(fbdev); break; case S3CFB_SET_WIN_ON: s3cfb_enable_window(fbdev, id); break; case S3CFB_SET_WIN_OFF: s3cfb_disable_window(fbdev, id); break; case S3CFB_SET_WIN_PATH: win->path = (enum s3cfb_data_path_t)argp; break; case S3CFB_SET_WIN_ADDR: fix->smem_start = (unsigned long)argp; s3cfb_set_buffer_address(fbdev, id); break; case S3CFB_SET_WIN_MEM: win->owner = (enum s3cfb_mem_owner_t)argp; break; case S3CFB_SET_VSYNC_INT: if (argp) s3cfb_set_global_interrupt(fbdev, 1); s3cfb_set_vsync_interrupt(fbdev, (int)argp); break; case S3CFB_GET_VSYNC_INT_STATUS: ret = s3cfb_get_vsync_interrupt(fbdev); break; default: ret = s3cfb_ioctl(fb, cmd, arg); break; } return ret; }
static int s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata; struct resource *res; int ret = 0; /* initialzing global structure */ ctrl = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); if (!ctrl) { dev_err(ctrl->dev, "failed to allocate for global fb structure\n"); goto err_global; } ctrl->dev = &pdev->dev; s3cfb_set_lcd_info(ctrl); /* gpio */ pdata = to_fb_plat(&pdev->dev); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); /* clock */ ctrl->clock = clk_get(&pdev->dev, pdata->clk_name); if (IS_ERR(ctrl->clock)) { dev_err(ctrl->dev, "failed to get fimd clock source\n"); ret = -EINVAL; goto err_clk; } clk_enable(ctrl->clock); /* io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(ctrl->dev, "failed to get io memory region\n"); ret = -EINVAL; goto err_io; } /* request mem region */ res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { dev_err(ctrl->dev, "failed to request io memory region\n"); ret = -EINVAL; goto err_io; } /* ioremap for register block */ ctrl->regs = ioremap(res->start, res->end - res->start + 1); if (!ctrl->regs) { dev_err(ctrl->dev, "failed to remap io region\n"); ret = -EINVAL; goto err_io; } /* irq */ ctrl->irq = platform_get_irq(pdev, 0); if (request_irq(ctrl->irq, s3cfb_irq_frame, IRQF_DISABLED, pdev->name, ctrl)) { dev_err(ctrl->dev, "request_irq failed\n"); ret = -EINVAL; goto err_irq; } #ifdef CONFIG_FB_S3C_V2_TRACE_UNDERRUN if (request_irq(platform_get_irq(pdev, 1), s3cfb_irq_fifo, IRQF_DISABLED, pdev->name, ctrl)) { dev_err(ctrl->dev, "request_irq failed\n"); ret = -EINVAL; goto err_irq; } s3cfb_set_fifo_interrupt(ctrl, 1); dev_info(ctrl->dev, "fifo underrun trace\n"); #endif /* init global */ s3cfb_init_global(); s3cfb_display_on(ctrl); /* panel control */ if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); if (ctrl->lcd->init_ldi) ctrl->lcd->init_ldi(); /* prepare memory */ if (s3cfb_alloc_framebuffer()) goto err_alloc; if (s3cfb_register_framebuffer()) goto err_alloc; s3cfb_set_clock(ctrl); s3cfb_enable_window(pdata->default_win); ret = device_create_file(&(pdev->dev), &dev_attr_win_power); if (ret < 0) dev_err(ctrl->dev, "failed to add sysfs entries\n"); dev_info(ctrl->dev, "registered successfully\n"); return 0; err_alloc: free_irq(ctrl->irq, ctrl); err_irq: iounmap(ctrl->regs); err_io: clk_disable(ctrl->clock); err_clk: clk_put(ctrl->clock); err_global: return ret; }
int s3cfb_blank(int blank_mode, struct fb_info *fb) { struct s3cfb_window *win = fb->par; struct s3cfb_window *tmp_win; struct s3cfb_global *fbdev = get_fimd_global(fb->node); struct platform_device *pdev = to_platform_device(fbdev->dev); struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev); int enabled_win = 0; int i; dev_dbg(fbdev->dev, "change blank mode\n"); switch (blank_mode) { case FB_BLANK_UNBLANK: if (!fb->fix.smem_start) { dev_info(fbdev->dev, \ "[fb%d] no allocated memory for unblank\n", win->id); break; } if (win->power_state == FB_BLANK_UNBLANK) { dev_info(fbdev->dev, \ "[fb%d] already in FB_BLANK_UNBLANK\n", win->id); break; } else { s3cfb_update_power_state(fbdev, win->id, FB_BLANK_UNBLANK); } enabled_win = atomic_read(&fbdev->enabled_win); if (enabled_win == 0) { pdata->clk_on(pdev, &fbdev->clock); s3cfb_init_global(fbdev); s3cfb_set_clock(fbdev); for (i = 0; i < pdata->nr_wins; i++) { tmp_win = fbdev->fb[i]->par; if (tmp_win->owner == DMA_MEM_FIMD) s3cfb_set_win_params(fbdev, tmp_win->id); } } if (win->enabled) /* from FB_BLANK_NORMAL */ s3cfb_win_map_off(fbdev, win->id); else /* from FB_BLANK_POWERDOWN */ s3cfb_enable_window(fbdev, win->id); if (enabled_win == 0) { s3cfb_display_on(fbdev); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); if (fbdev->lcd->init_ldi) fbdev->lcd->init_ldi(); } break; case FB_BLANK_NORMAL: if (win->power_state == FB_BLANK_NORMAL) { dev_info(fbdev->dev, \ "[fb%d] already in FB_BLANK_NORMAL\n", win->id); break; } else { s3cfb_update_power_state(fbdev, win->id, FB_BLANK_NORMAL); } enabled_win = atomic_read(&fbdev->enabled_win); if (enabled_win == 0) { pdata->clk_on(pdev, &fbdev->clock); s3cfb_init_global(fbdev); s3cfb_set_clock(fbdev); for (i = 0; i < pdata->nr_wins; i++) { tmp_win = fbdev->fb[i]->par; if (tmp_win->owner == DMA_MEM_FIMD) s3cfb_set_win_params(fbdev, tmp_win->id); } } s3cfb_win_map_on(fbdev, win->id, 0x0); if (!win->enabled) /* from FB_BLANK_POWERDOWN */ s3cfb_enable_window(fbdev, win->id); if (enabled_win == 0) { s3cfb_display_on(fbdev); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); if (fbdev->lcd->init_ldi) fbdev->lcd->init_ldi(); } break; case FB_BLANK_POWERDOWN: if (win->power_state == FB_BLANK_POWERDOWN) { dev_info(fbdev->dev, \ "[fb%d] already in FB_BLANK_POWERDOWN\n", win->id); break; } else { s3cfb_update_power_state(fbdev, win->id, FB_BLANK_POWERDOWN); } s3cfb_disable_window(fbdev, win->id); s3cfb_win_map_off(fbdev, win->id); if (atomic_read(&fbdev->enabled_win) == 0) { if (pdata->backlight_off) pdata->backlight_off(pdev); if (fbdev->lcd->deinit_ldi) fbdev->lcd->deinit_ldi(); if (pdata->lcd_off) pdata->lcd_off(pdev); s3cfb_display_off(fbdev); pdata->clk_off(pdev, &fbdev->clock); } break; case FB_BLANK_VSYNC_SUSPEND: /* fall through */ case FB_BLANK_HSYNC_SUSPEND: /* fall through */ default: dev_dbg(fbdev->dev, "unsupported blank mode\n"); return -EINVAL; } return 0; }
static int s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata = NULL; struct resource *res = NULL; struct s3cfb_global *fbdev[2]; int ret = 0; int i = 0; #ifdef CONFIG_EXYNOS_DEV_PD /* to use the runtime PM helper functions */ pm_runtime_enable(&pdev->dev); /* enable the power domain */ pm_runtime_get_sync(&pdev->dev); #endif #ifndef CONFIG_TC4_EVT lcd_regulator = regulator_get(NULL, "vdd33_lcd"); lcd_regulator_ldo13 = regulator_get(NULL, "vddioperi_18"); if (IS_ERR(lcd_regulator_ldo13)) { printk("%s: failed to get %s\n", __func__, "vddioperi_18"); ret = -ENODEV; goto err_regulator_ldo13; } if (IS_ERR(lcd_regulator)) { printk("%s: failed to get %s\n", __func__, "vdd33_lcd"); ret = -ENODEV; goto err_regulator; } regulator_enable(lcd_regulator_ldo13); //jacob regulator_enable(lcd_regulator); //yulu #endif fbfimd = kzalloc(sizeof(struct s3cfb_fimd_desc), GFP_KERNEL); if (FIMD_MAX == 2) fbfimd->dual = 1; else fbfimd->dual = 0; for (i = 0; i < FIMD_MAX; i++) { /* global structure */ fbfimd->fbdev[i] = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); fbdev[i] = fbfimd->fbdev[i]; if (!fbdev[i]) { dev_err(fbdev[i]->dev, "failed to allocate for \ global fb structure fimd[%d]!\n", i); goto err0; } fbdev[i]->dev = &pdev->dev; s3cfb_set_lcd_info(fbdev[i]); /* platform_data*/ pdata = to_fb_plat(&pdev->dev); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->clk_on) pdata->clk_on(pdev, &fbdev[i]->clock); /* io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) { dev_err(fbdev[i]->dev, "failed to get io memory region\n"); ret = -EINVAL; goto err1; } res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { dev_err(fbdev[i]->dev, "failed to request io memory region\n"); ret = -EINVAL; goto err1; } fbdev[i]->regs = ioremap(res->start, res->end - res->start + 1); if (!fbdev[i]->regs) { dev_err(fbdev[i]->dev, "failed to remap io region\n"); ret = -EINVAL; goto err1; } /* irq */ fbdev[i]->irq = platform_get_irq(pdev, 0); if (request_irq(fbdev[i]->irq, s3cfb_irq_frame, IRQF_SHARED, pdev->name, fbdev[i])) { dev_err(fbdev[i]->dev, "request_irq failed\n"); ret = -EINVAL; goto err2; } #ifdef CONFIG_FB_S5P_TRACE_UNDERRUN if (request_irq(platform_get_irq(pdev, 1), s3cfb_irq_fifo, IRQF_DISABLED, pdev->name, fbdev[i])) { dev_err(fbdev[i]->dev, "request_irq failed\n"); ret = -EINVAL; goto err2; } s3cfb_set_fifo_interrupt(fbdev[i], 1); dev_info(fbdev[i]->dev, "fifo underrun trace\n"); #endif /* hw setting */ s3cfb_init_global(fbdev[i]); fbdev[i]->system_state = POWER_ON; /* alloc fb_info */ if (s3cfb_alloc_framebuffer(fbdev[i], i)) { dev_err(fbdev[i]->dev, "alloc error fimd[%d]\n", i); goto err3; } /* register fb_info */ if (s3cfb_register_framebuffer(fbdev[i])) { //Cellon add start, Jacob, 2013/01/09, for framebuffer memory leak issue struct s3c_platform_fb *pdata_tmp = to_fb_plat(fbdev[i]->dev); int j; for (j = 0; j < pdata_tmp->nr_wins; j++) { if (fbdev[i]->fb[j]) framebuffer_release(fbdev[i]->fb[j]); } kfree(fbdev[i]->fb); //Cellon add end, Jacob, 2013/01/09 dev_err(fbdev[i]->dev, "register error fimd[%d]\n", i); goto err3; } /* enable display */ s3cfb_set_clock(fbdev[i]); s3cfb_enable_window(fbdev[0], pdata->default_win); #ifdef CONFIG_FB_S5P_SOFTBUTTON_UI /* Add Menu UI */ s3cfb_enable_window(fbdev[0], 4); #endif s3cfb_update_power_state(fbdev[i], pdata->default_win, FB_BLANK_UNBLANK); s3cfb_display_on(fbdev[i]); #ifdef CONFIG_HAS_WAKELOCK #ifdef CONFIG_HAS_EARLYSUSPEND fbdev[i]->early_suspend.suspend = s3cfb_early_suspend; fbdev[i]->early_suspend.resume = s3cfb_late_resume; fbdev[i]->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; register_early_suspend(&fbdev[i]->early_suspend); #endif #endif }