首页 > 代码库 > LCD驱动程序

LCD驱动程序

定义LCD相应寄存器的结构体

struct lcd_regs {     unsigned long     lcdcon1;     unsigned long     lcdcon2;     unsigned long     lcdcon3;     unsigned long     lcdcon4;     unsigned long     lcdcon5;    unsigned long     lcdsaddr1;    unsigned long     lcdsaddr2;    unsigned long     lcdsaddr3;    unsigned long     redlut;    unsigned long     greenlut;    unsigned long     bluelut;    unsigned long     reserved[9];    unsigned long     dithmode;    unsigned long     tpal;    unsigned long     lcdintpnd;    unsigned long     lcdsrcpnd;    unsigned long     lcdintmsk;    unsigned long     lpcsel;};

定义调色板

u32 pseudo_palette[16];

定义LCD寄存器结构体变量

volatile struct lcd_regs* lcd_regs;
其他定义
static struct fb_info *s3c_lcd;static volatile unsigned long *gpbcon;static volatile unsigned long *gpbdat;static volatile unsigned long *gpccon;static volatile unsigned long *gpdcon;static volatile unsigned long *gpgcon;
构造fb_ops结构体
static struct fb_ops s3c_lcdfb_ops = {     .owner          = THIS_MODULE,     .fb_setcolreg     = s3c_lcdfb_setcolreg,     .fb_fillrect     = cfb_fillrect,     .fb_copyarea     = cfb_copyarea,     .fb_imageblit     = cfb_imageblit,};static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf){     chan &= 0xffff;     chan >>= 16 - bf->length;     return chan << bf->offset;}static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,                    unsigned int green, unsigned int blue,                    unsigned int transp, struct fb_info *info){     unsigned int val;         if (regno > 16)          return 1;     /* 用red,green,blue三原色构造出val */     val  = chan_to_field(red,     &info->var.red);     val |= chan_to_field(green, &info->var.green);     val |= chan_to_field(blue,     &info->var.blue);         //((u32 *)(info->pseudo_palette))[regno] = val;     pseudo_palette[regno] = val;     return 0;}

 

1.分配fb_info结构体

struct fb_info *s3c_lcd = framebuffer_alloc(0, NULL);
2.设置fb_info结构体
2.1设置固定参数
strcpy(s3c_lcd->fix.id, "mylcd");s3c_lcd->fix.smem_len = 480*272*32/8;/* 单位字节 */s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR;s3c_lcd->fix.line_length = 480*4;/* 单位字节 */

2.2设置可变参数

s3c_lcd->var.xres = 480;s3c_lcd->var.yres = 272;s3c_lcd->var.xres_virtual = 480;s3c_lcd->var.yres_virtual = 272;s3c_lcd->var.bit_per_pixel = 32;/* RGB */s3c_lcd->var.red.offset = 16;s3c_lcd->var.red.lenght = 8;s3c_lcd->var.green.offset = 8;s3c_lcd->var.green.length = 8;s3c_lcd->var.blue.offset = 0;s3c_lcd->var.blue.length = 8;s3c_lcd->var.activate = FB_ACTIVATE_NOW;
2.3设置操作函数
s3c_lcd->fbops = &s3c_lcdfb_ops;
2.4其他设置
s3c_lcd->pseudo_palette = pseudo_palette;s3c_lcd->screen_size = 480*270*32/8;
3.硬件相关的设置
3.1配置GPIO管脚用于LCD
gpbcon = ioremap(0x56000010, 8);gpbdat = gpbcon+1;gpccon = ioremap(0x56000020, 4);gpdcon = ioremap(0x56000030, 4);gpgcon = ioremap(0x56000060, 4);*gpccon = 0xaaaaaaaa;*gpdcon = 0xaaaaaaaa;*gpbcon |= (3<<8);/* 使能LCD_PWREN */
3.2映射LCD寄存器并设置
lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs));lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0d<<1);/* 设置CLKVAL,VCLK = HCLK / [(CLKVAL+1) x 2], LCD手册P22 (Dclk=9MHz~15MHz) *//* 垂直方向的时间参数 *//*VBPD VSYNC之后再过多长时间发出第一行数据*//* VFPD 发出最后一行后再过多长时间发出VSYNC *//* VSPW VSYNC信号的脉冲宽度 */lcd_regs->lcdcon2 = (1<<24) | (271<<14) | (1<<6) | (9<<0);/* 水平方向的时间参数 *//* HBPD HSYNC之后再过多长时间才能发出这一行数据 *//* HFPD 发出一行最后一个像素数据之后,再过多长时间才能发出HSYNC */lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1<<0);/* HSPW HSYNC信号的脉冲宽度 */lcd_regs->lcdcon4 = 40;/* 信号极性、字节序 */lcd_regs->lcdcon5 = (0<<10) | (1<<9) | (1<<8) | (0<<12) | (0<<1) | (0<<0);
3.3分配显存,并把地址告诉LCD控制器
/* s3c_lcd->fix.smem_start为显存的物理地址 */s3c_lcd->screen_base = dma_alloc_writecombine(NULL, s3c_lcd->fix.smem_len, &s3c_lcd->fix.smem_start, GFP_KERNEL);lcd_regs->lcdaddr1 = (s3c_lcd->fix.smem_start >> 1) & ~(3<<30);lcd_regs->lcdaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff;lcd_regs->lcdaddr3 = (480*32/16);  /* 一行的长度(单位: 2字节) */
3.4启动LCD
lcd_regs->lcdcon1 |= (1<<0); /* 使能LCD控制器 */lcd_regs->lcdcon5 |= (1<<3); /* 使能LCD器件: LCD_PWREN */
4.注册
register_framebuffer(s3c_lcd);/* /dev/fb0 */

5.测试LCD驱动

5.1配置内核,去掉原来的驱动程序

-> Device Drivers
  -> Graphics support
<M> S3C2410 LCD framebuffer support
5.2编译内核
make zImage
make modules
将编译出来的cfbcopyarea.ko、cfbfillrect.ko、cfbimgblt.ko模块拷贝到文件系统
5.3使用新内核启动开发板
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
5.4测试
echo hello > /dev/tty1  // 可以在LCD上看见hello。
echo hello起作用的前提是要配置:CONFIG_FRAMEBUFFER_CONSOLE
cat lcd.ko > /dev/fb0   // 花屏