内核自带的驱动LCD,drivers/video/Fbmem.c
LCD驱动程序
假设
app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0
--------------------------------------------------------------
kernel:
fb_open
int fbidx = iminor(inode);
struct fb_info *info = = registered_fb[0];
以次设备号为下标。
app: read()
---------------------------------------------------------------
kernel:
fb_read
int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
if (info->fbops->fb_read)
return info->fbops->fb_read(info, buf, count, ppos);
src = (u32 __iomem *) (info->screen_base + p);
dst = buffer;
*dst++ = fb_readl(src++);
copy_to_user(buf, buffer, c)
1. registered_fb在哪里被设置?
答. register_framebuffer
怎么写LCD驱动程序?
1. 分配一个fb_info结构体: framebuffer_alloc
2. 设置
3. 注册: register_framebuffer
4. 硬件相关的操作
fbmem.c都是抽象出来的,最终都得依赖于底层的驱动。
VCLK 看手册,给合适的频率
VLINE--HYSNC 行同步信号
VFRAM--VSYNC 帧同步信号
VDEN(video date enable) 颜色
硬件操作:根据LCD手册,设置LCD控制器;
分配显存,并把地址告诉LCD控制器
配置引脚用于LCD
初始化:
/* 1. 分配一个fb_info */
/* 2. 设置 */
/* 2.1 设置固定的参数 */
/* 2.2 设置可变的参数 */
/* 2.3 设置操作函数 */
/* 2.4 其他的设置 */
/* 3. 硬件相关的操作 */
/* 3.1 配置GPIO用于LCD */
/* 3.2 根据LCD手册设置LCD控制器, 比如VCLK的频率等 */
/* 3.3 分配显存(framebuffer), 并把地址告诉LCD控制器 */
/* 4. 注册 */
我们看到的图像是从左到右,从上到下
测试:配置内核
1. make menuconfig去掉原来的驱动程序
-> Device Drivers
-> Graphics support
<M> S3C2410 LCD framebuffer support
2. make uImage
make modules
3. 使用新的uImage启动开发板:
具体驱动程序代码:
1 #include <linux/module.h> 2 #include <linux/kernel.h> 3 #include <linux/errno.h> 4 #include <linux/string.h> 5 #include <linux/mm.h> 6 #include <linux/slab.h> 7 #include <linux/delay.h> 8 #include <linux/fb.h> 9 #include <linux/init.h> 10 #include <linux/dma-mapping.h> 11 #include <linux/interrupt.h> 12 #include <linux/workqueue.h> 13 #include <linux/wait.h> 14 #include <linux/platform_device.h> 15 #include <linux/clk.h> 16 17 #include <asm/io.h> 18 #include <asm/uaccess.h> 19 #include <asm/div64.h> 20 21 #include <asm/mach/map.h> 22 #include <asm/arch/regs-lcd.h> 23 #include <asm/arch/regs-gpio.h> 24 #include <asm/arch/fb.h> 25 26 static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red, 27 unsigned int green, unsigned int blue, 28 unsigned int transp, struct fb_info *info); 29 30 31 struct lcd_regs { 32 unsigned long lcdcon1; 33 unsigned long lcdcon2; 34 unsigned long lcdcon3; 35 unsigned long lcdcon4; 36 unsigned long lcdcon5; 37 unsigned long lcdsaddr1; 38 unsigned long lcdsaddr2; 39 unsigned long lcdsaddr3; 40 unsigned long redlut; 41 unsigned long greenlut; 42 unsigned long bluelut; 43 unsigned long reserved[9]; 44 unsigned long dithmode; 45 unsigned long tpal; 46 unsigned long lcdintpnd; 47 unsigned long lcdsrcpnd; 48 unsigned long lcdintmsk; 49 unsigned long lpcsel; 50 }; 51 52 static struct fb_ops s3c_lcdfb_ops = { 53 .owner = THIS_MODULE, 54 .fb_setcolreg = s3c_lcdfb_setcolreg, 55 .fb_fillrect = cfb_fillrect, 56 .fb_copyarea = cfb_copyarea, 57 .fb_imageblit = cfb_imageblit, 58 }; 59 60 61 static struct fb_info *s3c_lcd; 62 static volatile unsigned long *gpbcon; 63 static volatile unsigned long *gpbdat; 64 s