/*! * @brief Disable LCD controller. * @param info framebuffer information pointer */ static void _disable_lcdc(struct fb_info *info) { struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par; if (mx2fbi->type == MX2FB_TYPE_GW) _disable_graphic_window(info); else { if (fb_enabled) { gpio_lcdc_inactive(); board_power_lcd(0); clk_disable(lcdc_clk); fb_enabled = 0; } #ifdef CONFIG_FB_MXC_TVOUT if (fb_mode) { int enable = 0; if ((strcmp(fb_mode, MODE_VGA) == 0) || (strcmp(fb_mode, MODE_NTSC) == 0) || (strcmp(fb_mode, MODE_PAL) == 0)) fs453_ioctl(ENCODER_ENABLE_OUTPUT, &enable); } #endif } }
/*! * @brief Enable LCD controller. * @param info framebuffer information pointer */ static void _enable_lcdc(struct fb_info *info) { static int first_enable = 1; struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par; /* * Graphic window can only be enabled while the HCLK to the LCDC * is disabled. Once enabled it can subsequently be disabled and * enabled without turning off the HCLK. * The graphic window is enabled and then disabled here. So next * time to enable graphic window the HCLK to LCDC does not need * to be disabled, and the flicker (due to disabling of HCLK to * LCDC) is avoided. */ if (first_enable) { _enable_graphic_window(info); _disable_graphic_window(info); first_enable = 0; } if (mx2fbi->type == MX2FB_TYPE_GW) _enable_graphic_window(info); else if (!fb_enabled) { clk_enable(lcdc_clk); gpio_lcdc_active(); board_power_lcd(1); _set_brightness(brightness); fb_enabled++; #ifdef CONFIG_FB_MXC_TVOUT if (fb_mode) { unsigned long mode = 0; if (strcmp(fb_mode, MODE_VGA) == 0) mode = VIDEO_ENCODER_VGA; else if (strcmp(fb_mode, MODE_NTSC) == 0) mode = VIDEO_ENCODER_NTSC; else if (strcmp(fb_mode, MODE_PAL) == 0) mode = VIDEO_ENCODER_PAL; if (mode) fs453_ioctl(ENCODER_SET_NORM, &mode); } #endif } }
/*! * @brief Ioctl function to support customized ioctl operations. * * @param info Framebuffer structure that represents a single frame buffer * @param cmd The command number * @param arg Argument which depends on cmd * * @return Negative errno on error, or zero on success. */ static int mx2fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par; struct mx2fb_gbl_alpha ga; struct mx2fb_color_key ck; switch (cmd) { case MX2FB_SET_GBL_ALPHA: if (mx2fbi->type != MX2FB_TYPE_GW) return -ENODEV; if (!arg) return -EINVAL; /* set graphic window information */ if (copy_from_user((void *)&ga, (void *)arg, sizeof(ga))) return -EFAULT; g_gwinfo.alpha_value = ga.alpha; if (g_gwinfo.enabled) _enable_graphic_window(info); else _disable_graphic_window(info); break; case MX2FB_SET_CLR_KEY: if (mx2fbi->type != MX2FB_TYPE_GW) return -ENODEV; if (!arg) return -EINVAL; /* set graphic window information */ if (copy_from_user((void *)&ck, (void *)arg, sizeof(ck))) return -EFAULT; g_gwinfo.ck_enabled = ck.enable; g_gwinfo.ck_red = (ck.color_key & 0x003F0000) >> 16; g_gwinfo.ck_green = (ck.color_key & 0x00003F00) >> 8; g_gwinfo.ck_blue = ck.color_key & 0x0000003F; if (g_gwinfo.enabled) _enable_graphic_window(info); else _disable_graphic_window(info); break; case FBIOGET_GWINFO: if (mx2fbi->type != MX2FB_TYPE_GW) return -ENODEV; if (!arg) return -EINVAL; /* get graphic window information */ if (copy_to_user((void *)arg, (void *)&g_gwinfo, sizeof(g_gwinfo))) return -EFAULT; break; case FBIOPUT_GWINFO: if (mx2fbi->type != MX2FB_TYPE_GW) return -ENODEV; if (!arg) return -EINVAL; /* set graphic window information */ if (copy_from_user((void *)&g_gwinfo, (void *)arg, sizeof(g_gwinfo))) return -EFAULT; if (g_gwinfo.enabled) _enable_graphic_window(info); else _disable_graphic_window(info); break; #ifdef CONFIG_FB_MXC_TVOUT case ENCODER_GET_CAPABILITIES:{ int ret; struct video_encoder_capability cap; if (mx2fbi->type != MX2FB_TYPE_BG) return -ENODEV; ret = fs453_ioctl(cmd, &cap); if (ret) return ret; if (copy_to_user((void *)arg, &cap, sizeof(cap))) return -EFAULT; break; } case ENCODER_SET_NORM:{ int ret; unsigned long mode; char *smode; struct fb_var_screeninfo var; if (mx2fbi->type != MX2FB_TYPE_BG) return -ENODEV; if (copy_from_user(&mode, (void *)arg, sizeof(mode))) return -EFAULT; if ((ret = fs453_ioctl(cmd, &mode))) return ret; if (mode == VIDEO_ENCODER_PAL) smode = MODE_PAL; else if (mode == VIDEO_ENCODER_NTSC) smode = MODE_NTSC; else smode = MODE_VGA; var = info->var; var.nonstd = 0; ret = fb_find_mode(&var, info, smode, mxcfb_modedb, mxcfb_modedb_sz, NULL, default_bpp); if ((ret != 1) && (ret != 2)) /* specified mode not found */ return -ENODEV; info->var = var; fb_mode = smode; return mx2fb_set_par(info); } case ENCODER_SET_INPUT: case ENCODER_SET_OUTPUT: case ENCODER_ENABLE_OUTPUT:{ unsigned long varg; if (mx2fbi->type != MX2FB_TYPE_BG) return -ENODEV; if (copy_from_user(&varg, (void *)arg, sizeof(varg))) return -EFAULT; return fs453_ioctl(cmd, &varg); } #endif default: dev_dbg(info->device, "Unknown ioctl command (0x%08X)\n", cmd); return -EINVAL; } return 0; }