📄 t6963fb.c
字号:
/* * linux/drivers/video/s3c44b0fb.c * * tpu. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Framebuffer driver for the S3C44B0X processors. */#include <linux/module.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/init.h>#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <asm/hardware.h>#include <asm/mach-types.h>#include <asm/uaccess.h>static struct s3c44b0fb_info { struct fb_info fb; int currcon;} *cfb;#define CMAP_SIZE 256#define PIO_REFRESH_TIMER_TICKS 4wait_queue_head_t proc_list;static int flag_wake = 0;/* * Set a single color register. Return != 0 for invalid regno. */static ints3c44b0fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){ //TODO return 0;} /* * Set the colormap */static ints3c44b0fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ struct s3c44b0fb_info *cfb = (struct s3c44b0fb_info *)info; struct fb_cmap *dcmap = &fb_display[con].cmap; int err = 0; /* no colormap allocated? */ if (!dcmap->len) err = fb_alloc_cmap(dcmap, CMAP_SIZE, 0); if (!err && con == cfb->currcon) { err = fb_set_cmap(cmap, kspc, s3c44b0fb_setcolreg, &cfb->fb); dcmap = &cfb->fb.cmap; } if (!err) fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1); return err;}/* * Set the User Defined Part of the Display */static ints3c44b0fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct display *display; unsigned int lcdcon, syscon; int chgvar = 0; if (var->activate & FB_ACTIVATE_TEST) return 0; if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) return -EINVAL; if (cfb->fb.var.xres != var->xres) chgvar = 1; if (cfb->fb.var.yres != var->yres) chgvar = 1; if (cfb->fb.var.xres_virtual != var->xres_virtual) chgvar = 1; if (cfb->fb.var.yres_virtual != var->yres_virtual) chgvar = 1; if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel) chgvar = 1; if (con < 0) { display = cfb->fb.disp; chgvar = 0; } else { display = fb_display + con; } var->transp.msb_right = 0; var->transp.offset = 0; var->transp.length = 0; var->red.msb_right = 5;//0; var->red.offset = 5; var->red.length = 3; var->green.msb_right = 2;//0; var->green.offset = 2; var->green.length = 3; var->blue.msb_right = 0; var->blue.offset = 0; var->blue.length = 2; switch (var->bits_per_pixel) {#ifdef FBCON_HAS_MFB case 1: printk("var->bits_per_pixel = %d\n",var->bits_per_pixel); cfb->fb.fix.visual = FB_VISUAL_MONO01; display->dispsw = &fbcon_mfb; display->dispsw_data = NULL; break;#endif#ifdef FBCON_HAS_CFB2 case 2: cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; display->dispsw = &fbcon_cfb2; display->dispsw_data = NULL; break;#endif#ifdef FBCON_HAS_CFB4 case 4: cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; display->dispsw = &fbcon_cfb4; display->dispsw_data = NULL; break;#endif#ifdef FBCON_HAS_CFB8 case 8: cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; display->dispsw = &fbcon_cfb8; display->dispsw_data = NULL; break;#endif default: return -EINVAL; } display->next_line = var->xres_virtual * var->bits_per_pixel / 8; cfb->fb.fix.line_length = display->next_line; display->screen_base = cfb->fb.screen_base; display->line_length = cfb->fb.fix.line_length; display->visual = cfb->fb.fix.visual; display->type = cfb->fb.fix.type; display->type_aux = cfb->fb.fix.type_aux; display->ypanstep = cfb->fb.fix.ypanstep; display->ywrapstep = cfb->fb.fix.ywrapstep; display->can_soft_blank = 1; display->inverse = 0; cfb->fb.var = *var; cfb->fb.var.activate &= ~FB_ACTIVATE_ALL; /* * Update the old var. The fbcon drivers still use this. * Once they are using cfb->fb.var, this can be dropped. * --rmk */ display->var = cfb->fb.var; /* * If we are setting all the virtual consoles, also set the * defaults used to create new consoles. */ if (var->activate & FB_ACTIVATE_ALL) cfb->fb.disp->var = cfb->fb.var; if (chgvar && info && cfb->fb.changevar) cfb->fb.changevar(con); fb_set_cmap(&cfb->fb.cmap, 1, s3c44b0fb_setcolreg, &cfb->fb); return 0;}/* * Get the currently displayed virtual consoles colormap. */static intgen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2); return 0;}/* * Get the currently displayed virtual consoles fixed part of the display. */static intgen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ *fix = info->fix; return 0;}/* * Get the current user defined part of the display. */static intgen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ *var = info->var; return 0;}static struct fb_ops s3c44b0fb_ops = { owner: THIS_MODULE, fb_set_var: s3c44b0fb_set_var, fb_set_cmap: s3c44b0fb_set_cmap, fb_get_fix: gen_get_fix, fb_get_var: gen_get_var, fb_get_cmap: gen_get_cmap,};static int s3c44b0fb_updatevar(int con, struct fb_info *info){ return -EINVAL;}static void s3c44b0fb_blank(int blank, struct fb_info *info){ //TODO if (blank) { } else { }}/********************************************************************************/#define U8 __u8#define U16 __u16 #define U32 __u32#define SCR_XSIZE 240#define SCR_YSIZE 128#define LCD_XSIZE 240#define LCD_YSIZE 128#define LCD_DEPTH 1#define LCD_BUF_SIZE ((SCR_XSIZE*SCR_YSIZE/8))unsigned char t6963fb_buff[LCD_BUF_SIZE];unsigned char tmp_buff[LCD_BUF_SIZE];#define time_out 0xfffffff#define LCD_RD_CLR (GPBDAT &= ~(1<<0))#define LCD_RD_SET (GPBDAT |= (1<<0))#define LCD_WR_CLR (GPDDAT &= ~(1<<8))#define LCD_WR_SET (GPDDAT |= (1<<8))#define LCD_CD_CLR (GPDDAT &= ~(1<<10))#define LCD_CD_SET (GPDDAT |= (1<<10))#define LCD_CS_CLR (GPDDAT &= ~(1<<9))#define LCD_CS_SET (GPDDAT |= (1<<9))#define LCD_FS_CLR (GPDDAT &= ~(1<<12))#define LCD_FS_SET (GPDDAT |= (1<<12))struct timer_list pio_timer;static inline void LCD_READ_EN(void) { GPDCON &= 0xffff0000;//GPD0 - GPD7 input GPDUP &= 0xff00; //enable pupll}//GPD0-12 out)static inline void LCD_WRITE_EN(void) { GPDCON |= 0x01555555;//GPD0 - GPD7 input GPDUP |= 0xff;//disable pupll}/************************************************************************* 功能:delay 参数: 返回值:-1: error 0: OK **************************************************************************/static void delay(int i) //Delay for 10 CPU Cycles //OK{ for( ;i > 0; i-- ) { asm("nop"); }}/************************************************************************* 功能:read lcd status 参数: 返回值:lcd status **************************************************************************/static u8 ReadStatus(void){ u8 i; LCD_READ_EN(); LCD_CS_CLR; LCD_CD_SET; LCD_RD_CLR; i = (u8)GPDDAT; LCD_RD_SET; delay(20); LCD_CS_SET; return i;}/************************************************************************* 功能:parse st0 st1 参数: 返回值:0 OK -1 err **************************************************************************/static signed char st01(void){ u8 lcd_status = 0; u32 time_nu = 0; do{ lcd_status = (ReadStatus() & 0x03); time_nu++; if(time_nu > time_out)return -1; }while(lcd_status != 0x03); return 0;}/************************************************************************* 功能:parse st2 参数: 返回值:0 OK -1 err **************************************************************************/static signed char st02(void){ u8 lcd_status = 0; u32 time_nu = 0; do{ lcd_status = ((ReadStatus()>>2) & 0x01); time_nu++; if(time_nu > time_out)return -1; }while(lcd_status != 0x01); return 0;}/************************************************************************* 功能:parse st3 参数: 返回值:0 OK -1 err **************************************************************************/static signed char st03(void){ u8 lcd_status = 0; u32 time_nu = 0; do{ lcd_status = ((ReadStatus()>>3) & 0x01); time_nu++; if(time_nu > time_out)return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -