以前没有写Lcd驱动程序,现在开始做项目了,才发现Lcd驱动程序必须认真学习,我总结所以驱动中LCD和网卡驱动是最难的,LCD主要是需要配置的寄存器太多了,还是老规矩先上代码。
内核版本:linux-3.4.2 lcd:4.3
上代码之前我得讲解一些基本的知识点,LCD驱动我们只需要写硬件这一块的代码就可以了,下面有三个函数内核已经帮我们写好了,我们只需要调用就可以了,这几个函数实现了内核层和应用成数据的传递,有兴趣的朋友去分析一下源码,我里驱动写好了我们可以选择动态加载驱动或者直接静态编译进内核,这个的区别在前文中我讲解的非常清楚了,希望朋友一定要去看一下,Linux驱动静态编译和动态编译方法详解
这个代码相对有点复杂,朋友们一定要仔细分析。驱动程序如下:
lcd.c文件如下:
#include 《linux/module.h》
#include 《linux/kernel.h》
#include 《linux/errno.h》
#include 《linux/string.h》
#include 《linux/mm.h》
#include 《linux/slab.h》
#include 《linux/delay.h》
#include 《linux/fb.h》
#include 《linux/init.h》
#include 《linux/dma-mapping.h》
#include 《linux/interrupt.h》
#include 《linux/workqueue.h》
#include 《linux/wait.h》
#include 《linux/platform_device.h》
#include 《linux/clk.h》
#include 《asm/io.h》
#include 《asm/uaccess.h》
#include 《asm/div64.h》
#include 《asm/mach/map.h》
staTIc int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info);
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;
};
staTIc struct fb_ops s3c_lcdfb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = s3c_lcdfb_setcolreg,
.fb_fillrect = cfb_fillrect, /* 这三个函数是在内核自带的,动态加载时候,需要把这个三个编译成模块当吧驱动程序编译进内核时候,就不用去管着三个函数 */
val |= chan_to_field(blue,&info-》var.blue);
//((u32 *)(info-》pseudo_palette))[regno] = val;
pseudo_palette[regno] = val;
return 0;
}
staTIc int lcd_init(void)
{
/* 1. 分配一个fb_info */
s3c_lcd = framebuffer_alloc(0, NULL);
/* 2. 设置 */
/* 2.1 设置固定的参数 */
strcpy(s3c_lcd-》fix.id, “mylcd”);
s3c_lcd-》fix.smem_len = 480*272*16/8;
s3c_lcd-》fix.type = FB_TYPE_PACKED_PIXELS;
s3c_lcd-》fix.visual = FB_VISUAL_TRUECOLOR; /* TFT */
s3c_lcd-》fix.line_length = 480*2;
/* 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.bits_per_pixel = 16;
/* RGB:565 */
s3c_lcd-》var.red.offset = 11;
s3c_lcd-》var.red.length = 5;
s3c_lcd-》var.green.offset = 5;
s3c_lcd-》var.green.length = 6;
s3c_lcd-》var.blue.offset = 0;
s3c_lcd-》var.blue.length = 5;
s3c_lcd-》var.acTIv