⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410fb.c

📁 s3c2410在linux2.4.18上LCD移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/drivers/video/s3c2410fb.c * *  CopyRight (C) 2002 SAMSUNG ELECTRONICS  *                    SW.LEE <hitchcar@sec.samsung.com> * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive for * more details. */#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 <linux/cpufreq.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>/* * enable this if your panel appears to have broken */#undef CHECK_COMPAT/* * debugging? */#define DEBUG 1/* * Complain if VAR is out of range. */#define DEBUG_VAR 1#include "s3c2410fb.h"void (*s3c2410fb_blank_helper)(int blank);/* EXPORT_SYMBOL(s3c2410fb_blank_helper); *//* * IMHO this looks wrong.  In 8BPP, length should be 8. */static 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, },};/* S3C2410  * 256 Palette Usage (TFT) * 256 color palette consist of 256(depth) * 16 bit SPSRAM */ static 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, },};/******* * role : Fill Machine dependant data ,according to  STN or TFT  * */static void  __init s3c2410fb_get_machine_info(struct s3c2410fb_info *fbi){          static struct s3c2410fb_mach_info inf  __initdata = {#if (LCD_TYPE == TFT240_320)	  pixclock:       174757,              bpp:            16,	  xres:		240,		yres:		320,#endif#if (LCD_TYPE == TFT640_480)	  pixclock:       174757,         bpp:            16,	  xres:		640,		yres:		480,#endif#if defined(CONFIG_SOMETHING_OHTERS) /* Not Tested .. */	  pixclock:       0,              bpp:            8,	  xres:		320,		yres:		240,#endif	 // hsync_len:	5,		vsync_len:	1,	 // left_margin:	7,		upper_margin:	1,	 // right_margin:	3,		lower_margin:	3,    //070903-zjm	  hsync_len:	64,		vsync_len:	2,                 //1<=hsync,vsync<=64;	  left_margin:	40,		upper_margin:	24,         //{1,255}	  right_margin:	32,		lower_margin:	11,         //[1,255]	  sync:	        0,      		cmap_static:	1,	//FB_ACTIVATE_NOW , /* value 0 */ 	/*reg : {		rLCDCON1 : (CLKVAL_TFT<<8) | (3<<5) | (1<<8) ,		rLCDCON2 : (32<<24) | (9<<6) | (1),		rLCDCON3 : (47<<19) | (15),		rLCDCON4 : (95) | (13<<18),		rLCDCON5 : (1<<11) | (1<<9) | (1<<8) | (1) | (1<<3),			}, */		};	fbi->max_xres			= inf.xres;	fbi->fb.var.xres		= inf.xres;	fbi->fb.var.xres_virtual	= inf.xres;	fbi->max_yres			= inf.yres;	fbi->fb.var.yres		= inf.yres;	fbi->fb.var.yres_virtual	= inf.yres;	fbi->max_bpp			= inf.bpp;	fbi->fb.var.bits_per_pixel	= inf.bpp;	fbi->fb.var.pixclock		= inf.pixclock;	fbi->fb.var.hsync_len		= inf.hsync_len;	fbi->fb.var.left_margin		= inf.left_margin;	fbi->fb.var.right_margin	= inf.right_margin;	fbi->fb.var.vsync_len		= inf.vsync_len;	fbi->fb.var.upper_margin	= inf.upper_margin;	fbi->fb.var.lower_margin	= inf.lower_margin;	fbi->fb.var.sync		= inf.sync;	fbi->fb.var.grayscale		= inf.cmap_greyscale;	fbi->cmap_inverse		= inf.cmap_inverse;	fbi->cmap_static		= inf.cmap_static;	}static void s3c2410fb_lcd_port_init(void );static int s3c2410fb_activate_var(struct fb_var_screeninfo *var, struct s3c2410fb_info *);static void set_ctrlr_state(struct s3c2410fb_info *fbi, u_int state);#if (LCD_TYPE == TFT240_320)#define FR_WIDTH            240#define FR_HEIGHT           320#endif#if (LCD_TYPE == TFT640_480)#define FR_WIDTH            640#define FR_HEIGHT           480#endifstruct FrameBuffer {   unsigned short pixel[FR_HEIGHT][FR_WIDTH];};struct FrameBuffer *FBuf;#ifdef YOU_WANT_TO_DRAW_TETRAGONstatic void lcd_demo(void){    // Test LCD Initialization. by displaying R.G.B and White.  int i,j;	for(i=0 ;i<FR_HEIGHT/2;i++)	{		for(j=0;j<FR_WIDTH;j++)		{		  if(j<FR_WIDTH/2)		    FBuf->pixel[i][j]= 0xffff;		  else		    FBuf->pixel[i][j]= 0xf800;		}	}	for(i=FR_HEIGHT/2 ;i<FR_HEIGHT;i++)	{		for(j=0;j<FR_WIDTH;j++)		{		if(j<FR_WIDTH/2)		    FBuf->pixel[i][j]= 0x07e0;		else		    FBuf->pixel[i][j]= 0x001f;		}	}    }#endifstatic void s3c2410fb_lcd_port_init(void){    rGPCUP=0xffffffff; // Disable Pull-up register    rGPCCON=0xaaaaaaaa; //Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND     rGPDUP=0xffffffff; // Disable Pull-up register    rGPDCON=0xaaaaaaaa; //Initialize VD[23:8]}                                  static inline void s3c2410fb_schedule_task(struct s3c2410fb_info *fbi, u_int state){	unsigned long flags;	local_irq_save(flags);	/*	 * We need to handle two requests being made at the same time.	 * There are two important cases:	 *  1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE)	 *     We must perform the unblanking, which will do our REENABLE for us.	 *  2. When we are blanking, but immediately unblank before we have	 *     blanked.  We do the "REENABLE" thing here as well, just to be sure.	 */	if (fbi->task_state == C_ENABLE && state == C_REENABLE)		state = (u_int) -1;	if (fbi->task_state == C_DISABLE && state == C_ENABLE)		state = C_REENABLE;	if (state != (u_int)-1) {		fbi->task_state = state;		schedule_task(&fbi->task);	}	local_irq_restore(flags);}/* * Get the VAR structure pointer for the specified console */static 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;}/* * Get the DISPLAY structure pointer for the specified console * * struct display fb_display[MAX_NR_CONSOLES]; from fbcon.c */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];}/* * Get the CMAP pointer for the specified console * * struct fb_cmap { *	__u32 start;			 First entry	 *	__u32 len;			 Number of entries  *	__u16 *red;			 Red values *	__u16 *green; *	__u16 *blue; *	__u16 *transp;			 transparency, can be NULL  * }; * */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 u_intchan_to_field(u_int chan, struct fb_bitfield *bf){	chan &= 0xffff;	chan >>= 16 - bf->length;	return chan << bf->offset;}/* * 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;}/****** * bit mask RGB=565  -> RRRR RGGG GGGB BBBB *                      1111 1000 0000 0000   0xf800 *                      0000 0111 1110 0000   0x07e0 *                      0000 0000 0001 1111   0x001f *******************************************************/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) {		val = ((blue >> 16) & 0x001f);		val |= ((green >> 11) & 0x07e0);		val |= ((red >> 5) & 0x0f800);		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 val;	int ret = 1;	/*	 * If inverse mode was selected, invert all the colours	 * rather than the register number.  The register number	 * is what you poke into the framebuffer to produce the	 * colour you requested.	 */      	//if (disp->inverse) 	//{	//	red   = 0xffff - red;	//	green = 0xffff - green;	//	blue  = 0xffff - blue;	//}	/*	 * If greyscale is true, then we convert the RGB value	 * to greyscale no mater what visual we are using.	 */	if (fbi->fb.var.grayscale)		red = green = blue = (19595 * red + 38470 * green +					7471 * blue) >> 16;	switch (fbi->fb.disp->visual) {	case FB_VISUAL_TRUECOLOR:		/*		 * 12 or 16-bit True Colour.  We encode the RGB value		 * according to the RGB bitfield information.		 */		if (regno < 16) {			u16 *pal = fbi->fb.pseudo_palette;			val  = chan_to_field(red, &fbi->fb.var.red);			val |= chan_to_field(green, &fbi->fb.var.green);			val |= chan_to_field(blue, &fbi->fb.var.blue);			pal[regno] = val;			ret = 0;		}		break;	case FB_VISUAL_STATIC_PSEUDOCOLOR:	case FB_VISUAL_PSEUDOCOLOR:		ret = s3c2410fb_setpalettereg(regno, red, green, blue, trans, info);		break;	}	return ret;}/* *  s3c2410fb_decode_var(): *    Get the video params out of 'var'. If a value doesn't fit, round it up, *    if it's too big, return -EINVAL. * *    Suggestion: Round up in the following order: bits_per_pixel, xres, *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, *    bitfields, horizontal timing, vertical timing. */static ints3c2410fb_validate_var(struct fb_var_screeninfo *var,		      struct s3c2410fb_info *fbi)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -