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

📄 imsttfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{	if (con == currcon)	/* current console? */		return fb_get_cmap(cmap, kspc, imsttfb_getcolreg, info);	else if (fb_display[con].cmap.len)	/* non default colormap? */		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else {		u_int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);	}	return 0;}static intimsttfb_set_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){	int err;	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;		if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))			return err;	}	if (con == currcon)			/* current console? */		return fb_set_cmap(cmap, kspc, imsttfb_setcolreg, info);	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}#define FBIMSTT_SETREG		0x545401#define FBIMSTT_GETREG		0x545402#define FBIMSTT_SETCMAPREG	0x545403#define FBIMSTT_GETCMAPREG	0x545404#define FBIMSTT_SETIDXREG	0x545405#define FBIMSTT_GETIDXREG	0x545406static intimsttfb_ioctl (struct inode *inode, struct file *file, u_int cmd,	       u_long arg, int con, struct fb_info *info){	struct fb_info_imstt *p = (struct fb_info_imstt *)info;	__u8 idx[2];	__u32 reg[2];	switch (cmd) {		case FBIMSTT_SETREG:			if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))				return -EFAULT;			out_le32(&p->dc_regs[reg[0]], reg[1]);			return 0;		case FBIMSTT_GETREG:			if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))				return -EFAULT;			reg[1] = in_le32(&p->dc_regs[reg[0]]);			if (copy_to_user((void *)(arg + 4), &reg[1], 4))				return -EFAULT;			return 0;		case FBIMSTT_SETCMAPREG:			if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))				return -EFAULT;			out_le32(&((u_int *)p->cmap_regs)[reg[0]], reg[1]);			return 0;		case FBIMSTT_GETCMAPREG:			if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))				return -EFAULT;			reg[1] = in_le32(&((u_int *)p->cmap_regs)[reg[0]]);			if (copy_to_user((void *)(arg + 4), &reg[1], 4))				return -EFAULT;			return 0;		case FBIMSTT_SETIDXREG:			if (copy_from_user(idx, (void *)arg, 2))				return -EFAULT;			p->cmap_regs[PIDXHI] = 0;		eieio();			p->cmap_regs[PIDXLO] = idx[0];		eieio();			p->cmap_regs[PIDXDATA] = idx[1];	eieio();			return 0;		case FBIMSTT_GETIDXREG:			if (copy_from_user(idx, (void *)arg, 1))				return -EFAULT;			p->cmap_regs[PIDXHI] = 0;		eieio();			p->cmap_regs[PIDXLO] = idx[0];		eieio();			idx[1] = p->cmap_regs[PIDXDATA];			if (copy_to_user((void *)(arg + 1), &idx[1], 1))				return -EFAULT;			return 0;		default:			return -ENOIOCTLCMD;	}}static struct pci_device_id imsttfb_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT128,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, IBM },	{ PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT3D,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TVP },	{ 0, }};MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl);static struct pci_driver imsttfb_pci_driver = {	name:		"imsttfb",	id_table:	imsttfb_pci_tbl,	probe:		imsttfb_probe,	remove:		__devexit_p(imsttfb_remove),};static struct fb_ops imsttfb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	imsttfb_get_fix,	fb_get_var:	imsttfb_get_var,	fb_set_var:	imsttfb_set_var,	fb_get_cmap:	imsttfb_get_cmap,	fb_set_cmap:	imsttfb_set_cmap,	fb_pan_display:	imsttfb_pan_display,	fb_ioctl:	imsttfb_ioctl,};static intimsttfbcon_switch (int con, struct fb_info *info){	struct fb_info_imstt *p = (struct fb_info_imstt *)info;	struct display *old = &fb_display[currcon], *new = &fb_display[con];	if (old->cmap.len)		fb_get_cmap(&old->cmap, 1, imsttfb_getcolreg, info);	if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor)		old->conp->vc_sw->con_cursor(old->conp, CM_ERASE);	currcon = con;	if (old->var.xres != new->var.xres	    || old->var.yres != new->var.yres	    || old->var.bits_per_pixel != new->var.bits_per_pixel	    || old->var.green.length != new->var.green.length	    || old->var.accel_flags != new->var.accel_flags) {		set_dispsw(new, p);		if (!compute_imstt_regvals(p, new->var.xres, new->var.yres))			return -1;		if (new->var.bits_per_pixel == 16) {			if (new->var.green.length == 6)				set_565(p);			else				set_555(p);		}		set_imstt_regvals(p, new->var.bits_per_pixel);	}	set_offset(new, p);	imsttfbcon_set_font(new, fontwidth(new), fontheight(new));	do_install_cmap(con, info);	return 0;}static intimsttfbcon_updatevar (int con, struct fb_info *info){	struct fb_info_imstt *p = (struct fb_info_imstt *)info;	struct display *disp = &fb_display[con];	if (con != currcon)		goto out;	if (p->ramdac == IBM)		imsttfbcon_cursor(disp, CM_ERASE, p->cursor.x, p->cursor.y);	set_offset(disp, p);out:	return 0;}static voidimsttfbcon_blank (int blank, struct fb_info *info){	struct fb_info_imstt *p = (struct fb_info_imstt *)info;	__u32 ctrl;	ctrl = in_le32(&p->dc_regs[STGCTL]);	if (blank > 0) {		switch (blank - 1) {			case VESA_NO_BLANKING:			case VESA_POWERDOWN:				ctrl &= ~0x00000380;				if (p->ramdac == IBM) {					p->cmap_regs[PIDXHI] = 0;	eieio();					p->cmap_regs[PIDXLO] = MISCTL2;	eieio();					p->cmap_regs[PIDXDATA] = 0x55;	eieio();					p->cmap_regs[PIDXLO] = MISCTL1;	eieio();					p->cmap_regs[PIDXDATA] = 0x11;	eieio();					p->cmap_regs[PIDXLO] = SYNCCTL;	eieio();					p->cmap_regs[PIDXDATA] = 0x0f;	eieio();					p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();					p->cmap_regs[PIDXDATA] = 0x1f;	eieio();					p->cmap_regs[PIDXLO] = CLKCTL;	eieio();					p->cmap_regs[PIDXDATA] = 0xc0;				}				break;			case VESA_VSYNC_SUSPEND:				ctrl &= ~0x00000020;				break;			case VESA_HSYNC_SUSPEND:				ctrl &= ~0x00000010;				break;		}	} else {		if (p->ramdac == IBM) {			ctrl |= 0x000017b0;			p->cmap_regs[PIDXHI] = 0;	eieio();			p->cmap_regs[PIDXLO] = CLKCTL;	eieio();			p->cmap_regs[PIDXDATA] = 0x01;	eieio();			p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();			p->cmap_regs[PIDXDATA] = 0x00;	eieio();			p->cmap_regs[PIDXLO] = SYNCCTL;	eieio();			p->cmap_regs[PIDXDATA] = 0x00;	eieio();			p->cmap_regs[PIDXLO] = MISCTL1;	eieio();			p->cmap_regs[PIDXDATA] = 0x01;	eieio();			p->cmap_regs[PIDXLO] = MISCTL2;	eieio();			p->cmap_regs[PIDXDATA] = 0x45;	eieio();		} else			ctrl |= 0x00001780;	}	out_le32(&p->dc_regs[STGCTL], ctrl);}static void __init init_imstt(struct fb_info_imstt *p){	__u32 i, tmp;	__u32 *ip, *end;	tmp = in_le32(&p->dc_regs[PRC]);	if (p->ramdac == IBM)		p->total_vram = (tmp & 0x0004) ? 0x400000 : 0x200000;	else		p->total_vram = 0x800000;	ip = (__u32 *)p->frame_buffer;	end = (__u32 *)(p->frame_buffer + p->total_vram);	while (ip < end)		*ip++ = 0;	/* initialize the card */	tmp = in_le32(&p->dc_regs[STGCTL]);	out_le32(&p->dc_regs[STGCTL], tmp & ~0x1);	out_le32(&p->dc_regs[SSR], 0);	/* set default values for DAC registers */ 	if (p->ramdac == IBM) {		p->cmap_regs[PPMASK] = 0xff;	eieio();		p->cmap_regs[PIDXHI] = 0;	eieio();		for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) {			p->cmap_regs[PIDXLO] = ibm_initregs[i].addr;	eieio();			p->cmap_regs[PIDXDATA] = ibm_initregs[i].value;	eieio();		}	} else {		for (i = 0; i < sizeof(tvp_initregs) / sizeof(*tvp_initregs); i++) {			p->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;	eieio();			p->cmap_regs[TVPIDATA] = tvp_initregs[i].value;	eieio();		}	}#ifdef CONFIG_ALL_PPC	{		int vmode = init_vmode, cmode = init_cmode;#ifdef CONFIG_NVRAM		/* Attempt to read vmode/cmode from NVRAM */		if (vmode == VMODE_NVRAM)			vmode = nvram_read_byte(NV_VMODE);		if (cmode == CMODE_NVRAM)			cmode = nvram_read_byte(NV_CMODE);#endif		/* If we didn't get something from NVRAM, pick a		 * sane default.		 */		if (vmode <= 0 || vmode > VMODE_MAX)			vmode = VMODE_640_480_67;		if (cmode < CMODE_8 || cmode > CMODE_32)			cmode = CMODE_8;		if (mac_vmode_to_var(vmode, cmode, &p->disp.var)) {			p->disp.var.xres = p->disp.var.xres_virtual = INIT_XRES;			p->disp.var.yres = p->disp.var.yres_virtual = INIT_YRES;			p->disp.var.bits_per_pixel = INIT_BPP;		}	}#else	p->disp.var.xres = p->disp.var.xres_virtual = INIT_XRES;	p->disp.var.yres = p->disp.var.yres_virtual = INIT_YRES;	p->disp.var.bits_per_pixel = INIT_BPP;#endif	if ((p->disp.var.xres * p->disp.var.yres) * (p->disp.var.bits_per_pixel >> 3) > p->total_vram	    || !(compute_imstt_regvals(p, p->disp.var.xres, p->disp.var.yres))) {		printk("imsttfb: %ux%ux%u not supported\n", p->disp.var.xres, p->disp.var.yres, p->disp.var.bits_per_pixel);		kfree(p);		return;	}	sprintf(p->fix.id, "IMS TT (%s)", p->ramdac == IBM ? "IBM" : "TVP");	p->fix.smem_start = p->frame_buffer_phys;	p->fix.smem_len = p->total_vram;	p->fix.mmio_start = p->dc_regs_phys;	p->fix.mmio_len = 0x1000;	p->fix.accel = FB_ACCEL_IMS_TWINTURBO;	p->fix.type = FB_TYPE_PACKED_PIXELS;	p->fix.visual = p->disp.var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR							: FB_VISUAL_DIRECTCOLOR;	p->fix.line_length = p->disp.var.xres * (p->disp.var.bits_per_pixel >> 3);	p->fix.xpanstep = 8;	p->fix.ypanstep = 1;	p->fix.ywrapstep = 0;	p->disp.var.accel_flags = noaccel ? 0 : FB_ACCELF_TEXT;	set_disp(&p->disp, p);	if (!noaccel && p->ramdac == IBM)		imstt_cursor_init(p);	if (p->disp.var.green.length == 6)		set_565(p);	else		set_555(p);	set_imstt_regvals(p, p->disp.var.bits_per_pixel);	p->disp.var.pixclock = 1000000 / getclkMHz(p);	strcpy(p->info.modename, p->fix.id);	strcpy(p->info.fontname, fontname);	p->info.node = -1;	p->info.fbops = &imsttfb_ops;	p->info.disp = &p->disp;	p->info.changevar = 0;	p->info.switch_con = &imsttfbcon_switch;	p->info.updatevar = &imsttfbcon_updatevar;	p->info.blank = &imsttfbcon_blank;	p->info.flags = FBINFO_FLAG_DEFAULT;	for (i = 0; i < 16; i++) {		u_int j = color_table[i];		p->palette[i].red = default_red[j];		p->palette[i].green = default_grn[j];		p->palette[i].blue = default_blu[j];	}	if (register_framebuffer(&p->info) < 0) {		kfree(p);		return;	}	i = GET_FB_IDX(p->info.node);	tmp = (in_le32(&p->dc_regs[SSTATUS]) & 0x0f00) >> 8;	printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",		i, p->fix.id, p->total_vram >> 20, tmp);#ifdef CONFIG_FB_COMPAT_XPMAC	strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));	display_info.fb_address = p->frame_buffer_phys;	display_info.cmap_adr_address = p->cmap_regs_phys + PADDRW;	display_info.cmap_data_address = p->cmap_regs_phys + PDATA;	display_info.disp_reg_address = p->dc_regs_phys;	if (!console_fb_info)		console_fb_info = &p->info;#endif /* CONFIG_FB_COMPAT_XPMAC */}static int __devinitimsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent){	struct fb_info_imstt *p;	unsigned long addr, size;	addr = pci_resource_start (pdev, 0);	size = pci_resource_len (pdev, 0);	p = kmalloc(sizeof(struct fb_info_imstt), GFP_KERNEL);	if (!p) {		printk(KERN_ERR "imsttfb: Can't allocate memory\n");		return -ENOMEM;	}	memset(p, 0, sizeof(struct fb_info_imstt));	if (!request_mem_region(addr, size, "imsttfb")) {		printk(KERN_ERR "imsttfb: Can't reserve memory region\n");		kfree(p);		return -ENODEV;	}	switch (pdev->device) {		case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */			p->ramdac = IBM;			break;		case PCI_DEVICE_ID_IMS_TT3D:  /* IMS,tt3d */			p->ramdac = TVP;			break;		default:			printk(KERN_INFO "imsttfb: Device 0x%lx unknown, "					 "contact maintainer.\n", pdev->device);			return -ENODEV;	}	p->frame_buffer_phys = addr;	p->board_size = size;	p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);	p->dc_regs_phys = addr + 0x800000;	p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);	p->cmap_regs_phys = addr + 0x840000;	p->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);	init_imstt(p);	pci_set_drvdata(pdev, p);	return 0;}static void __devexitimsttfb_remove(struct pci_dev *pdev){	struct fb_info_imstt *p = pci_get_drvdata(pdev);	unregister_framebuffer(&p->info);	iounmap(p->cmap_regs);	iounmap(p->dc_regs);	iounmap(p->frame_buffer);	release_mem_region(p->frame_buffer_phys, p->board_size);	kfree(p);}#ifndef MODULEint __init imsttfb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "font:", 5)) {			char *p;			int i;			p = this_opt + 5;			for (i = 0; i < sizeof(fontname) - 1; i++)				if (!*p || *p == ' ' || *p == ',')					break;			memcpy(fontname, this_opt + 5, i);			fontname[i] = 0;		} else if (!strncmp(this_opt, "noblink", 7)) {			curblink = 0;		} else if (!strncmp(this_opt, "noaccel", 7)) {			noaccel = 1;		} else if (!strncmp(this_opt, "inverse", 7)) {			inverse = 1;			fb_invert_cmaps();		}#if defined(CONFIG_PPC)		else if (!strncmp(this_opt, "vmode:", 6)) {			int vmode = simple_strtoul(this_opt+6, NULL, 0);			if (vmode > 0 && vmode <= VMODE_MAX)				init_vmode = vmode;		} else if (!strncmp(this_opt, "cmode:", 6)) {			int cmode = simple_strtoul(this_opt+6, NULL, 0);			switch (cmode) {				case CMODE_8:				case 8:					init_cmode = CMODE_8;					break;				case CMODE_16:				case 15:				case 16:					init_cmode = CMODE_16;					break;				case CMODE_32:				case 24:				case 32:					init_cmode = CMODE_32;					break;			}		}#endif	}	return 0;}#endif /* MODULE */int __init imsttfb_init(void){	return pci_module_init(&imsttfb_pci_driver);} static void __exit imsttfb_exit(void){	pci_unregister_driver(&imsttfb_pci_driver);}#ifdef MODULEMODULE_LICENSE("GPL");module_init(imsttfb_init);#endifmodule_exit(imsttfb_exit);

⌨️ 快捷键说明

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