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

📄 epson1356fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	writew(addr_offset, &dispmode->mem_addr_offset0);	writeb(0, &dispmode->pixel_panning);	// reset BitBlt engine	e1356fb_engine_init(par, info);#ifdef E1356FB_VERBOSE_DEBUG	dump_display_regs(dispcfg, dispmode);#endif	/* clear out framebuffer memory */	fbfill(fb_info.membase_virt, 0, fb_info.fb_size);	// finally, enable display!	writeb(main_display_mode, &info->reg.misc->disp_mode); }static inte1356fb_verify_timing(struct e1356fb_par* par,		      const struct fb_info_e1356* info){	int disp_type = info->fix.disp_type;	// timing boundary checks	if (par->horiz_ndp > max_hndp[disp_type]) {		DPRINTK("horiz_ndp too big: %d\n", par->horiz_ndp);		return -EINVAL;	}	if (par->vert_ndp > max_vndp[disp_type]) {		DPRINTK("vert_ndp too big: %d\n", par->vert_ndp);		return -EINVAL;	}	if (disp_type != DISP_TYPE_LCD) {		if (par->hsync_start >		    max_hsync_start[(par->bpp==16)][disp_type]) {			DPRINTK("hsync_start too big: %d\n",				par->hsync_start);			return -EINVAL;		}		if (par->vsync_start > max_vsync_start[disp_type]) {			DPRINTK("vsync_start too big: %d\n",				par->vsync_start);			return -EINVAL;		}		if (!IS_TV(disp_type)) {			if (par->hsync_width > max_hsync_width[disp_type]) {				DPRINTK("hsync_width too big: %d\n",					par->hsync_width);				return -EINVAL;			}			if (par->vsync_width > max_vsync_width[disp_type]) {				DPRINTK("vsync_width too big: %d\n",					par->vsync_width);				return -EINVAL;			}		}	}	if (IS_TV(disp_type)) {		int tv_pixclk = (disp_type == DISP_TYPE_NTSC) ?			NTSC_PIXCLOCK : PAL_PIXCLOCK;		if (info->fix.tv_filt & TV_FILT_FLICKER)			tv_pixclk *= 2;				if (par->ipclk.pixclk_d != tv_pixclk) {			DPRINTK("invalid TV pixel clock %u kHz\n",				par->ipclk.pixclk_d);			return -EINVAL;		}	}		if (e1356_calc_pixclock(info, &par->ipclk) < 0) {		DPRINTK("can't set pixel clock %u kHz\n",			par->ipclk.pixclk_d);		return -EINVAL;	} #ifdef E1356FB_VERBOSE_DEBUG	DPRINTK("desired pixclock = %d kHz, actual = %d kHz, error = %d%%\n",		par->ipclk.pixclk_d, par->ipclk.pixclk, par->ipclk.error);#endif    	if (disp_type != DISP_TYPE_LCD) {		if (par->horiz_ndp < par->hsync_start + par->hsync_width) {			DPRINTK("invalid horiz. timing\n");			return -EINVAL;		}		if (par->vert_ndp < par->vsync_start + par->vsync_width) {			DPRINTK("invalid vert. timing\n");			return -EINVAL;		}		// SED1356 Hardware Functional Spec, section 13.5		if (disp_type == DISP_TYPE_NTSC &&		    ((par->width + par->horiz_ndp != 910) ||		     (par->height + 2*par->vert_ndp+1 != 525))) {			DPRINTK("invalid NTSC timing\n");			return -EINVAL;		} else if (disp_type == DISP_TYPE_PAL &&			   ((par->width + par->horiz_ndp != 1135) ||			    (par->height + 2*par->vert_ndp+1 != 625))) {			DPRINTK("invalid PAL timing\n");			return -EINVAL;		}	}    	par->hsync_freq = (1000 * par->ipclk.pixclk) /		(par->width + par->horiz_ndp);	par->vsync_freq = par->hsync_freq / (par->height + par->vert_ndp);		if (par->hsync_freq < 30000 || par->hsync_freq > 90000) {		DPRINTK("hsync freq too %s: %u Hz\n",			par->hsync_freq < 30000 ? "low" : "high",			par->hsync_freq);		return -EINVAL;	}	if (par->vsync_freq < 50 || par->vsync_freq > 110) {		DPRINTK("vsync freq too %s: %u Hz\n",			par->vsync_freq < 50 ? "low" : "high",			par->vsync_freq);		return -EINVAL;	}	return 0;}static inte1356fb_verify_par(struct e1356fb_par* par,		   const struct fb_info_e1356* info){	int disp_type = info->fix.disp_type;    	if (par->bpp != 8 && par->bpp != 16) {		DPRINTK("depth not supported: %u bpp\n", par->bpp);		return -EINVAL;	}	if (par->width > par->width_virt) {		DPRINTK("virtual x resolution < physical x resolution not possible\n");		return -EINVAL;	}	if (par->height > par->height_virt) {		DPRINTK("virtual y resolution < physical y resolution not possible\n");		return -EINVAL;	}	if (par->width < 320 || par->width > 1024) {		DPRINTK("width not supported: %u\n", par->width);		return -EINVAL;	}	if ((disp_type == DISP_TYPE_LCD && (par->width % 16)) ||	    (disp_type == DISP_TYPE_TFT && (par->width % 8))) {		DPRINTK("invalid width for panel type: %u\n", par->width);		return -EINVAL;	}	if (par->height < 200 || par->height > 1024) {		DPRINTK("height not supported: %u\n", par->height);		return -EINVAL;	}	if (par->width_virt * par->height_virt * par->Bpp >	    info->fb_size) {		DPRINTK("not enough memory for virtual screen (%ux%ux%u)\n",			par->width_virt, par->height_virt, par->bpp);		return -EINVAL;	}	return e1356fb_verify_timing(par, info);}static inte1356fb_var_to_par(const struct fb_var_screeninfo* var,		   struct e1356fb_par* par,		   const struct fb_info_e1356* info){	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		DPRINTK("interlace not supported\n");		return -EINVAL;	}	memset(par, 0, sizeof(struct e1356fb_par));	par->width       = (var->xres + 15) & ~15; /* could sometimes be 8 */	par->width_virt  = var->xres_virtual;	par->height      = var->yres;	par->height_virt = var->yres_virtual;	par->bpp         = var->bits_per_pixel;	par->Bpp         = (par->bpp + 7) >> 3;	par->ipclk.pixclk_d = PICOS2KHZ(var->pixclock);	par->hsync_start = var->right_margin;	par->hsync_width = var->hsync_len;	par->vsync_start = var->lower_margin;	par->vsync_width = var->vsync_len;	par->horiz_ndp = var->left_margin + var->right_margin + var->hsync_len;	par->vert_ndp = var->upper_margin + var->lower_margin + var->vsync_len;	par->hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0;	par->vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0;	par->cmap_len  = (par->bpp == 8) ? 256 : 16;	return e1356fb_verify_par(par, info);}static inte1356fb_par_to_var(struct fb_var_screeninfo* var,		   struct e1356fb_par* par,		   const struct fb_info_e1356* info){	struct fb_var_screeninfo v;	int ret;    	// First, make sure par is valid.	if ((ret = e1356fb_verify_par(par, info)))		return ret;	memset(&v, 0, sizeof(struct fb_var_screeninfo));	v.xres_virtual   = par->width_virt;	v.yres_virtual   = par->height_virt;	v.xres           = par->width;	v.yres           = par->height;	v.right_margin   = par->hsync_start;	v.hsync_len      = par->hsync_width;	v.left_margin    = par->horiz_ndp - par->hsync_start - par->hsync_width;	v.lower_margin   = par->vsync_start;	v.vsync_len      = par->vsync_width;	v.upper_margin   = par->vert_ndp - par->vsync_start - par->vsync_width;	v.bits_per_pixel = par->bpp;	switch(par->bpp) {	case 8:		v.red.offset = v.green.offset = v.blue.offset = 0;		v.red.length = v.green.length = v.blue.length = 4;		break;	case 16:		v.red.offset   = 11;		v.red.length   = 5;		v.green.offset = 5;		v.green.length = 6;		v.blue.offset  = 0;		v.blue.length  = 5;		break;	}	v.height = v.width = -1;	v.pixclock = KHZ2PICOS(par->ipclk.pixclk);	if (par->hsync_pol)		v.sync |= FB_SYNC_HOR_HIGH_ACT;	if (par->vsync_pol)		v.sync |= FB_SYNC_VERT_HIGH_ACT;	*var = v;	return 0;}static inte1356fb_encode_fix(struct fb_fix_screeninfo*  fix,		   const struct e1356fb_par*   par,		   const struct fb_info_e1356* info){	memset(fix, 0, sizeof(struct fb_fix_screeninfo));    	strcpy(fix->id, "Epson SED1356");	fix->smem_start  = info->fix.membase_phys;	fix->smem_len    = info->fb_size;	fix->mmio_start  = info->fix.regbase_phys;	fix->mmio_len    = info->regbase_size;	fix->accel       = FB_ACCEL_EPSON_SED1356;	fix->type        = FB_TYPE_PACKED_PIXELS;	fix->type_aux    = 0;	fix->line_length = par->width_virt * par->Bpp;	fix->visual      =		(par->bpp == 8) ? FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;    	fix->xpanstep    = info->fix.nopan ? 0 : 1;	fix->ypanstep    = info->fix.nopan ? 0 : 1;	fix->ywrapstep   = 0;    	return 0;}static int e1356fb_open(struct fb_info *fb, int user){	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;        if (user) {                info->open++;	}	MOD_INC_USE_COUNT;	return 0;}static int e1356fb_release(struct fb_info *fb, int user){	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;        if (user && info->open) {                info->open--;		if (info->open == 0)                        info->mmaped = 0;	}	MOD_DEC_USE_COUNT;	return 0;}static inte1356fb_get_fix(struct fb_fix_screeninfo *fix, 		int con,		struct fb_info *fb){	const struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;	struct e1356fb_par par;	//DPRINTK("\n");	if (con == -1)		par = info->current_par;	else		e1356fb_var_to_par(&fb_display[con].var, &par, info);	e1356fb_encode_fix(fix, &par, info);	return 0;}static inte1356fb_get_var(struct fb_var_screeninfo *var, 		int con,		struct fb_info *fb){	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;	//DPRINTK("\n");	if (con == -1)		e1356fb_par_to_var(var, &info->current_par, info);	else		*var = fb_display[con].var;	return 0;} static voide1356fb_set_dispsw(struct display *disp, 		   struct fb_info_e1356 *info,		   int bpp, 		   int accel){	struct e1356fb_fix* fix = &info->fix;	//DPRINTK("\n");	if (disp->dispsw && disp->conp) 		fb_con.con_cursor(disp->conp, CM_ERASE);	switch (bpp) {#ifdef FBCON_HAS_CFB8	case 8:		disp->dispsw = fix->noaccel ? &fbcon_cfb8 : &fbcon_e1356_8;		if (fix->nohwcursor)			fbcon_e1356_8.cursor = NULL;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		disp->dispsw = fix->noaccel ? &fbcon_cfb16 : &fbcon_e1356_16;		disp->dispsw_data = info->fbcon_cmap16;		if (fix->nohwcursor)			fbcon_e1356_16.cursor = NULL;		break;#endif	default:		disp->dispsw = &fbcon_dummy;	}   }static inte1356fb_set_var(struct fb_var_screeninfo *var, 		int con,		struct fb_info *fb){	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;	struct e1356fb_par par;	struct display *display;	int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;	int activate = var->activate;	int j,k;    	DPRINTK("\n");		if (con >= 0)		display = &fb_display[con];	else		display = fb->disp;	/* used during initialization */   	if ((err = e1356fb_var_to_par(var, &par, info))) {		struct fb_videomode *dm;		/*		 * this mode didn't pass the tests. Try the		 * corresponding mode from our own modedb.		 */		DPRINTK("req mode failed, trying SED1356 %dx%d mode\n",			var->xres, var->yres);		if (e1356fb_get_mode(info, var->xres,				     var->yres, NULL, &dm) < 0) {			DPRINTK("no SED1356 %dx%d mode found, failed\n",				var->xres, var->yres);			return err;		}		fb_videomode_to_var(dm, var);		if ((err = e1356fb_var_to_par(var, &par, info))) {			DPRINTK("SED1356 %dx%d mode failed\n",				var->xres, var->yres);			return err;		}	}		if (info->fix.tv_filt & TV_FILT_FLICKER)		printk("e1356fb: TV flicker filter enabled\n");    	e1356fb_par_to_var(var, &par, info);   	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {		oldxres  = display->var.xres;		oldyres  = display->var.yres;		oldvxres = display->var.xres_virtual;		oldvyres = display->var.yres_virtual;		oldbpp   = display->var.bits_per_pixel;		oldaccel = display->var.accel_flags;		display->var = *var;		if (con < 0                         ||		    oldxres  != var->xres           || 		    oldyres  != var->yres           ||		    oldvxres != var->xres_virtual   || 		    oldvyres != var->yres_virtual   ||		    oldbpp   != var->bits_per_pixel || 		    oldaccel != var->accel_flags) {			struct fb_fix_screeninfo fix;	    			e1356fb_encode_fix(&fix, &par, info);			display->screen_base    = info->membase_virt;			display->visual         = fix.visual;			display->type           = fix.type;			display->type_aux       = fix.type_aux;			display->ypanstep       = fix.ypanstep;			display->ywrapstep      = fix.ywrapstep;			display->line_length    = fix.line_length;			display->next_line      = fix.line_length;			display->can_soft_blank = 1;			display->inverse        = 0;			accel = var->accel_flags & FB_ACCELF_TEXT;			e1356fb_set_dispsw(display, info, par.bpp, accel);	 			if (info->fix.nopan)				display->scrollmode = SCROLL_YREDRAW;				if (info->fb_info.changevar)				(*info->fb_info.changevar)(con);		}		if (var->bits_per_pixel==8)			for(j = 0; j < 16; j++) {				k = color_table[j];				fb_info.palette[j].red   = default_red[k];				fb_info.palette[j].green = default_grn[k];				fb_info.palette[j].blue  = default_blu[k];			}      		del_timer(&(info->cursor.timer)); 		fb_info.cursor.state=CM_ERASE;			if (!info->fb_info.display_fg ||		    info->fb_info.display_fg->vc_num == con || con < 0)			e1356fb_set_par(&par, info);		if (!info->fix.nohwcursor) 			if (display && display->conp)				e1356fb_createcursor( display );		info->cursor.redraw = 1;		if (oldbpp != var->bits_per_pixel || con < 0) {			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))				return err;

⌨️ 快捷键说明

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