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

📄 atafb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* ATAFB_FALCON *//* ------------------- ST(E) specific functions ---------------------- */#ifdef ATAFB_STEstatic int stste_encode_fix(struct fb_fix_screeninfo *fix,			    struct atafb_par *par){	int mode;	strcpy(fix->id, "Atari Builtin");	fix->smem_start = (unsigned long)real_screen_base;	fix->smem_len = screen_len;	fix->type = FB_TYPE_INTERLEAVED_PLANES;	fix->type_aux = 2;	fix->visual = FB_VISUAL_PSEUDOCOLOR;	mode = par->hw.st.mode & 3;	if (mode == ST_HIGH) {		fix->type = FB_TYPE_PACKED_PIXELS;		fix->type_aux = 0;		fix->visual = FB_VISUAL_MONO10;	}	if (ATARIHW_PRESENT(EXTD_SHIFTER)) {		fix->xpanstep = 16;		fix->ypanstep = 1;	} else {		fix->xpanstep = 0;		fix->ypanstep = 0;	}	fix->ywrapstep = 0;	fix->line_length = par->next_line;	fix->accel = FB_ACCEL_ATARIBLITT;	return 0;}static int stste_decode_var(struct fb_var_screeninfo *var,			    struct atafb_par *par){	int xres = var->xres;	int yres = var->yres;	int bpp = var->bits_per_pixel;	int linelen;	int yres_virtual = var->yres_virtual;	if (mono_moni) {		if (bpp > 1 || xres > sttt_xres || yres > st_yres)			return -EINVAL;		par->hw.st.mode = ST_HIGH;		xres = sttt_xres;		yres = st_yres;		bpp = 1;	} else {		if (bpp > 4 || xres > sttt_xres || yres > st_yres)			return -EINVAL;		if (bpp > 2) {			if (xres > sttt_xres / 2 || yres > st_yres / 2)				return -EINVAL;			par->hw.st.mode = ST_LOW;			xres = sttt_xres / 2;			yres = st_yres / 2;			bpp = 4;		} else if (bpp > 1) {			if (xres > sttt_xres || yres > st_yres / 2)				return -EINVAL;			par->hw.st.mode = ST_MID;			xres = sttt_xres;			yres = st_yres / 2;			bpp = 2;		} else			return -EINVAL;	}	if (yres_virtual <= 0)		yres_virtual = 0;	else if (yres_virtual < yres)		yres_virtual = yres;	if (var->sync & FB_SYNC_EXT)		par->hw.st.sync = (par->hw.st.sync & ~1) | 1;	else		par->hw.st.sync = (par->hw.st.sync & ~1);	linelen = xres * bpp / 8;	if (yres_virtual * linelen > screen_len && screen_len)		return -EINVAL;	if (yres * linelen > screen_len && screen_len)		return -EINVAL;	if (var->yoffset + yres > yres_virtual && yres_virtual)		return -EINVAL;	par->yres_virtual = yres_virtual;	par->screen_base = screen_base + var->yoffset * linelen;	par->next_line = linelen;	return 0;}static int stste_encode_var(struct fb_var_screeninfo *var,			    struct atafb_par *par){	int linelen;	memset(var, 0, sizeof(struct fb_var_screeninfo));	var->red.offset = 0;	var->red.length = ATARIHW_PRESENT(EXTD_SHIFTER) ? 4 : 3;	var->red.msb_right = 0;	var->grayscale = 0;	var->pixclock = 31041;	var->left_margin = 120;		/* these are 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;	if (!(par->hw.st.sync & 1))		var->sync = 0;	else		var->sync = FB_SYNC_EXT;	switch (par->hw.st.mode & 3) {	case ST_LOW:		var->xres = sttt_xres / 2;		var->yres = st_yres / 2;		var->bits_per_pixel = 4;		break;	case ST_MID:		var->xres = sttt_xres;		var->yres = st_yres / 2;		var->bits_per_pixel = 2;		break;	case ST_HIGH:		var->xres = sttt_xres;		var->yres = st_yres;		var->bits_per_pixel = 1;		break;	}	var->blue = var->green = var->red;	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_setcolreg(unsigned int regno, unsigned int red,			   unsigned int green, unsigned int blue,			   unsigned int 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 = (st_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;	local_irq_save(flags);	st_mfp.tim_ct_b = 0x10;	st_mfp.active_edge |= 8;	st_mfp.tim_ct_b = 0;	st_mfp.tim_dt_b = 0xf0;	st_mfp.tim_ct_b = 8;	while (st_mfp.tim_dt_b > 1)	/* TOS does it this way, don't ask why */		;	new = st_mfp.tim_dt_b;	do {		udelay(LINE_DELAY);		old = new;		new = st_mfp.tim_dt_b;	} while (old != new);	st_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);	}	local_irq_restore(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 = par->next_line;	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;	par->next_line = external_xres_virtual * external_depth / 8;	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_setcolreg(unsigned int regno, unsigned int red,			 unsigned int green, unsigned int blue,			 unsigned int transp, struct fb_info *info){	unsigned char colmask = (1 << external_bitspercol) - 1;	if (!external_vgaiobase)		return 1;	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);

⌨️ 快捷键说明

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