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

📄 sstfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static void __sst_dac_write(u_long vbase, u8 reg, u8 val){	r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);#ifdef SST_DEBUG	if ((reg & 0x07) != reg)		dprintk("bug line %d: register adress '%d' is too high\n",		         __LINE__,reg);#endif	reg &= 0x07;	__sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);}/* indexed access to ti/att dacs */static u32 __dac_i_read(u_long vbase, u8 reg){	u32 ret;	__sst_dac_write(vbase, DACREG_ADDR_I, reg);	ret = __sst_dac_read(vbase, DACREG_DATA_I);	r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);	return ret;}static void __dac_i_write(u_long vbase, u8 reg,u8 val){	r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);	__sst_dac_write(vbase, DACREG_ADDR_I, reg);	__sst_dac_write(vbase, DACREG_DATA_I, val);}/* * *  Internal routines * */static void sstfb_install_cmap(int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	f_dprintk("sstfb_install_cmap(con: %d)\n",con);	f_ddprintk("currcon: %d\n", sst_info->currcon);	if (con != sst_info->currcon)		return;	if (fb_display[con].cmap.len)		fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);	else		fb_set_cmap(			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),			1, sstfb_setcolreg, info);#undef sst_info}static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,                           u_int *transp, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	f_dddprintk("sstfb_getcolreg\n");	if (regno >= 16) return 1;	*red    = sst_info->palette[regno].red;	*green  = sst_info->palette[regno].green;	*blue   = sst_info->palette[regno].blue;	*transp = sst_info->palette[regno].transp;	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",	            regno,*red, *green, *blue, *transp);	return 0;#undef sst_info}static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,                           u_int transp, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	u32 col;	struct display * disp;	f_dddprintk("sstfb_setcolreg\n");	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",	            regno, red, green, blue, transp);	if (regno >= 16) return 1;	sst_info->palette[regno].red   = red;	sst_info->palette[regno].green = green;	sst_info->palette[regno].blue  = blue;	sst_info->palette[regno].transp= transp;	disp=&sst_info->disp;	red    >>= (16 - disp->var.red.length);	green  >>= (16 - disp->var.green.length);	blue   >>= (16 - disp->var.blue.length);	transp >>= (16 - disp->var.transp.length);	col = (red << disp->var.red.offset)	    | (green << disp->var.green.offset)	    | (blue  << disp->var.blue.offset)	    | (transp << disp->var.transp.offset);	switch(disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB16	case 16:		sst_info->fbcon_cmap.cfb16[regno]=(u16)col;		break;#endif#ifdef EN_24_32_BPP#if defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)	case 24:	case 32:		sst_info->fbcon_cmap.cfb32[regno]=col;		break;#endif#endif	default:		BUG();		break;	}	f_dddprintk("bpp: %d . encoded color: %#x\n",	            disp->var.bits_per_pixel, col);	return 0;#undef sst_info}/* set par according to var ( checks var ) */static int sstfb_decode_var (const struct fb_var_screeninfo *var,                             struct sstfb_par *par,                             const struct sstfb_info *sst_info){	int real_length;	f_dprintk("sstfb_decode_var\n");	/* Check var validity */	par->valid=0;	memset(par, 0, sizeof(par));	par->xDim       = var->xres;	par->hSyncOn    = var->hsync_len;	par->hSyncOff   = var->xres + var->right_margin + var->left_margin;	par->hBackPorch = var->left_margin;	par->yDim       = var->yres;	par->vSyncOn    = var->vsync_len;	par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;	par->vBackPorch = var->upper_margin;	if(sst_calc_pll (PS2KHZ(var->pixclock), &par->freq, &par->pll)) {		eprintk("Pixclock %d out of range\n", var->pixclock);		return -EINVAL; //XXX	}	par->sync=var->sync & (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);	par->vmode=var->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE);	/* in laced mode, vBackPorch should be even. odd -> funky display */	if (par->vmode & FB_VMODE_INTERLACED)		par->vBackPorch += (par->vBackPorch % 2);	if (par->vmode & FB_VMODE_DOUBLE) {		par->vBackPorch <<= 1;		par->yDim <<=1;		par->vSyncOn <<=1;		par->vSyncOff <<=1;	}	switch (var->bits_per_pixel) {	case 0 ... 16 :		par->bpp = 16;		break;#ifdef EN_24_32_BPP	case 17 ... 24 :		par->bpp = 24;		break;	case 25 ... 32 :		par->bpp = 32;		break;#endif	default :		eprintk ("Unsupported bpp %d\n", par->bpp);		return -EINVAL;		break;	}	if (IS_VOODOO2(sst_info)) {		/* voodoo2 has 32 pixel wide tiles , BUT stange things		 happen with odd number of tiles */		par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;	} else {		/* voodoo1 has 64 pixels wide tiles. */		par->tiles_in_X= (par->xDim + 63 ) / 64;	}	/* validity tests */	if((par->xDim <= 1) || (par->yDim <= 0 )	   || (par->hSyncOn <= 1)	   || (par->hSyncOff <= 1)	   || (par->hBackPorch <= 2)	   || (par->vSyncOn <= 0)	   || (par->vSyncOff <= 0)	   || (par->vBackPorch <= 0)	   || (par->tiles_in_X <= 0)) {		return -EINVAL;	}	if (IS_VOODOO2(sst_info)) {		/* Voodoo 2 limits */		if(((par->xDim-1) >= POW2(11)) || (par->yDim >= POW2(11))) {			eprintk ("Unsupported resolution %dx%d\n",			         var->xres, var->yres);			return -EINVAL;		}		if (((par->hSyncOn-1) >= POW2(9))		   || ((par->hSyncOff-1) >= POW2(11))		   || ((par->hBackPorch-2) >= POW2(9))		   || (par->vSyncOn >= POW2(13))		   || (par->vSyncOff >= POW2(13))		   || (par->vBackPorch >= POW2(9))		   || (par->tiles_in_X >= POW2(6))) {			eprintk ("Unsupported Timing\n");			return -EINVAL;		}	} else {		/* Voodoo limits */		if (par->vmode) {			eprintk("Interlace/Doublescan not supported %#x\n",				par->vmode);			return -EINVAL;		}		if(((par->xDim-1) >= POW2(10)) || (par->yDim >= POW2(10))) {			eprintk ("Unsupported resolution %dx%d\n",			         var->xres, var->yres);			return -EINVAL;		}		if (((par->hSyncOn-1) >= POW2(8))		   || ((par->hSyncOff-1) >= POW2(10))		   || ((par->hBackPorch-2) >= POW2(8))		   || (par->vSyncOn >= POW2(12))		   || (par->vSyncOff >= POW2(12))		   || (par->vBackPorch >= POW2(8))		   || (par->tiles_in_X >= POW2(4))) {			eprintk ("Unsupported Timings\n");			return -EINVAL;		}	}	/* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/	/* FIXME: i don't like this... looks wrong*/	real_length = par->tiles_in_X  * (IS_VOODOO2(sst_info) ? 32 : 64 )	              * ((par->bpp == 16) ? 2 : 4);	if ((real_length * var->yres) > sst_info->video.len) {		eprintk ("Not enough video memory\n");		return -ENOMEM;	}	par->valid=1;	return 0;}/* sets var according to par (basicaly, sets sane values) */static int sstfb_encode_var (struct fb_var_screeninfo *var,                             const struct sstfb_par *par,                             const struct sstfb_info *sst_info){	memset(var,0,sizeof(struct fb_var_screeninfo));	var->xres           = par->xDim;	var->yres           = par->yDim;	var->xres_virtual   = par->xDim;	var->yres_virtual   = par->yDim;	var->bits_per_pixel = par->bpp;	/* {x|y}offset = 0 ; sync=0 */	var->height         = -1;	var->width          = -1;	var->pixclock       = KHZ2PS(par->freq);	var->left_margin    = par->hBackPorch;	var->right_margin   = par->hSyncOff - par->xDim - par->hBackPorch;	var->upper_margin   = par->vBackPorch;	var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;	var->hsync_len      = par->hSyncOn;	var->vsync_len      = par->vSyncOn;	var->sync           = par->sync;	var->vmode          = par->vmode;	if (var->vmode & FB_VMODE_DOUBLE) {		var->yres           >>=1;		var->yres_virtual   >>=1;		var->vsync_len      >>=1;		var->upper_margin   >>=1;		var->lower_margin   >>=1;	}	/*	 * correct the color bit fields	 */	/* var->{red|green|blue}.msb_right    = 0; */	switch (par->bpp) {	case 16:	/* RGB 565  LfbMode 0 */		var->red.length    = 5;		var->green.length  = 6;		var->blue.length   = 5;		var->transp.length = 0;		var->red.offset    = 11;		var->green.offset  = 5;		var->blue.offset   = 0;		var->transp.offset = 0;		break;#ifdef EN_24_32_BPP	case 24:	/* RGB 888 LfbMode 4 */	case 32:	/* ARGB 8888 LfbMode 5 */	       	/* in 24bpp we fake a 32 bpp mode */		var->red.length    = 8;		var->green.length  = 8;		var->blue.length   = 8;		var->transp.length = 0;		var->red.offset    = 16;		var->green.offset  = 8;		var->blue.offset   = 0;		var->transp.offset = 0;		break;#endif	default:		eprintk("bug line %d: bad depth '%u'\n", __LINE__, par->bpp);		break;	}	return 0;}/* * Frame buffer API */static int sstfb_open(struct fb_info *info, int user){	f_dprintk("sstfb_open(user: %d)\n",user);	return 0;}static int sstfb_release(struct fb_info *info, int user){	f_dprintk("sstfb_release(user: %d)\n",user);	return 0;}static int sstfb_get_fix(struct fb_fix_screeninfo *fix,                         int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	struct fb_var_screeninfo *var;	struct fb_var_screeninfo var2;	f_dprintk("sstfb_get_fix(con: %d)\n",con);	memset(fix, 0, sizeof(struct fb_fix_screeninfo));		if (con == -1) {		sstfb_encode_var(&var2, &sst_info->current_par, sst_info);		var = &var2;	} else		var = &fb_display[con].var;	strcpy(fix->id, sst_info->info.modename);	/* lfb phys address = membase + 4Mb */	fix->smem_start  = sst_info->video.base;	fix->smem_len    = sst_info->video.len;	fix->type        = FB_TYPE_PACKED_PIXELS;	fix->visual      = FB_VISUAL_TRUECOLOR;	fix->accel       = FB_ACCEL_NONE;	/*	 *   According to the specs, the linelength must be of 1024 *pixels*.	 * and the 24bpp mode is in fact a 32 bpp mode.	 */	fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;	return 0;#undef sst_info}static int sstfb_get_var(struct fb_var_screeninfo *var,                         int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	f_dprintk("sstfb_get_var(con: %d)\n",con);	if (con == -1)		sstfb_encode_var(var, &sst_info->current_par, sst_info);	else		*var = fb_display[con].var;	print_var(var, "var");	return 0;#undef sst_info }static int sstfb_set_var(struct fb_var_screeninfo *var,                         int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	struct sstfb_par par;	struct display *display;	int err;	int old_bpp,old_xres,old_yres;	f_dprintk("sstfb_set_var(con: %d)\n",con);	f_ddprintk("xres yres vxres vyres bpp activate\n");	f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8x\n",		 var->xres,var->yres,var->xres_virtual,var->yres_virtual,		 var->bits_per_pixel,var->activate);	if (con < 0)		display = &sst_info->disp;	else		display = &fb_display[con];	if ((err = sstfb_decode_var(var, &par, sst_info)))		return err;	sstfb_encode_var (var, &par, sst_info);	switch (var->activate & FB_ACTIVATE_MASK) {		case FB_ACTIVATE_TEST:			return 0;		case FB_ACTIVATE_NXTOPEN:		case FB_ACTIVATE_NOW:			break;		default:			return -EINVAL;	}	old_xres = display->var.xres;	old_yres = display->var.yres;	old_bpp  = display->var.bits_per_pixel;	display->var = *var;	if ((old_xres != var->xres) || (old_yres != var->yres)	    || (old_bpp != var->bits_per_pixel)) {		/* 2-3  lignes redondantes avec get_fix */		display->screen_base = (char *) sst_info->video.vbase;		display->visual = FB_VISUAL_TRUECOLOR;		display->type = FB_TYPE_PACKED_PIXELS;		display->type_aux = 0;		display->ypanstep = 0;

⌨️ 快捷键说明

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