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

📄 atafb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	var->transp.offset=0;	var->transp.length=0;	var->transp.msb_right=0;	var->xres_virtual=sttt_xres_virtual;	linelen=var->xres_virtual * var->bits_per_pixel / 8;	ovsc_addlen=linelen*(sttt_yres_virtual - st_yres);		if (! use_hwscroll)		var->yres_virtual=var->yres;	else if (screen_len) {		if (par->yres_virtual)			var->yres_virtual = par->yres_virtual;		else			/* yres_virtual==0 means use maximum */			var->yres_virtual = screen_len / linelen;	}	else {		if (hwscroll < 0)			var->yres_virtual = 2 * var->yres;		else			var->yres_virtual=var->yres+hwscroll * 16;	}	var->xoffset=0;	if (screen_base)		var->yoffset=(par->screen_base - screen_base)/linelen;	else		var->yoffset=0;	var->nonstd=0;	var->activate=0;	var->vmode=FB_VMODE_NONINTERLACED;	return 0;}static void stste_get_par( struct atafb_par *par ){	unsigned long addr;	par->hw.st.mode=shifter_tt.st_shiftmode;	par->hw.st.sync=shifter.syncmode;	addr = ((shifter.bas_hi & 0xff) << 16) |	       ((shifter.bas_md & 0xff) << 8);	if (ATARIHW_PRESENT(EXTD_SHIFTER))		addr |= (shifter.bas_lo & 0xff);	par->screen_base = phys_to_virt(addr);}static void stste_set_par( struct atafb_par *par ){	shifter_tt.st_shiftmode=par->hw.st.mode;	shifter.syncmode=par->hw.st.sync;	/* only set screen_base if really necessary */	if (current_par.screen_base != par->screen_base)		fbhw->set_screen_base(par->screen_base);}static int stste_getcolreg(unsigned regno, unsigned *red,			   unsigned *green, unsigned *blue,			   unsigned *transp, struct fb_info *info){	unsigned col, t;		if (regno > 15)		return 1;	col = shifter_tt.color_reg[regno];	if (ATARIHW_PRESENT(EXTD_SHIFTER)) {		t = ((col >> 7) & 0xe) | ((col >> 11) & 1);		t |= t << 4;		*red = t | (t << 8);		t = ((col >> 3) & 0xe) | ((col >> 7) & 1);		t |= t << 4;		*green = t | (t << 8);		t = ((col << 1) & 0xe) | ((col >> 3) & 1);		t |= t << 4;		*blue = t | (t << 8);	}	else {		t = (col >> 7) & 0xe;		t |= t << 4;		*red = t | (t << 8);		t = (col >> 3) & 0xe;		t |= t << 4;		*green = t | (t << 8);		t = (col << 1) & 0xe;		t |= t << 4;		*blue = t | (t << 8);	}	*transp = 0;	return 0;}static int stste_setcolreg(unsigned regno, unsigned red,			   unsigned green, unsigned blue,			   unsigned transp, struct fb_info *info){	if (regno > 15)		return 1;	red >>= 12;	blue >>= 12;	green >>= 12;	if (ATARIHW_PRESENT(EXTD_SHIFTER))		shifter_tt.color_reg[regno] =			(((red & 0xe) >> 1) | ((red & 1) << 3) << 8) |			(((green & 0xe) >> 1) | ((green & 1) << 3) << 4) |			((blue & 0xe) >> 1) | ((blue & 1) << 3);	else		shifter_tt.color_reg[regno] =			((red & 0xe) << 7) |			((green & 0xe) << 3) |			((blue & 0xe) >> 1);	return 0;}						  static int stste_detect( void ){	struct atafb_par par;	/* Determine the connected monitor: The DMA sound must be	 * disabled before reading the MFP GPIP, because the Sound	 * Done Signal and the Monochrome Detect are XORed together!	 */	if (ATARIHW_PRESENT(PCM_8BIT)) {		tt_dmasnd.ctrl = DMASND_CTRL_OFF;		udelay(20);	/* wait a while for things to settle down */	}	mono_moni = (mfp.par_dt_reg & 0x80) == 0;	stste_get_par(&par);	stste_encode_var(&atafb_predefined[0], &par);	if (!ATARIHW_PRESENT(EXTD_SHIFTER))		use_hwscroll = 0;	return 1;}static void stste_set_screen_base(void *s_base){	unsigned long addr;	addr= virt_to_phys(s_base);	/* Setup Screen Memory */	shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16);  	shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8);	if (ATARIHW_PRESENT(EXTD_SHIFTER))		shifter.bas_lo=(unsigned char)  (addr & 0x0000ff);}#endif /* ATAFB_STE *//* Switching the screen size should be done during vsync, otherwise * the margins may get messed up. This is a well known problem of * the ST's video system. * * Unfortunately there is hardly any way to find the vsync, as the * vertical blank interrupt is no longer in time on machines with * overscan type modifications. * * We can, however, use Timer B to safely detect the black shoulder, * but then we've got to guess an appropriate delay to find the vsync. * This might not work on every machine. * * martin_rogge @ ki.maus.de, 8th Aug 1995 */#define LINE_DELAY  (mono_moni ? 30 : 70)#define SYNC_DELAY  (mono_moni ? 1500 : 2000)/* SWITCH_ACIA may be used for Falcon (ScreenBlaster III internal!) */static void st_ovsc_switch(void){    unsigned long flags;    register unsigned char old, new;    if (!(atari_switches & ATARI_SWITCH_OVSC_MASK))	return;    save_flags(flags);    cli();    mfp.tim_ct_b = 0x10;    mfp.active_edge |= 8;    mfp.tim_ct_b = 0;    mfp.tim_dt_b = 0xf0;    mfp.tim_ct_b = 8;    while (mfp.tim_dt_b > 1)	/* TOS does it this way, don't ask why */	;    new = mfp.tim_dt_b;    do {	udelay(LINE_DELAY);	old = new;	new = mfp.tim_dt_b;    } while (old != new);    mfp.tim_ct_b = 0x10;    udelay(SYNC_DELAY);    if (atari_switches & ATARI_SWITCH_OVSC_IKBD)	acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE;    if (atari_switches & ATARI_SWITCH_OVSC_MIDI)	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;    if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) {	sound_ym.rd_data_reg_sel = 14;	sound_ym.wd_data = sound_ym.rd_data_reg_sel |			   ((atari_switches&ATARI_SWITCH_OVSC_SND6) ? 0x40:0) |			   ((atari_switches&ATARI_SWITCH_OVSC_SND7) ? 0x80:0);    }    restore_flags(flags);}/* ------------------- External Video ---------------------- */#ifdef ATAFB_EXTstatic int ext_encode_fix( struct fb_fix_screeninfo *fix,						   struct atafb_par *par ){	strcpy(fix->id,"Unknown Extern");	fix->smem_start = (unsigned long)external_addr;	fix->smem_len = PAGE_ALIGN(external_len);	if (external_depth == 1) {		fix->type = FB_TYPE_PACKED_PIXELS;		/* The letters 'n' and 'i' in the "atavideo=external:" stand		 * for "normal" and "inverted", rsp., in the monochrome case */		fix->visual =			(external_pmode == FB_TYPE_INTERLEAVED_PLANES ||			 external_pmode == FB_TYPE_PACKED_PIXELS) ?				FB_VISUAL_MONO10 :					FB_VISUAL_MONO01;	}	else {		/* Use STATIC if we don't know how to access color registers */		int visual = external_vgaiobase ?					 FB_VISUAL_PSEUDOCOLOR :					 FB_VISUAL_STATIC_PSEUDOCOLOR;		switch (external_pmode) {		    case -1:              /* truecolor */			fix->type=FB_TYPE_PACKED_PIXELS;			fix->visual=FB_VISUAL_TRUECOLOR;			break;		    case FB_TYPE_PACKED_PIXELS:			fix->type=FB_TYPE_PACKED_PIXELS;			fix->visual=visual;			break;		    case FB_TYPE_PLANES:			fix->type=FB_TYPE_PLANES;			fix->visual=visual;			break;		    case FB_TYPE_INTERLEAVED_PLANES:			fix->type=FB_TYPE_INTERLEAVED_PLANES;			fix->type_aux=2;			fix->visual=visual;			break;		}	}	fix->xpanstep = 0;	fix->ypanstep = 0;	fix->ywrapstep = 0;	fix->line_length = 0;	return 0;}static int ext_decode_var( struct fb_var_screeninfo *var,						   struct atafb_par *par ){	struct fb_var_screeninfo *myvar = &atafb_predefined[0];		if (var->bits_per_pixel > myvar->bits_per_pixel ||		var->xres > myvar->xres ||		var->xres_virtual > myvar->xres_virtual ||		var->yres > myvar->yres ||		var->xoffset > 0 ||		var->yoffset > 0)		return -EINVAL;	return 0;}static int ext_encode_var( struct fb_var_screeninfo *var,						   struct atafb_par *par ){	memset(var, 0, sizeof(struct fb_var_screeninfo));	var->red.offset=0;	var->red.length=(external_pmode == -1) ? external_depth/3 : 			(external_vgaiobase ? external_bitspercol : 0);	var->red.msb_right=0;	var->grayscale=0;	var->pixclock=31041;	var->left_margin=120;		/* these are surely incorrect 	*/	var->right_margin=100;	var->upper_margin=8;	var->lower_margin=16;	var->hsync_len=140;	var->vsync_len=30;	var->height=-1;	var->width=-1;	var->sync=0;	var->xres = external_xres;	var->yres = external_yres;	var->xres_virtual = external_xres_virtual;	var->bits_per_pixel = external_depth;		var->blue=var->green=var->red;	var->transp.offset=0;	var->transp.length=0;	var->transp.msb_right=0;	var->yres_virtual=var->yres;	var->xoffset=0;	var->yoffset=0;	var->nonstd=0;	var->activate=0;	var->vmode=FB_VMODE_NONINTERLACED;	return 0;}static void ext_get_par( struct atafb_par *par ){	par->screen_base = external_addr;}static void ext_set_par( struct atafb_par *par ){}#define OUTB(port,val) \	*((unsigned volatile char *) ((port)+external_vgaiobase))=(val)#define INB(port) \	(*((unsigned volatile char *) ((port)+external_vgaiobase)))#define DACDelay 				\	do {					\		unsigned char tmp=INB(0x3da);	\		tmp=INB(0x3da);			\	} while (0)static int ext_getcolreg( unsigned regno, unsigned *red,						  unsigned *green, unsigned *blue,						  unsigned *transp, struct fb_info *info ){	if (! external_vgaiobase)		return 1;	    *red   = ext_color[regno].red;	    *green = ext_color[regno].green;	    *blue  = ext_color[regno].blue;	    *transp=0;	    return 0;}	static int ext_setcolreg( unsigned regno, unsigned red,						  unsigned green, unsigned blue,						  unsigned transp, struct fb_info *info ){	unsigned char colmask = (1 << external_bitspercol) - 1;	if (! external_vgaiobase)		return 1;	ext_color[regno].red = red;	ext_color[regno].green = green;	ext_color[regno].blue = blue;	switch (external_card_type) {	  case IS_VGA:	    OUTB(0x3c8, regno);	    DACDelay;	    OUTB(0x3c9, red & colmask);	    DACDelay;	    OUTB(0x3c9, green & colmask);	    DACDelay;	    OUTB(0x3c9, blue & colmask);	    DACDelay;	    return 0;	  case IS_MV300:	    OUTB((MV300_reg[regno] << 2)+1, red);	    OUTB((MV300_reg[regno] << 2)+1, green);	    OUTB((MV300_reg[regno] << 2)+1, blue);	    return 0;	  default:	    return 1;	  }}	static int ext_detect( void ){	struct fb_var_screeninfo *myvar = &atafb_predefined[0];	struct atafb_par dummy_par;	myvar->xres = external_xres;	myvar->xres_virtual = external_xres_virtual;	myvar->yres = external_yres;	myvar->bits_per_pixel = external_depth;	ext_encode_var(myvar, &dummy_par);	return 1;}#endif /* ATAFB_EXT *//* ------ This is the same for most hardware types -------- */static void set_screen_base(void *s_base){	unsigned long addr;	addr= virt_to_phys(s_base);	/* Setup Screen Memory */	shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16);  	shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8);  	shifter.bas_lo=(unsigned char)  (addr & 0x0000ff);}static int pan_display( struct fb_var_screeninfo *var,                        struct atafb_par *par ){	if (!fbhw->set_screen_base ||		(!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset))		return -EINVAL;	var->xoffset = up(var->xoffset, 16);	par->screen_base = screen_base +	        (var->yoffset * fb_display[currcon].var.xres_virtual + var->xoffset)	        * fb_display[currcon].var.bits_per_pixel / 8;	fbhw->set_screen_base (par->screen_base);	return 0;}/* ------------ Interfaces to hardware functions ------------ */#ifdef ATAFB_TTstatic struct fb_hwswitch tt_switch = {	tt_detect, tt_encode_fix, tt_decode_var, tt_encode_var,	tt_get_par, tt_set_par, tt_getcolreg, tt_setcolreg,	set_screen_base, NULL, pan_display};#endif#ifdef ATAFB_FALCONstatic struct fb_hwswitch falcon_switch = {	falcon_detect, falcon_encode_fix, falcon_decode_var, falcon_encode_var,	falcon_get_par, falcon_set_par, falcon_getcolreg,	falcon_setcolreg, set_screen_base, falcon_blank, falcon_pan_display};#endif#ifdef ATAFB_STEstatic struct fb_hwswitch st_switch = {	stste_detect, stste_encode_fix, stste_decode_var, stste_encode_var,	stste_get_par, stste_set_par, stste_getcolreg, stste_setcolreg,	stste_set_screen_base, NULL, pan_display};#endif#ifdef ATAFB_EXTstatic struct fb_hwswitch ext_switch = {	ext_detect, ext_encode_fix, ext_decode_var, ext_encode_var,	ext_get_par, ext_set_par, ext_getcolreg, ext_setcolreg, NULL, NULL, NULL};#endifstatic void atafb_g

⌨️ 快捷键说明

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