?? s3c2410fb.c
字號(hào):
#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/interrupt.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/delay.h>#include <linux/pm.h>#include <linux/init.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mach-types.h>#include <asm/uaccess.h>#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include "s3c2410fb.h"void (*s3c2410fb_blank_helper)(int blank);EXPORT_SYMBOL(s3c2410fb_blank_helper);/* * CONFIG_FB_S3C2410_EMUL * * 浼欏繁 鐐キ鐨嬪鉤鑳?? : 96*320 淇婇紦楗崬璁? * * var.xres = 96 鏍忚偤 紿嶇粖, * fix.line_length = 240*2 鑲?鑼勪績(jī). * app 鍟?linux FB spec. 闃?闇栬崘鑼勪績(jī)鎼?宸╁姏鍟?緇濋槕 宸存崬淇? * * var.xres_virtual 闃?鐐兼播紿嶇話 瑙勮繃妗?縐樋縐?鏉?鑽?涔愮槫鐖? spec. 鑻炵話 鍠婃。鑲? * app. 鍟?鍐蟲(chóng)病 搴﹀害縐﹀叿 涓?鎸ョ埗 閰掕仾鎵? panning/wrapping 鑻?閮ㄨ??鍫Θ鍟? * 涔愭爮楠ㄨ偤 紜呭姏鑼勪績(jī). *///#define CONFIG_S3C2410_SMDK_800480_WHL//#define CONFIG_S3C2410_SMDK_640480//#define CONFIG_S3C2410_SMDK_320240//#define CONFIG_S3C2410_SMDK_STN_640480#define CONFIG_S3C2410_SMDK_240320//#define CONFIG_S3C2410_SMDK_800600#ifdef CONFIG_S3C2410_SMDK_STN_640480static struct s3c2410fb_rgb rgb_8 = { red: {offset: 5, length: 3, }, green: {offset: 2, length: 3, }, blue: {offset: 0, length: 2, }, transp: {offset: 0, length: 0, },};#elsestatic struct s3c2410fb_rgb rgb_8 = { red: {offset: 0, length: 4, }, green: {offset: 0, length: 4, }, blue: {offset: 0, length: 4, }, transp: {offset: 0, length: 0, },};#endifstatic struct s3c2410fb_rgb def_rgb_16 = { red: {offset: 11, length: 5, }, green: {offset: 5, length: 6, }, blue: {offset: 0, length: 5, }, transp: {offset: 0, length: 0, },};#if 0static struct s3c2410fb_rgb xxx_tft_rgb_16 = { red: {offset: 11, length: 5, }, green: {offset: 6, length: 5, }, blue: {offset: 1, length: 5, }, transp: {offset: 0, length: 1, },};#elsestatic struct s3c2410fb_rgb xxx_tft_rgb_16 = { red: {offset: 11, length: 5, }, green: {offset: 5, length: 6, }, blue: {offset: 0, length: 5, }, transp: {offset: 0, length: 0, },};#endif#if 0#ifdef CONFIG_S3C2410_SMDKstatic struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 174757, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 240,#endif yres: 320, hsync_len : 5, vsync_len : 1, left_margin : 7, upper_margin : 1, right_margin: 3, lower_margin : 3, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) , lcdcon2 : LCD2_VBPD(1) | LCD2_VFPD(2) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(6) | LCD3_HFPD(2), lcdcon4 : LCD4_HSPW(4) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },};#endif#else#ifdef CONFIG_S3C2410_SMDK_640480static struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 640,#endif yres: 480, hsync_len : 96, vsync_len : 2, left_margin : 40, upper_margin : 24, right_margin: 32, lower_margin : 11, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) , lcdcon2 : LCD2_VBPD(32) | LCD2_VFPD(9) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(47) | LCD3_HFPD(15), lcdcon4 : LCD4_HSPW(95) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },};#endif#ifdef CONFIG_S3C2410_SMDK_800600static struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 800,#endif yres: 600, hsync_len : 96, vsync_len : 2, left_margin : 40, upper_margin : 24, right_margin: 32, lower_margin : 11, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) , lcdcon2 : LCD2_VBPD(3) | LCD2_VFPD(2) | LCD2_VSPW(2), lcdcon3 : LCD3_HBPD(28) | LCD3_HFPD(50), lcdcon4 : LCD4_HSPW(15) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },};#endif#ifdef CONFIG_S3C2410_SMDK_800480_WHLstatic struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 800,#endif yres: 480, hsync_len : 96, vsync_len : 2, left_margin : 40, upper_margin : 24, right_margin: 32, lower_margin : 11, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) , lcdcon2 : LCD2_VBPD(39) | LCD2_VFPD(19) | LCD2_VSPW(3), lcdcon3 : LCD3_HBPD(49) | LCD3_HFPD(19), lcdcon4 : LCD4_HSPW(99) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },};#endif#ifdef CONFIG_S3C2410_SMDK_320240static struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 320,#endif yres: 240, hsync_len : 5, vsync_len : 1, left_margin : 7, upper_margin : 1, right_margin: 3, lower_margin : 3, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(5) , lcdcon2 : LCD2_VBPD(1) | LCD2_VFPD(2) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(49) | LCD3_HFPD(15), lcdcon4 : LCD4_HSPW(13) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },};#endif#ifdef CONFIG_S3C2410_SMDK_240320static struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 16,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 240,#endif yres: 320, /*hsync_len : 5, vsync_len : 1, left_margin : 7, upper_margin : 1, right_margin: 3, lower_margin : 3, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(6) , lcdcon2 : LCD2_VBPD(1) | LCD2_VFPD(2) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(6) | LCD3_HFPD(2), lcdcon4 : LCD4_HSPW(3) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },*/ hsync_len : 5, vsync_len : 1, left_margin : 7, upper_margin : 1, right_margin: 3, lower_margin : 3, sync: 0, cmap_static: 1, reg : { /*lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(2) , lcdcon2 : LCD2_VBPD(7) | LCD2_VFPD(16) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(16) | LCD3_HFPD(8), lcdcon4 : LCD4_HSPW(65) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN,*/ lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(6) , lcdcon2 : LCD2_VBPD(7) | LCD2_VFPD(2) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(49) | LCD3_HFPD(15), lcdcon4 : LCD4_HSPW(13) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, }, /*hsync_len : 96, vsync_len : 2, left_margin : 40, upper_margin : 24, right_margin: 32, lower_margin : 11, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1) , lcdcon2 : LCD2_VBPD(32) | LCD2_VFPD(9) | LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(47) | LCD3_HFPD(15), lcdcon4 : LCD4_HSPW(95) | LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 | LCD5_INVVLINE | LCD5_INVVFRAME | LCD5_HWSWP | LCD5_PWREN, },*/};#endif#ifdef CONFIG_S3C2410_SMDK_STN_640480static struct s3c2410fb_mach_info xxx_stn_info __initdata = { pixclock: 39721, bpp: 8,#ifdef CONFIG_FB_S3C2410_EMUL xres: 96,#else xres: 640,#endif yres: 480, hsync_len : 5, vsync_len : 1, left_margin : 7, upper_margin : 1, right_margin: 3, lower_margin : 3, sync: 0, cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_8S | LCD1_PNR_8S | LCD1_CLKVAL(8) , lcdcon2 : LCD2_LINEVAL(479), lcdcon3 : LCD3_WDLY_128 | LCD3_HOZVAL(640*3/8 -1) | 32, lcdcon4 : LCD4_MVAL(13) | LCD4_WLH(3), lcdcon5 : LCD5_BSWP, },};#endif#endifstatic inline u_intchan_to_field(u_int chan, struct fb_bitfield *bf){ chan &= 0xffff; //chan >>= 16 - bf->length; //return chan << bf->offset; chan >>= 16 - bf->offset; return chan << bf->length;}/* * Convert bits-per-pixel to a hardware palette PBS value. */static inline u_intpalette_pbs(struct fb_var_screeninfo *var){ int ret = 0; switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: ret = 0 << 12; break;#endif#ifdef FBCON_HAS_CFB8 case 8: ret = 1 << 12; break;#endif#ifdef FBCON_HAS_CFB16 case 16: ret = 2 << 12; break;#endif } return ret;}#ifdef CONFIG_S3C2410_SMDK_STN_640480static struct s3c2410fb_mach_info * __inits3c2410fb_get_machine_info(struct s3c2410fb_info *fbi){ struct s3c2410fb_mach_info *inf = NULL; inf = &xxx_stn_info; fbi->reg = inf->reg; fbi->rgb[RGB_8] = &rgb_8; return inf;}#elsestatic struct s3c2410fb_mach_info * __inits3c2410fb_get_machine_info(struct s3c2410fb_info *fbi){ struct s3c2410fb_mach_info *inf = NULL; inf = &xxx_stn_info; fbi->reg = inf->reg; fbi->rgb[RGB_16] = &xxx_tft_rgb_16; return inf;}#endifstatic inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con){ struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info; return (con == fbi->currcon || con == -1) ? &fbi->fb.var : &fb_display[con].var;}static inline struct fb_cmap *get_con_cmap(struct fb_info *info, int con){ struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info; return (con == fbi->currcon || con == -1) ? &fbi->fb.cmap : &fb_display[con].cmap;}static inline struct display *get_con_display(struct fb_info *info, int con){ struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info; return (con < 0) ? (fbi->fb.disp) : &(fb_display[con]);}static ints3c2410fb_validate_var(struct fb_var_screeninfo *var, struct s3c2410fb_info *fbi){ int ret = -EINVAL; if (var->xres < MIN_XRES) var->xres = MIN_XRES; if (var->yres < MIN_YRES) var->yres = MIN_YRES; if (var->xres > fbi->max_xres) var->xres = fbi->max_xres; if (var->yres > fbi->max_yres) var->yres = fbi->max_yres; var->xres_virtual = var->xres_virtual < var->xres ? var->xres : var->xres_virtual; var->yres_virtual = var->yres_virtual < var->yres ? var->yres : var->yres_virtual; switch(var->bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: ret = 0; break;#endif#ifdef FBCON_HAS_CFB8 case 8: ret = 0; break;#endif#ifdef FBCON_HAS_CFB16 case 16: ret = 0; break;#endif default: break; } return ret;}static ints3c2410fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info; u_int val, ret = 1; if (regno < fbi->palette_size) {#ifndef CONFIG_S3C2400_GAMEPARK val = ((red >> 4) & 0xf00); val |= ((green >> 8) & 0x0f0); val |= ((blue >> 12) & 0x00f);#else val = ((blue >> 16) & 0x001f); val |= ((green >> 11) & 0x07e0); val |= ((red >> 5) & 0x0f800); val |= 1; /* intensity bit */#endif if (regno == 0) val |= palette_pbs(&fbi->fb.var); fbi->palette_cpu[regno] = val; ret = 0; } return ret;}static ints3c2410fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info; struct display *disp = get_con_display(info, fbi->currcon); u_int var; int ret = 1; if (disp->inverse) { red = 0xffff - red; green = 0xffff - green; blue = 0xffff - blue; } if (fbi->fb.var.grayscale) red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; switch (fbi->fb.disp->visual) { case FB_VISUAL_TRUECOLOR: if (regno < 16) { u16 *pal = fbi->fb.pseudo_palette; var = chan_to_field(red, &fbi->fb.var.red); var |= chan_to_field(green, &fbi->fb.var.green); var |= chan_to_field(blue, &fbi->fb.var.blue); pal[regno] = var; ret = 0; } break; case FB_VISUAL_STATIC_PSEUDOCOLOR: case FB_VISUAL_PSEUDOCOLOR: ret = s3c2410fb_setpalettereg(regno, red, green, blue, trans, info); break; } return ret;}static int s3c2410fb_activate_var(struct fb_var_screeninfo *var, struct s3c2410fb_info *fbi){ struct s3c2410fb_lcd_reg new_regs; u_int half_screen_size, yres; u_long flags; /*new_reg 鍟?緇㈠綍緇?鍘嗗綍緇?*/ unsigned long VideoPhysicalTemp = fbi->screen_dma; save_flags_cli(flags); new_regs.lcdcon1 = fbi->reg.lcdcon1 & ~LCD1_ENVID; new_regs.lcdcon2 = (fbi->reg.lcdcon2 & ~LCD2_LINEVAL_MSK) | LCD2_LINEVAL(var->yres - 1); #ifdef CONFIG_S3C2410_SMDK_STN_640480 new_regs.lcdcon3 = fbi->reg.lcdcon3; #else /* TFT LCD only ! */ new_regs.lcdcon3 = (fbi->reg.lcdcon3 & ~LCD3_HOZVAL_MSK) | LCD3_HOZVAL(var->xres - 1); #endif new_regs.lcdcon4 = fbi->reg.lcdcon4; new_regs.lcdcon5 = fbi->reg.lcdcon5; #ifdef CONFIG_S3C2410_SMDK_STN_640480 new_regs.lcdsaddr1 = LCDADDR_BANK(((unsigned long)VideoPhysicalTemp >> 22)) | LCDADDR_BASEU(((unsigned long)VideoPhysicalTemp >> 1)); /* 16bpp */ new_regs.lcdsaddr2 = LCDADDR_BASEL( ((unsigned long)VideoPhysicalTemp + (var->xres * (var->yres/*-1*/))) >> 1); new_regs.lcdsaddr3 = LCDADDR_OFFSET(0) | (LCDADDR_PAGE(var->xres) >> 1); #else new_regs.lcdsaddr1 = LCDADDR_BANK(((unsigned long)VideoPhysicalTemp >> 22)) | LCDADDR_BASEU(((unsigned long)VideoPhysicalTemp >> 1)); /* 16bpp */ new_regs.lcdsaddr2 = LCDADDR_BASEL( ((unsigned long)VideoPhysicalTemp + (var->xres * 2 * (var->yres/*-1*/))) >> 1); new_regs.lcdsaddr3 = LCDADDR_OFFSET(0) | (LCDADDR_PAGE(var->xres) /*>> 1*/); #endif yres = var->yres; /* if ( dual 鎹炴悂) */ //yres /= 2; half_screen_size = var->bits_per_pixel; //half_screen_size = half_screen_size * var->xres * var->yres / 16; half_screen_size = half_screen_size * var->xres * var->yres / 8; fbi->reg.lcdcon1 = new_regs.lcdcon1; fbi->reg.lcdcon2 = new_regs.lcdcon2; fbi->reg.lcdcon3 = new_regs.lcdcon3; fbi->reg.lcdcon4 = new_regs.lcdcon4; fbi->reg.lcdcon5 = new_regs.lcdcon5; fbi->reg.lcdsaddr1 = new_regs.lcdsaddr1; fbi->reg.lcdsaddr2 = new_regs.lcdsaddr2; fbi->reg.lcdsaddr3 = new_regs.lcdsaddr3; LCDCON1 = fbi->reg.lcdcon1; LCDCON2 = fbi->reg.lcdcon2; LCDCON3 = fbi->reg.lcdcon3; LCDCON4 = fbi->reg.lcdcon4;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -