/* 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; }
/* 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; }
/* 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); }
/* for backward compatibilities */ void s3cfb_enable_dma(int id) { struct s3cfb_window *win = ctrl->fb[id]->par; win->path = DATA_PATH_DMA; s3cfb_set_vsync_interrupt(ctrl, 1); s3cfb_wait_for_vsync(); s3cfb_set_vsync_interrupt(ctrl, 0); s3cfb_disable_window(id); s3cfb_display_off(ctrl); s3cfb_set_window_control(ctrl, id); s3cfb_display_on(ctrl); }
void s3cfb_late_resume(struct early_suspend *h) { struct s3cfb_global *fbdev = container_of(h, struct s3cfb_global, early_suspend); struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev); struct platform_device *pdev = to_platform_device(fbdev->dev); struct fb_info *fb; struct s3cfb_window *win; int i, j, ret; pr_info("s3cfb_late_resume is called\n"); ret = regulator_enable(fbdev->regulator); if (ret < 0) dev_err(fbdev->dev, "failed to enable regulator\n"); ret = regulator_enable(fbdev->vcc_lcd); if (ret < 0) dev_err(fbdev->dev, "failed to enable vcc_lcd\n"); ret = regulator_enable(fbdev->vlcd); if (ret < 0) dev_err(fbdev->dev, "failed to enable vlcd\n"); #if defined(CONFIG_FB_S3C_TL2796) lcd_cfg_gpio_late_resume(); #endif dev_dbg(fbdev->dev, "wake up from suspend\n"); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); clk_enable(fbdev->clock); s3cfb_init_global(fbdev); s3cfb_set_clock(fbdev); s3cfb_display_on(fbdev); for (i = pdata->default_win; i < pdata->nr_wins + pdata->default_win; i++) { j = i % pdata->nr_wins; fb = fbdev->fb[j]; win = fb->par; if ((win->path == DATA_PATH_DMA) && (win->enabled)) { s3cfb_set_par(fb); s3cfb_set_window(fbdev, win->id, 1); } } s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->reset_lcd) pdata->reset_lcd(pdev); pr_info("s3cfb_late_resume is complete\n"); return ; }
int s3c_ielcd_init_global(struct s3cfb_global *ctrl) { unsigned int cfg; *ielcd_fbdev = *ctrl; ielcd_fbdev->regs = s3c_ielcd_base; #ifdef CONFIG_FB_S3C_MIPI_LCD s3cfb_set_polarity_only(ielcd_fbdev); #else s3cfb_set_polarity(ielcd_fbdev); #endif s3cfb_set_timing(ielcd_fbdev); s3cfb_set_lcd_size(ielcd_fbdev); /* dithmode */ s3c_ielcd_writel(0x0, S3C_IELCD_DITHMODE); /* clk mode and mode * read from lcd vid con */ cfg = readl(ctrl->regs + S3C_VIDCON0); cfg &= ~((7 << 26) | (1 << 5) | (1 << 0)); #ifdef CONFIG_FB_S3C_MIPI_LCD cfg |= (0 << 26 | 0 << 5); #else cfg |= (0 << 26 | 1 << 5); #endif s3c_ielcd_writel(cfg, S3C_IELCD_VIDCON0); s3c_ielcd_writel(1<<5, S3C_IELCD_VIDINTCON0); s3cfb_set_vsync_interrupt(ielcd_fbdev, 0); s3cfb_set_global_interrupt(ielcd_fbdev, 0); /*s3cfb_display_on(ielcd_fbdev);*/ s3c_ielcd_writel(0, S3C_IELCD_VIDOSD0A); s3c_ielcd_writel((ctrl->lcd->width - 1) << 11 | (ctrl->lcd->height - 1), S3C_IELCD_VIDOSD0B); s3c_ielcd_writel((ctrl->lcd->width * ctrl->lcd->height), S3C_IELCD_VIDOSD0C); cfg = S3C_WINCON_DATAPATH_LOCAL | S3C_WINCON_BPPMODE_32BPP; cfg |= S3C_WINCON_INRGB_RGB; s3c_ielcd_writel(cfg, S3C_IELCD_WINCON0); s3cfb_window_on(ielcd_fbdev, 0); return 0; }
int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) { struct fb_var_screeninfo *var = &fb->var; struct s3cfb_window *win = fb->par; struct s3cfb_global *fbdev = get_fimd_global(fb->node); struct s3cfb_lcd *lcd = fbdev->lcd; int ret = 0; 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(fbdev); 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(fbdev, 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(fbdev, 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(fbdev, 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(fbdev, 1); s3cfb_set_vsync_interrupt(fbdev, p.vsync); } break; #if MALI_USE_UNIFIED_MEMORY_PROVIDER case S3CFB_GET_FB_UMP_SECURE_ID_0: { u32 __user *psecureid = (u32 __user *) arg; ump_secure_id secure_id; dev_info(fbdev->dev, "ump_dd_secure_id_get\n"); secure_id = ump_dd_secure_id_get(ump_wrapped_buffer); dev_info(fbdev->dev, "Saving secure id 0x%x in userptr %p\n" , (unsigned int)secure_id, psecureid); dev_dbg(fbdev->dev, "Saving secure id 0x%x in userptr %p\n" , (unsigned int)secure_id, psecureid); return put_user((unsigned int)secure_id, psecureid); } break; #endif } 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 __devinit s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata; struct s3cfb_global *fbdev; struct resource *res; int i, j, ret = 0; fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); if (!fbdev) { dev_err(fbdev->dev, "failed to allocate for " "global fb structure\n"); ret = -ENOMEM; goto err_global; } fbdev->dev = &pdev->dev; fbdev->regulator = regulator_get(&pdev->dev, "pd"); if (!fbdev->regulator) { dev_err(fbdev->dev, "failed to get regulator\n"); ret = -EINVAL; goto err_regulator; } ret = regulator_enable(fbdev->regulator); if (ret < 0) { dev_err(fbdev->dev, "failed to enable regulator\n"); ret = -EINVAL; goto err_regulator; } fbdev->vcc_lcd = regulator_get(&pdev->dev, "vcc_lcd"); if (!fbdev->vcc_lcd) { dev_err(fbdev->dev, "failed to get vcc_lcd\n"); ret = -EINVAL; goto err_vcc_lcd; } ret = regulator_enable(fbdev->vcc_lcd); if (ret < 0) { dev_err(fbdev->dev, "failed to enable vcc_lcd\n"); ret = -EINVAL; goto err_vcc_lcd; } fbdev->vlcd = regulator_get(&pdev->dev, "vlcd"); if (!fbdev->vlcd) { dev_err(fbdev->dev, "failed to get vlcd\n"); ret = -EINVAL; goto err_vlcd; } ret = regulator_enable(fbdev->vlcd); if (ret < 0) { dev_err(fbdev->dev, "failed to enable vlcd\n"); ret = -EINVAL; goto err_vlcd; } pdata = to_fb_plat(&pdev->dev); if (!pdata) { dev_err(fbdev->dev, "failed to get platform data\n"); ret = -EINVAL; goto err_pdata; } fbdev->lcd = (struct s3cfb_lcd *)pdata->lcd; if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->clk_on) pdata->clk_on(pdev, &fbdev->clock); 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; } 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; } 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_mem; } s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); #ifdef CONFIG_FB_S3C_MDNIE s3c_mdnie_setup(); #endif s3cfb_init_global(fbdev); if (s3cfb_alloc_framebuffer(fbdev)) { ret = -ENOMEM; goto err_alloc; } if (s3cfb_register_framebuffer(fbdev)) { ret = -EINVAL; goto err_register; } s3cfb_set_clock(fbdev); #ifdef CONFIG_FB_S3C_MDNIE mDNIe_Mode_Set(); #endif s3cfb_set_window(fbdev, pdata->default_win, 1); s3cfb_set_alpha_value_width(fbdev, pdata->default_win); s3cfb_display_on(fbdev); 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; } #ifdef CONFIG_FB_S3C_LCD_INIT #if defined(CONFIG_FB_S3C_TL2796) if (pdata->backlight_on) pdata->backlight_on(pdev); #endif #ifndef CONFIG_MACH_ARIES if (!bootloaderfb && pdata->reset_lcd) pdata->reset_lcd(pdev); #endif #endif #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; register_early_suspend(&fbdev->early_suspend); #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_irq: s3cfb_display_off(fbdev); s3cfb_set_window(fbdev, pdata->default_win, 0); for (i = pdata->default_win; i < pdata->nr_wins + pdata->default_win; i++) { j = i % pdata->nr_wins; unregister_framebuffer(fbdev->fb[j]); } err_register: for (i = 0; i < pdata->nr_wins; i++) { if (i == pdata->default_win) s3cfb_unmap_default_video_memory(fbdev->fb[i]); framebuffer_release(fbdev->fb[i]); } kfree(fbdev->fb); err_alloc: iounmap(fbdev->regs); err_mem: release_mem_region(res->start, res->end - res->start + 1); err_io: pdata->clk_off(pdev, &fbdev->clock); err_pdata: regulator_disable(fbdev->vlcd); err_vlcd: regulator_disable(fbdev->vcc_lcd); err_vcc_lcd: regulator_disable(fbdev->regulator); err_regulator: kfree(fbdev); err_global: return ret; }
static int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) { struct s3cfb_global *fbdev = platform_get_drvdata(to_platform_device(fb->device)); struct fb_var_screeninfo *var = &fb->var; struct s3cfb_window *win = fb->par; struct s3cfb_lcd *lcd = fbdev->lcd; struct fb_fix_screeninfo *fix = &fb->fix; struct s3cfb_next_info next_fb_info; int ret = 0; 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(fbdev); break; // Custom IOCTL added to return the VSYNC timestamp case S3CFB_WAIT_FOR_VSYNC: ret = s3cfb_wait_for_vsync(fbdev); if(ret > 0) { u64 nsecs = ktime_to_ns(fbdev->vsync_timestamp); copy_to_user((void*)arg, &nsecs, sizeof(u64)); } 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(fbdev, 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(fbdev, 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(fbdev, 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(fbdev, 1); s3cfb_set_vsync_interrupt(fbdev, p.vsync); } break; case S3CFB_GET_CURR_FB_INFO: next_fb_info.phy_start_addr = fix->smem_start; next_fb_info.xres = var->xres; next_fb_info.yres = var->yres; next_fb_info.xres_virtual = var->xres_virtual; next_fb_info.yres_virtual = var->yres_virtual; next_fb_info.xoffset = var->xoffset; next_fb_info.yoffset = var->yoffset; next_fb_info.lcd_offset_x = 0; next_fb_info.lcd_offset_y = 0; if (copy_to_user((void *)arg, (struct s3cfb_next_info *) &next_fb_info, sizeof(struct s3cfb_next_info))) return -EFAULT; break; } return ret; }
static int __devinit s3cfb_probe(struct platform_device *pdev) { struct s3c_platform_fb *pdata; struct s3cfb_global *fbdev; struct resource *res; int i, j, ret = 0; printk("%s\n",__func__); fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); if (!fbdev) { dev_err(&pdev->dev, "failed to allocate for " "global fb structure\n"); ret = -ENOMEM; goto err_global; } fbdev->dev = &pdev->dev; #ifdef CONFIG_FB_S3C_LTE480WV s3cfb_set_lcd_info(fbdev); #endif fbdev->regulator = regulator_get(&pdev->dev, "pd"); if (!fbdev->regulator) { dev_err(fbdev->dev, "failed to get regulator\n"); ret = -EINVAL; goto err_regulator; } ret = regulator_enable(fbdev->regulator); if (ret < 0) { dev_err(fbdev->dev, "failed to enable regulator\n"); ret = -EINVAL; goto err_regulator; } pdata = to_fb_plat(&pdev->dev); if (!pdata) { dev_err(fbdev->dev, "failed to get platform data\n"); ret = -EINVAL; goto err_pdata; } //fbdev->lcd = (struct s3cfb_lcd *)pdata->lcd; if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); if (pdata->clk_on) pdata->clk_on(pdev, &fbdev->clock); 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; } 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; } 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_mem; } /*set gamma LUT*/ //SSCR xuhui 110130 s3cfb_set_gamma(fbdev); s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); s3cfb_init_global(fbdev); if (s3cfb_alloc_framebuffer(fbdev)) { ret = -ENOMEM; goto err_alloc; } if (s3cfb_register_framebuffer(fbdev)) { ret = -EINVAL; goto err_register; } s3cfb_set_clock(fbdev); s3cfb_set_window(fbdev, pdata->default_win, 1); s3cfb_display_on(fbdev); 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; } #ifdef CONFIG_FB_S3C_LCD_INIT if (pdata->backlight_on) pdata->backlight_on(pdev); if (!bootloaderfb && pdata->reset_lcd) pdata->reset_lcd(pdev); if (pdata->lcd_on) pdata->lcd_on(pdev); #endif #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; register_early_suspend(&fbdev->early_suspend); #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"); #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) if (fb_prepare_logo( fbdev->fb[pdata->default_win], FB_ROTATE_UR)) { printk("Start display and show logo\n"); /* Start display and show logo on boot */ fb_set_cmap(&fbdev->fb[pdata->default_win]->cmap, fbdev->fb[pdata->default_win]); fb_show_logo(fbdev->fb[pdata->default_win], FB_ROTATE_UR); } #endif return 0; err_irq: s3cfb_display_off(fbdev); s3cfb_set_window(fbdev, pdata->default_win, 0); for (i = pdata->default_win; i < pdata->nr_wins + pdata->default_win; i++) { j = i % pdata->nr_wins; unregister_framebuffer(fbdev->fb[j]); } err_register: for (i = 0; i < pdata->nr_wins; i++) { if (i == pdata->default_win) s3cfb_unmap_default_video_memory(fbdev->fb[i]); framebuffer_release(fbdev->fb[i]); } kfree(fbdev->fb); err_alloc: iounmap(fbdev->regs); err_mem: release_mem_region(res->start, res->end - res->start + 1); err_io: pdata->clk_off(pdev, &fbdev->clock); err_pdata: regulator_disable(fbdev->regulator); err_regulator: kfree(fbdev); err_global: return ret; }
static int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) { struct s3cfb_global *fbdev = platform_get_drvdata(to_platform_device(fb->device)); struct fb_var_screeninfo *var = &fb->var; struct s3cfb_window *win = fb->par; struct s3cfb_lcd *lcd = fbdev->lcd; struct fb_fix_screeninfo *fix = &fb->fix; struct s3cfb_next_info next_fb_info; volatile unsigned int * LCDControllerBase = NULL; int framebuffer_addr = 0; int ret = 0; 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(fbdev); 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(fbdev, 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(fbdev, 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(fbdev, 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(fbdev, 1); s3cfb_set_vsync_interrupt(fbdev, p.vsync); } break; case S3CFB_GET_CURR_FB_INFO: next_fb_info.phy_start_addr = fix->smem_start; next_fb_info.xres = var->xres; next_fb_info.yres = var->yres; next_fb_info.xres_virtual = var->xres_virtual; next_fb_info.yres_virtual = var->yres_virtual; next_fb_info.xoffset = var->xoffset; next_fb_info.yoffset = var->yoffset; next_fb_info.lcd_offset_x = 0; next_fb_info.lcd_offset_y = 0; if (copy_to_user((void *)arg, (struct s3cfb_next_info *) &next_fb_info, sizeof(struct s3cfb_next_info))) return -EFAULT; break; /* get changing physical framebuffer address(because of double buffering) */ case S3CFB_GET_LCD_ADDR: LCDControllerBase = (volatile unsigned int *)ioremap(0xf8000000,1024); framebuffer_addr = LCDControllerBase[0xa0/4 + (win->id)*2]; iounmap(LCDControllerBase); dev_dbg(fbdev->dev, "framebuffer_addr: 0x%08x\n", framebuffer_addr); if (copy_to_user((void *)arg, &framebuffer_addr, sizeof(int))) return -EFAULT; break; } return ret; }
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_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; }
void s3cfb_late_resume(struct early_suspend *h) { struct s3cfb_global *fbdev = container_of(h, struct s3cfb_global, early_suspend); struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev); struct platform_device *pdev = to_platform_device(fbdev->dev); struct fb_info *fb; struct s3cfb_window *win; int i, j, ret; pr_info("s3cfb_late_resume is called\n"); ret = regulator_enable(fbdev->regulator); if (ret < 0) dev_err(fbdev->dev, "failed to enable regulator\n"); #ifdef CONFIG_MACH_ARIES ret = regulator_enable(fbdev->vcc_lcd); if (ret < 0) dev_err(fbdev->dev, "failed to enable vcc_lcd\n"); ret = regulator_enable(fbdev->vlcd); if (ret < 0) dev_err(fbdev->dev, "failed to enable vlcd\n"); #endif #if defined(CONFIG_FB_S3C_TL2796) lcd_cfg_gpio_late_resume(); #endif dev_dbg(fbdev->dev, "wake up from suspend\n"); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); clk_enable(fbdev->clock); #ifdef CONFIG_FB_S3C_MDNIE writel(0x1, S5P_MDNIE_SEL); writel(3,fbdev->regs + 0x27c); #endif s3cfb_init_global(fbdev); s3cfb_set_clock(fbdev); #ifdef CONFIG_FB_S3C_MDNIE s3c_mdnie_init_global(fbdev); s3c_mdnie_start(fbdev); #endif #ifdef CONFIG_FB_S3C_CMC623 tune_cmc623_pre_resume(); #endif s3cfb_set_alpha_value_width(fbdev, pdata->default_win); s3cfb_display_on(fbdev); #ifdef CONFIG_FB_S3C_CMC623 tune_cmc623_resume(); #endif #if defined (CONFIG_FB_S3C_LVDS) lms700_powerup(); #endif for (i = pdata->default_win; i < pdata->nr_wins + pdata->default_win; i++) { j = i % pdata->nr_wins; fb = fbdev->fb[j]; win = fb->par; if ((win->path == DATA_PATH_DMA) && (win->enabled)) { s3cfb_set_par(fb); s3cfb_set_window(fbdev, win->id, 1); } } s3cfb_set_vsync_interrupt(fbdev, 1); s3cfb_set_global_interrupt(fbdev, 1); if (pdata->backlight_on) pdata->backlight_on(pdev); if (pdata->reset_lcd) pdata->reset_lcd(pdev); pr_info("s3cfb_late_resume is complete\n"); return ; }