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

📄 s3c44b0xfb.c

📁 uclinux上的frame buffer driver for s3c44b0x LCD(16级灰度)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/drivers/video/s3c44b0xfb.c  * * Copyright (C) 2003 Stefan Macher <macher@sympat.de> *                    Alexander Assel <assel@sympat.de> * * 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. *//* TODO (roughly in order of priority): * color gray / (monochrom) 2 bpp (8 bpp color) * configuration via modul parameters and i/o control */#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/delay.h>#include <linux/fb.h>#include <linux/init.h>#include "linux/config.h"#include <video/fbcon.h>//#include <video/fbcon-cfb4.h> /* add -- luzhl */#include "s3c44b0xfb.h"#include "asm-armnommu/arch-S3C44B0X/s3c44b0x.h"/*---------------------------------*//* global parameters               *//*---------------------------------*/static int s3c44b0x_lcd_index; /*!< index within panels; will be set according to panel_name */#if MODULE /* in case of module the panel name is set as module parameter */static u8 panel_valid = 0;static unsigned char *panel_name = NULL;#else /* FIXME this should be similar to module but as linux boot line parameter */static u8 panel_valid = 1;static unsigned char *panel_name = "LCDBA7T11M4_320x240x4"; /* mod -- luzhl */#endifstatic u8 bootloader = 0; /* use bootloader settings for LCD controller setup */static struct fb_ops s3c44b0xfb_ops;struct fbgen_hwswitch s3c44b0xfb_switch;/*---------------------------------*//* parameter decleration           *//*---------------------------------*/#if MODULEMODULE_PARM(panel_name, "s");MODULE_PARM_DESC(panel_name, "Name of the connected panel\nknown panels are: LCDBA7T11M4_320x240x8");MODULE_PARM(bootloader, "b");MODULE_PARM_DESC(bootloader, "Set it to 1 if you want the device driver to use the parameters that has the bootloader configured\n");MODULE_AUTHOR("Alexander Assel  <asselv@sympat.de> Stefan Macher <macher@sympat.de>");MODULE_DESCRIPTION("S3C44B0X LCD framebuffer device driver");#endif/*--------------------------------*//************************************** * definition of the known displays **************************************//* if you add some new panels in the struct bellow change also the   module description on the end of this file*/struct known_lcd_panels panels[] = { {	/* holds the lcd panel name */	"LCDBA7T11M4_320x240x4", /* mod -- luzhl */	/* clkval */	3, /* mod -- luzhl */ /* FIXME this is based on a cpu clock of 60,75 MHz */	/* Determine the VLINE pulses high level width [clocks] valid values 4, 8, 12 and 16 */	16,	/* Determine the delay between VLINE and VCLOCK [clocks] valid values 4, 8, 12 and 16 */	16,	/* Determine toggle rate of VM 0 -> each frame 1 -> defined by MVAL */	0,	/* display mode is 8 bit single scan */	1, /* mod -- luzhl */       /* controls the poloarity of VCLOCK active edge 0 -> falling edge 1 -> rising edge */	0,	/* indicate the line pulse polarity 0 -> normal 1 -> inverted */	0,	/* indicate the frame pulse polarity 0 -> normal 1 -> inverted */	0,	/* indicates the video data polarity 0 -> normal 1 -> inverted */	0,	/* indicates the blank time in one horizontal line duration */	10,	/* LCD self refrash mode enable */	0,	/* byte swap control */#ifdef CONFIG_CPU_BIG_ENDIAN	0,#else		1,#endif  /* defines the rate at which the vm signal will toggle */	0x0D,   /* display width in pixels */	320,  /* display height in pixels */	240,  /* bits per pixel valid is 1 (mono), 2 (gray), 4 (gray) and 8 (color) */	4, /* mod -- luzhl */	79, /* mod -- luzhl */ /* hozval */	239, /* lineval */	S3C44B0X_PDATC, /* port register for enabling the display */	(1<<8), /* mask port c pin 8 */	(1<<8), /* set port c pin 8 to high */	S3C44B0X_PCONC, /* port control register for setting PORTC.8 to output */	(3<<16), /* mask port c pin8 control */	(1<<16) /* set port c pin 8 control to output */}}; static struct s3c44b0xfb_info fb_info;static struct s3c44b0xfb_par current_par;static int current_par_valid = 0;static struct display disp; /* add -- luzhl */int s3c44b0xfb_init(void);int s3c44b0xfb_setup(char*);/* ------------------- chipset specific functions -------------------------- */static void s3c44b0xfb_detect(void){        /*	 * Yeh, well, we're not going to change any settings so we're	 * always stuck with the default ...	 */}static int s3c44b0xfb_encode_fix(struct fb_fix_screeninfo *fix, const void *_par,			       struct fb_info_gen *_info){    /*     *  This function should fill in the 'fix' structure based on the values     *  in the `par' structure.     */	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;        struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par *) _par;	struct fb_var_screeninfo *var = &par->var;	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	fix->smem_start = info->fb_phys;	fix->smem_len = info->fb_size;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;        fix->visual = (var->bits_per_pixel == 1) ?	       	FB_VISUAL_MONO01 : FB_VISUAL_PSEUDOCOLOR; /* mod -- luzhl */ /* FB_VISUAL_TRUECOLOR; */	fix->ywrapstep = 0;	fix->xpanstep = 0;	fix->ypanstep = 0;	fix->line_length = current_par.line_length;	return 0;}static int s3c44b0xfb_decode_var(const struct fb_var_screeninfo *var, void *par,			       struct fb_info_gen *info){    /*     *  Get the video params out of 'var'. If a value doesn't fit, round it up,     *  if it's too big, return -EINVAL.     *     *  Suggestion: Round up in the following order: bits_per_pixel, xres,     *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,     *  bitfields, horizontal timing, vertical timing.     */	struct known_lcd_panels *p_lcd = &panels[s3c44b0x_lcd_index];	if (var->xres != p_lcd->width ||	    var->yres != p_lcd->height)	{		return -EINVAL;	}	if(var->bits_per_pixel != p_lcd->bpp) 	{		return -EINVAL;	}	return 0;}static int s3c44b0xfb_encode_var(struct fb_var_screeninfo *var, const void *_par,			       struct fb_info_gen *info){    /*     *  Fill the 'var' structure based on the values in 'par' and maybe other     *  values read out of the hardware.     */	struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par*)_par;	memcpy(var, &par->var, sizeof(struct fb_var_screeninfo));   	return 0;}static void s3c44b0xfb_get_par(void *_par, struct fb_info_gen *info){	/*	 *  Fill the hardware's 'par' structure.	 */		struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par*)_par;	if (current_par_valid)		memcpy(par, &current_par, sizeof(struct s3c44b0xfb_par));}static void s3c44b0xfb_set_par(const void *par, struct fb_info_gen *info){    /*     *  Set the hardware according to 'par'.     */    /* nothing to do: we don't change any settings */  }static int s3c44b0xfb_getcolreg(unsigned regno, unsigned *red, unsigned *green,			 unsigned *blue, unsigned *transp,			 struct fb_info *_info){    /*     *  Read a single color register and split it into colors/transparent.     *  The return values must have a 16 bit magnitude.     *  Return != 0 for invalid regno.     */	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;	u32 blueval, redval, greenval;	u8 helpvalue;	blueval = inw(S3C44B0X_BLUELUT);	redval = inw(S3C44B0X_REDLUT);	greenval = inw(S3C44B0X_GREENLUT);	switch(info->gen.info.var.bits_per_pixel)	{	case 1:		if(regno > 1)			return 1; /* error */		if(regno == 0)			*red = *green = *blue = 0;		else			*red = *green = *blue = 0xFFFF;		break;	case 2:		if(regno > 4)			return 1; /* error */			blueval = (blueval >> (regno<<2)) & 0xF;		*red = *green = *blue = 0x1111 * blueval; /* 0xFFFF / 0xF = 0x1111 */		break;	case 4:		if(regno > 16)			return 1; /* error */		*red = *green = *blue = 0x1111 * regno; /* 0xFFFF / 0xF = 0x1111 */		break;	case 8:		if(regno > 256)			return 1;		helpvalue = regno >> 5;		redval = (redval >> (helpvalue<<2)) & 0xF;		*red = redval * 0x1111;		helpvalue = (regno >> 2) & 0x7;		greenval = (greenval >> (helpvalue<<2)) & 0xF;		*green = greenval * 0x1111;		helpvalue = regno & 0x03;		blueval = (blueval >> (helpvalue<<2)) & 0xF;		*blue = blueval * 0x1111;		break;	default:		return 1; 	}	return 0;}static int s3c44b0xfb_setcolreg(unsigned regno, unsigned red, unsigned green,			      unsigned blue, unsigned transp,			      struct fb_info *_info){    /*     *  Set a single color register. The values supplied have a 16 bit     *  magnitude.     *  Return != 0 for invalid regno.     */	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;	unsigned int helpvalue;	u32 blueval, redval, greenval;	blueval = inw(S3C44B0X_BLUELUT);	redval = inw(S3C44B0X_REDLUT);	greenval = inw(S3C44B0X_GREENLUT);	switch(info->gen.info.var.bits_per_pixel)	{	case 1:		return -EINVAL;		break;	case 2:		if((regno > 4) || (red != green) || (red != blue)) /* FIXME: maybe wrong */			return 1;		helpvalue = (unsigned int)(blue / 0x1111) & 0xF;		blueval &= ~(0xF << (regno<<2));		blueval |= (helpvalue << (regno<<2));		outl(blueval, S3C44B0X_BLUELUT);		break;	case 4:		return -EINVAL;		break;	case 8:		if(regno > 256)			return 1;		helpvalue = (unsigned int)(blue / 0x1111) & 0xF;		blueval &= ~(0xF << ((regno&0x03)<<2));		blueval |= (helpvalue << ((regno&0x03)<<2));		outl(blueval, S3C44B0X_BLUELUT);		helpvalue = (unsigned int)(red / 0x1111) & 0xF;		redval &= ~(0xF << (((regno>>5)&0x7)<<2));		redval |= (helpvalue << (((regno>>5)&0x7)<<2));		outl(redval, S3C44B0X_BLUELUT);		helpvalue = (unsigned int)(green / 0x1111) & 0xF;		greenval &= ~(0xF << (((regno>>2)&0x7)<<2));		greenval |= (helpvalue << (((regno>>2)&0x7)<<2));		outl(greenval, S3C44B0X_BLUELUT);		break;	default:		return 1;	}				    return 0;}static int s3c44b0xfb_pan_display(const struct fb_var_screeninfo *var,				struct fb_info_gen *info){    /*     *  Pan (or wrap, depending on the `vmode' field) the display using the     *  `xoffset' and `yoffset' fields of the `var' structure.     *  If the values don't fit, return -EINVAL.     */	return -EINVAL;}static int s3c44b0xfb_blank(int blank_mode, struct fb_info_gen *info){    /*     *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL     *  then the caller blanks by setting the CLUT (Color Look Up Table) to all     *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due     *  to e.g. a video mode which doesn't support it. Implements VESA suspend     *  and powerdown modes on hardware that supports disabling hsync/vsync:     *    blank_mode == 2: suspend vsync     *    blank_mode == 3: suspend hsync     *    blank_mode == 4: powerdown     */	u32 helpvalue;	switch(blank_mode)	{	case 2:		return -EINVAL;	case 3:		return -EINVAL;	case 4:		helpvalue = inw(S3C44B0X_LCDCON1);		outl(helpvalue&~S3C44B0X_LCDCON1_ENVID, S3C44B0X_LCDCON1); /* disable video output */		break;	default:		return -EINVAL;	}    /* ... */    return 0;}static void s3c44b0xfb_gen_blank(int blank_mode, struct fb_info *info){	s3c44b0xfb_blank(blank_mode, &fb_info.gen);	return;}#if 0 /* mod -- luzhl */static void s3c44b0xfb_set_disp(const void *par, struct display *disp,			      struct fb_info_gen *info){    /*     *  Fill in a pointer with the virtual address of the mapped frame buffer.

⌨️ 快捷键说明

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