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

📄 chipsfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  drivers/video/chipsfb.c -- frame buffer device for *  Chips & Technologies 65550 chip. * *  Copyright (C) 1998 Paul Mackerras * *  This file is derived from the Powermac "chips" driver: *  Copyright (C) 1997 Fabio Riccardi. *  And from the frame buffer device for Open Firmware-initialized devices: *  Copyright (C) 1997 Geert Uytterhoeven. * *  This file is subject to the terms and conditions of the GNU General Public *  License. See the file COPYING in the main directory of this archive for *  more details. */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/selection.h>#include <linux/init.h>#include <linux/pci.h>#include <asm/io.h>#ifdef CONFIG_FB_COMPAT_XPMAC#include <asm/vc_ioctl.h>#include <asm/pci-bridge.h>#endif#ifdef CONFIG_PMAC_BACKLIGHT#include <asm/backlight.h>#endif#ifdef CONFIG_PMAC_PBOOK#include <linux/adb.h>#include <linux/pmu.h>#endif#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/macmodes.h>static int currcon = 0;struct fb_info_chips {	struct fb_info info;	struct fb_fix_screeninfo fix;	struct fb_var_screeninfo var;	struct display disp;	struct {		__u8 red, green, blue;	} palette[256];	struct pci_dev *pdev;	unsigned long frame_buffer_phys;	__u8 *frame_buffer;	unsigned long blitter_regs_phys;	__u32 *blitter_regs;	unsigned long blitter_data_phys;	__u8 *blitter_data;	struct fb_info_chips *next;#ifdef CONFIG_PMAC_PBOOK	unsigned char *save_framebuffer;#endif#ifdef FBCON_HAS_CFB16	u16 fbcon_cfb16_cmap[16];#endif};#define write_ind(num, val, ap, dp)	do { \	outb((num), (ap)); outb((val), (dp)); \} while (0)#define read_ind(num, var, ap, dp)	do { \	outb((num), (ap)); var = inb((dp)); \} while (0)/* extension registers */#define write_xr(num, val)	write_ind(num, val, 0x3d6, 0x3d7)#define read_xr(num, var)	read_ind(num, var, 0x3d6, 0x3d7)/* flat panel registers */#define write_fr(num, val)	write_ind(num, val, 0x3d0, 0x3d1)#define read_fr(num, var)	read_ind(num, var, 0x3d0, 0x3d1)/* CRTC registers */#define write_cr(num, val)	write_ind(num, val, 0x3d4, 0x3d5)#define read_cr(num, var)	read_ind(num, var, 0x3d4, 0x3d5)/* graphics registers */#define write_gr(num, val)	write_ind(num, val, 0x3ce, 0x3cf)#define read_gr(num, var)	read_ind(num, var, 0x3ce, 0x3cf)/* sequencer registers */#define write_sr(num, val)	write_ind(num, val, 0x3c4, 0x3c5)#define read_sr(num, var)	read_ind(num, var, 0x3c4, 0x3c5)/* attribute registers - slightly strange */#define write_ar(num, val)	do { \	inb(0x3da); write_ind(num, val, 0x3c0, 0x3c0); \} while (0)#define read_ar(num, var)	do { \	inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \} while (0)static struct fb_info_chips *all_chips;#ifdef CONFIG_PMAC_PBOOKint chips_sleep_notify(struct pmu_sleep_notifier *self, int when);static struct pmu_sleep_notifier chips_sleep_notifier = {	chips_sleep_notify, SLEEP_LEVEL_VIDEO,};#endif/* * Exported functions */int chips_init(void);static void chips_pci_init(struct pci_dev *dp);static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info);static int chips_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info);static int chips_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info);static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info);static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info);static struct fb_ops chipsfb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	chips_get_fix,	fb_get_var:	chips_get_var,	fb_set_var:	chips_set_var,	fb_get_cmap:	chips_get_cmap,	fb_set_cmap:	chips_set_cmap,};static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,			     u_int *blue, u_int *transp, struct fb_info *info);static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,			     u_int transp, struct fb_info *info);static void do_install_cmap(int con, struct fb_info *info);static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info){	struct fb_info_chips *cp = (struct fb_info_chips *) info;	*fix = cp->fix;	return 0;}static int chips_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	struct fb_info_chips *cp = (struct fb_info_chips *) info;	*var = cp->var;	return 0;}static int chips_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	struct fb_info_chips *cp = (struct fb_info_chips *) info;	struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;	if (var->xres > 800 || var->yres > 600	    || var->xres_virtual > 800 || var->yres_virtual > 600	    || (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)	    || var->nonstd	    || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)		return -EINVAL;	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&		var->bits_per_pixel != disp->var.bits_per_pixel) {		chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);	}	return 0;}static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info){	if (con == currcon)		/* current console? */		return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info);	if (fb_display[con].cmap.len)	/* non default colormap? */		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else {		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 int chips_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, chipsfb_setcolreg, info);	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}static int chipsfbcon_switch(int con, struct fb_info *info){	struct fb_info_chips *p = (struct fb_info_chips *) info;	int new_bpp, old_bpp;	/* Do we have to save the colormap? */	if (fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, chipsfb_getcolreg, info);	new_bpp = fb_display[con].var.bits_per_pixel;	old_bpp = fb_display[currcon].var.bits_per_pixel;	currcon = con;	if (new_bpp != old_bpp)		chips_set_bitdepth(p, &fb_display[con], con, new_bpp);		do_install_cmap(con, info);	return 0;}static int chipsfb_updatevar(int con, struct fb_info *info){	return 0;}static void chipsfb_blank(int blank, struct fb_info *info){	struct fb_info_chips *p = (struct fb_info_chips *) info;	int i;	// used to disable backlight only for blank > 1, but it seems	// useful at blank = 1 too (saves battery, extends backlight life)	if (blank) {#ifdef CONFIG_PMAC_BACKLIGHT		set_backlight_enable(0);#endif /* CONFIG_PMAC_BACKLIGHT */		/* get the palette from the chip */		for (i = 0; i < 256; ++i) {			outb(i, 0x3c7);			udelay(1);			p->palette[i].red = inb(0x3c9);			p->palette[i].green = inb(0x3c9);			p->palette[i].blue = inb(0x3c9);		}		for (i = 0; i < 256; ++i) {			outb(i, 0x3c8);			udelay(1);			outb(0, 0x3c9);			outb(0, 0x3c9);			outb(0, 0x3c9);		}	} else {#ifdef CONFIG_PMAC_BACKLIGHT		set_backlight_enable(1);#endif /* CONFIG_PMAC_BACKLIGHT */		for (i = 0; i < 256; ++i) {			outb(i, 0x3c8);			udelay(1);			outb(p->palette[i].red, 0x3c9);			outb(p->palette[i].green, 0x3c9);			outb(p->palette[i].blue, 0x3c9);		}	}}static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,			     u_int *blue, u_int *transp, struct fb_info *info){	struct fb_info_chips *p = (struct fb_info_chips *) info;	if (regno > 255)		return 1;	*red = (p->palette[regno].red<<8) | p->palette[regno].red;	*green = (p->palette[regno].green<<8) | p->palette[regno].green;	*blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;	*transp = 0;	return 0;}static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,			     u_int transp, struct fb_info *info){	struct fb_info_chips *p = (struct fb_info_chips *) info;	if (regno > 255)		return 1;	red >>= 8;	green >>= 8;	blue >>= 8;	p->palette[regno].red = red;	p->palette[regno].green = green;	p->palette[regno].blue = blue;	outb(regno, 0x3c8);	udelay(1);	outb(red, 0x3c9);	outb(green, 0x3c9);	outb(blue, 0x3c9);#ifdef FBCON_HAS_CFB16	if (regno < 16)		p->fbcon_cfb16_cmap[regno] = ((red & 0xf8) << 7)			| ((green & 0xf8) << 2) | ((blue & 0xf8) >> 3);#endif	return 0;}static void do_install_cmap(int con, struct fb_info *info){	if (con != currcon)		return;	if (fb_display[con].cmap.len)		fb_set_cmap(&fb_display[con].cmap, 1, chipsfb_setcolreg, info);	else {		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;		fb_set_cmap(fb_default_cmap(size), 1, chipsfb_setcolreg, info);	}}static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp){	int err;	struct fb_fix_screeninfo* fix = &p->fix;	struct fb_var_screeninfo* var = &p->var;		if (bpp == 16) {		if (con == currcon) {			write_cr(0x13, 200);		// Set line length (doublewords)			write_xr(0x81, 0x14);		// 15 bit (555) color mode			write_xr(0x82, 0x00);		// Disable palettes			write_xr(0x20, 0x10);		// 16 bit blitter mode		}		fix->line_length = 800*2;		fix->visual = FB_VISUAL_TRUECOLOR;		var->red.offset = 10;		var->green.offset = 5;		var->blue.offset = 0;		var->red.length = var->green.length = var->blue.length = 5;		#ifdef FBCON_HAS_CFB16		disp->dispsw = &fbcon_cfb16;		disp->dispsw_data = p->fbcon_cfb16_cmap;#else		disp->dispsw = &fbcon_dummy;#endif	} else if (bpp == 8) {		if (con == currcon) {			write_cr(0x13, 100);		// Set line length (doublewords)			write_xr(0x81, 0x12);		// 8 bit color mode			write_xr(0x82, 0x08);		// Graphics gamma enable			write_xr(0x20, 0x00);		// 8 bit blitter mode		}

⌨️ 快捷键说明

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