?? w90p710fb.c
字號:
/**************************************************************************** * * Copyright (c) 2004 - 2006 Winbond Electronics Corp. All rights reserved. * ***************************************************************************/ /**************************************************************************** * * FILENAME * w90p710fb.c * * VERSION * 1.0 * * DESCRIPTION * W90P710 LCD frame buffer driver. * * * HISTORY * 05/02/06 Ver 1.0 Created by NS22 CCWang * * REMARK * None * **************************************************************************/#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-cfb2.h>#include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb24.h>#include <linux/smp_lock.h>#include "w90p710_lcd.h"//#define WB_AU_DEBUG//#define WB_AU_DEBUG_ENTER_LEAVE#ifdef WB_AU_DEBUG#define DBG(fmt, arg...) printk(fmt, ##arg)#else#define DBG(fmt, arg...)#endif#ifdef WB_AU_DEBUG_ENTER_LEAVE#define ENTER() DBG("[%-10s] : Enter\n", __FUNCTION__)#define LEAVE() DBG("[%-10s] : Leave\n", __FUNCTION__)#else#define ENTER()#define LEAVE()#endifvoid Disable_LCD(void);void Enable_LCD(void);void InitCasioLCD(void);void InitAUOLCD(void);int usiIsBusy(void);static void w90p710fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs);#if 0void (*w90p710fb_blank_helper)(int blank);EXPORT_SYMBOL(w90p710fb_blank_helper);#endifstatic struct w90p710fb_rgb rgb_8 = { red: {offset: 6, length: 2, }, green: {offset: 4, length: 2, }, blue: {offset: 0, length: 4, }, transp: {offset: 0, length: 0, },};static struct w90p710fb_rgb def_rgb_16 = { red: {offset: 11, length: 5, }, green: {offset: 5, length: 6, }, blue: {offset: 0, length: 5, }, transp: {offset: 0, length: 0, },};static struct w90p710fb_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, },};static struct w90p710fb_rgb xxx_tft_rgb_24 = { red: {offset: 16,length: 8, }, green: {offset: 8, length: 8, }, blue: {offset: 0, length: 8, }, transp: {offset: 0, length: 0, },};static struct w90p710fb_mach_info xxx_tft_info __initdata = { pixclock: 67797, #ifdef CONFIG_W90P710_LCD_TFT_24BPP bpp: 24,#endif#if defined(CONFIG_W90P710_LCD_TFT_16BPP) || defined(CONFIG_W90P710_LCD_STN_16BPP) bpp: 16,#endif#if defined(CONFIG_W90P710_LCD_TFT_8BPP) || defined(CONFIG_W90P710_LCD_STN_8BPP) bpp: 8,#endif#if defined(CONFIG_W90P710_LCD_TFT_4BPP) || defined(CONFIG_W90P710_LCD_STN_4BPP) bpp: 4,#endif#if defined(CONFIG_W90P710_LCD_TFT_2BPP) || defined(CONFIG_W90P710_LCD_STN_2BPP) bpp: 2,#endif#if defined(CONFIG_W90P710_LCD_TFT_1BPP) || defined(CONFIG_W90P710_LCD_STN_1BPP) bpp: 1,#endif#ifdef CONFIG_W90P710_LCD_TFT#ifdef CONFIG_W90P710_LCD_TFT_CASIO xres: 480, yres: 240,#else#ifdef CONFIG_W90P710_LCD_TFT_AUO960240 xres: 320, yres: 240,#else#ifdef CONFIG_W90P710_LCD_TFT_TOPPOLY240320 xres: 240, yres: 320,#else#ifdef CONFIG_W90P710_LCD_TFT_LG xres: 640, yres: 480,#endif#endif#endif#endif#else xres: 320, yres: 240,#endif hsync_len : 64, vsync_len : 6, left_margin : 125, upper_margin : 70, right_margin: 115, lower_margin : 36, sync: 0, cmap_static: 0, reg : { lcdcon : LCD_LCDCON_LCDBUS_24 | LCD_LCDCON_LCDTFTTYPE | LCD_LCDCON_LCDTFT | LCD_LCDCON_BPP_16 , lcdfifo1para : LCD_FIFO1PRM_F1BURSTY_08DATABURST | LCD_FIFO1PRM_F1TRANSZ_4BYTE, },};volatile unsigned int _lcd_VSYNC,_lcd_VSYNCCount;static spinlock_t wb_osd_lock = SPIN_LOCK_UNLOCKED;static inline u_intchan_to_field(u_int chan, struct fb_bitfield *bf){ chan &= 0xffff; chan >>= 16 - bf->length; return chan << bf->offset;}#if 0/* * 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;}#endifstatic struct w90p710fb_mach_info * __init w90p710fb_get_machine_info(struct w90p710fb_info *fbi){ struct w90p710fb_mach_info *inf = NULL; inf = &xxx_tft_info; fbi->reg = inf->reg; fbi->rgb[RGB_16] = &xxx_tft_rgb_16; fbi->rgb[RGB_24] = &xxx_tft_rgb_24; return inf;}static inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con){ struct w90p710fb_info *fbi = (struct w90p710fb_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 w90p710fb_info *fbi = (struct w90p710fb_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 w90p710fb_info *fbi = (struct w90p710fb_info *)info; return (con < 0) ? (fbi->fb.disp) : &(fb_display[con]);}static intw90p710fb_validate_var(struct fb_var_screeninfo *var, struct w90p710fb_info *fbi){ int ret = -EINVAL; //printk("w90p710fb_validate_var()..\n"); 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_MFB case 1: ret = 0; break;#endif#ifdef FBCON_HAS_CFB2 case 2: ret = 0; break;#endif#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#ifdef FBCON_HAS_CFB24 case 24: ret = 0; break;#endif default: break; } return ret;}static intw90p710fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct w90p710fb_info *fbi = (struct w90p710fb_info *)info; u_int val, ret = 1; ENTER(); if (regno < fbi->palette_size) { #if 0 for(i = 0; i < fbi->palette_size; i++) { /* Configure entries of look-up table */ WriteLUT(i,fbi->palette_cpu[i]); }#endif //val = (blue & 0x0000ff); //val |= ((green << 8) & 0x00ff00); //val |= ((red << 16) & 0xff0000); //val |= 1; /* intensity bit */ val = ((red & 0xff00) << 8) | ((green & 0xff00) >> 0) | ((blue & 0xff00) >> 8); //if (regno == 0) // val |= palette_pbs(&fbi->fb.var); fbi->palette_cpu[regno] = val; /* Clear VSYNC interrupt and FIFO1 VFRAME FINISH interrupt */ //_lcd_VSYNC = 0; /* Wait until VSYNC interrupt and FIFO1 VFRAME FINISH interrupt occur */ //while(!_lcd_VSYNC); /* Configure TFT Look-up Table */ outpw(REG_LCD_LCDCON, (inpw(REG_LCD_LCDCON) | LCD_LCDCON_LUTWREN) & ~LCD_LCDCON_VDLUTEN); //outpw(LCD_LCDCON, inpw(LCD_LCDCON) & ~LCD_LCDCON_LUTEN); /* Configure entries of look-up table */ WriteLUT(regno,val); /* Configure TFT Look-up Table */ outpw(REG_LCD_LCDCON, (inpw(REG_LCD_LCDCON) | LCD_LCDCON_VDLUTEN) & ~LCD_LCDCON_LUTWREN); //outpw(LCD_LCDCON, inpw(LCD_LCDCON) & ~LCD_LCDCON_LUTWREN); ret = 0; //printk("regno = %d, r[%d] g[%d] b[%d],value = %d \n",regno,red,green,blue,val); } LEAVE(); return ret; }static intw90p710fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct w90p710fb_info *fbi = (struct w90p710fb_info *)info; struct display *disp = get_con_display(info, fbi->currcon); u_int var; int ret = 1; ENTER(); 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 = w90p710fb_setpalettereg(regno, red, green, blue, trans, info); break; } LEAVE(); return ret;}static int w90p710fb_activate_var(struct fb_var_screeninfo *var, struct w90p710fb_info *fbi){ struct w90p710fb_lcd_reg new_regs; u_long flags; u_int half_screen_size/*, yres*/; //u_int i = 0; unsigned long VideoPhysicalTemp = fbi->screen_dma; ENTER(); save_flags_cli(flags); //Disable_LCD(); /*********************************************************************/ new_regs.lcdfifo1saddr = VideoPhysicalTemp; /*Configure FIFO1 transfer data source start address */ outpw(REG_LCD_F1SADDR, new_regs.lcdfifo1saddr); fbi->reg.lcdfifo1saddr = new_regs.lcdfifo1saddr; half_screen_size = var->bits_per_pixel; half_screen_size = half_screen_size * var->xres * var->yres / 16; new_regs.lcdfifo1count = fbi->reg.lcdfifo1count ;#ifdef CONFIG_W90P710_LCD_TFT_24BPP /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, (var->xres << 16) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres); #endif #if defined(CONFIG_W90P710_LCD_TFT_16BPP) || defined(CONFIG_W90P710_LCD_STN_16BPP) /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, ((var->xres << 16) >> 1) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres >> 1);#endif#if defined(CONFIG_W90P710_LCD_TFT_8BPP) || defined(CONFIG_W90P710_LCD_STN_8BPP) /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, ((var->xres << 16) >> 2) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres >> 2);#endif#if defined(CONFIG_W90P710_LCD_TFT_4BPP) || defined(CONFIG_W90P710_LCD_STN_4BPP) /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, ((var->xres << 16) >> 3) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres >> 3);#endif#if defined(CONFIG_W90P710_LCD_TFT_2BPP) || defined(CONFIG_W90P710_LCD_STN_2BPP) /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, ((var->xres << 16) >> 4) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres >> 4);#endif#if defined(CONFIG_W90P710_LCD_TFT_1BPP) || defined(CONFIG_W90P710_LCD_STN_1BPP) /* FIFO1 transfer data count register */ outpw(REG_LCD_F1DREQCNT, ((var->xres << 16) >> 5) | var->yres); /* FIFO 1 real column count register */ outpw(REG_LCD_FIFO1RELACOLCNT, var->xres >> 5);#endif //printk("var->xres = %d, var->yres = %d\n",var->xres,var->yres); //printk("var->bits_per_pixel = %d BPP\n",var->bits_per_pixel); //printk("Frame Buffer address = %lx\n",VideoPhysicalTemp); //Enable_LCD(); restore_flags(flags); /*********************************************************************/ LEAVE(); return 0;}static inline void w90p710fb_set_truecolor(u_int is_true_color){ if (is_true_color) { } else { }} static voidw90p710fb_hw_set_var(struct fb_var_screeninfo *var, struct w90p710fb_info *fbi){ u_long palette_mem_size; ENTER();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -