本帖最后由 桥~ 于 2012-4-21 11:23 编辑
初学驱动~试着写了下面的程序
insmod qiao_lcd.ko 后屏幕黑屏了 只能说有反应
运行测试程序后写数据成功了,但是没显示图片
求指导~~~
驱动程序如下:
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/poll.h>
- #include <asm/irq.h>
- #include <asm/io.h>
- #include <linux/interrupt.h>
- #include <asm/uaccess.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
- #include <plat/regs-timer.h>
- #include <mach/regs-irq.h>
- #include <mach/regs-lcd.h>
- #include <asm/mach/time.h>
- #include <linux/clk.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/miscdevice.h>
- #define DEVICE_NAME "qiao_lcd"
- #define MVAL (13)
- #define MVAL_USED (0) //0=each frame 1=rate by MVAL
- #define INVVDEN (1) //0=normal 1=inverted
- #define BSWP (0) //Byte swap control
- #define HWSWP (1) //Half word swap control
- #define PNRMODE (3) // 设置为TFT屏
- #define BPPMODE (12) // 设置为16bpp模式
- //TFT_SIZE
- #define LCD_XSIZE_TFT (480)
- #define LCD_YSIZE_TFT (272)
- #define SCR_XSIZE_TFT (480)
- #define SCR_YSIZE_TFT (272)
- //Timing parameter for 4.3' LCD
- #define VBPD (2) //垂直同步信号的后肩
- #define VFPD (4) //垂直同步信号的前肩
- #define VSPW (8) //垂直同步信号的脉宽
- #define HBPD (10) //水平同步信号的后肩
- #define HFPD (19) //水平同步信号的前肩
- #define HSPW (30) //水平同步信号的脉宽
- #define CLKVAL_TFT (4)
- #define HOZVAL_TFT (LCD_XSIZE_TFT-1)
- #define LINEVAL_TFT (LCD_YSIZE_TFT-1)
- #define M5D(n) ((n) & 0x1fffff) // To get lower 21bits
- #undef DEBUG
- #define DEBUG
- #ifdef DEBUG
- #define PRINTK(fmt, args...) printk("debug information: " fmt, ## args)
- #else
- #define PRINTK(fmt, args...)
- #endif
- static void *LCD_BUFFER;
- static void __iomem *p;
- static ssize_t lcd_write (struct file *file, const char __user *buff, size_t count, loff_t *offp)
- {
- ssize_t ret;
- ret = copy_from_user(LCD_BUFFER,buff,count);
- if(!ret) printk( KERN_ERR "driver write success!\n");
- else
- {
- printk( KERN_ERR "write faild bytes = %d",ret);
- return ret;
- }
- return ret;
- }
- struct file_operations fops={
- .owner = THIS_MODULE,
- .write = lcd_write,
- };
- struct miscdevice misc={
- .minor = MISC_DYNAMIC_MINOR,
- .name = DEVICE_NAME,
- .fops = &fops,
- };
- static int __init qiao_lcd_init(void)
- {
- int ret;
- p = ioremap(0x4d000000, 0x63);
- PRINTK("p = %x \n", p);
- LCD_BUFFER = kmalloc(SCR_YSIZE_TFT * SCR_XSIZE_TFT * 2 ,GFP_KERNEL);
- PRINTK("LCD_BUFFER = %x \n", LCD_BUFFER);
- __raw_writel(0x00000000,S3C2410_GPCUP);
- __raw_writel(0xaaaa02a9,S3C2410_GPCCON);
- __raw_writel(0x00000000,S3C2410_GPDUP);
- __raw_writel(0xaaaaaaaa,S3C2410_GPDCON);
- __raw_writel((CLKVAL_TFT<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0,p+S3C2410_LCDCON1);
- PRINTK("p+S3C2410_LCDCON1 = %x \n", readl(p+S3C2410_LCDCON1));
- __raw_writel((VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW),p+S3C2410_LCDCON2);
- __raw_writel((HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD),p+S3C2410_LCDCON3);
- __raw_writel((MVAL<<8)|(HSPW),p+S3C2410_LCDCON4);
- __raw_writel((1<<11) | (0<<10) | (1<<9) | (1<<8) | (0<<7) | (0<<6) | (1<<3) |(BSWP<<1) | (HWSWP),p+S3C2410_LCDCON5);
- __raw_writel((((unsigned long)LCD_BUFFER>>22)<<21)|M5D((unsigned long)LCD_BUFFER>>1),p+S3C2410_LCDSADDR1);
- __raw_writel(M5D( ((unsigned long)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1 ),p+S3C2410_LCDSADDR2);
- __raw_writel((((SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1),p+S3C2410_LCDSADDR3);
- __raw_writel(__raw_readl(p+S3C2410_LCDINTMSK)|(3),p+S3C2410_LCDINTMSK);
- __raw_writel(__raw_readl(p+S3C2410_LPCSEL)&(~7),p+S3C2410_LPCSEL);
- __raw_writel(0,p+S3C2410_LCDREG(0x50));
- __raw_writel(__raw_readl(S3C2410_GPGUP)&(~(1<<4))|(1<<4),S3C2410_GPGUP);
- __raw_writel(__raw_readl(S3C2410_GPGCON)&(~(3<<8))|(3<<8),S3C2410_GPGCON);
- __raw_writel(__raw_readl(S3C2410_GPGDAT) | (1<<4),S3C2410_GPGDAT);
- __raw_writel(__raw_readl(p+S3C2410_LCDCON5)&(~(1<<3))|(1<<3),p+S3C2410_LCDCON5);
- __raw_writel(__raw_readl(p+S3C2410_LCDCON5)&(~(1<<5))|(0<<5),p+S3C2410_LCDCON5);
- __raw_writel(__raw_readl(p+S3C2410_LCDCON1) | (1),p+S3C2410_LCDCON1);
- PRINTK("p+S3C2410_LCDCON1 = %x \n", readl(p+S3C2410_LCDCON1));
- PRINTK("p+S3C2410_LCDCON2 = %x \n", readl(p+S3C2410_LCDCON2));
- PRINTK("p+S3C2410_LCDCON3 = %x \n", readl(p+S3C2410_LCDCON3));
- PRINTK("p+S3C2410_LCDCON4 = %x \n", readl(p+S3C2410_LCDCON4));
- PRINTK("p+S3C2410_LCDCON5 = %x \n", readl(p+S3C2410_LCDCON5));
- ret = misc_register(&misc);
- if(! ret) printk(DEVICE_NAME "initialized\n");
- return ret;
- }
- static void __exit qiao_lcd_exit(void)
- {
- misc_deregister(&misc);
- }
- module_init(qiao_lcd_init);
- module_exit(qiao_lcd_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("qiao");
- MODULE_DESCRIPTION("qiao_lcd_driver");
复制代码
测试程序如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "meimei.h"
- int main()
- {
- int fd;
- long ret;
- fd = open("/dev/qiao_lcd", 2);
- if (fd < 0)
- {
- printf("open device qiao_lcd faild");
- exit(1);
- }
- ret = write(fd,&gImage_meimei,sizeof(gImage_meimei));
- if(!ret) printf("test successfully!\n");
- else
- {
- printf("bytes filed number is %d",ret);
- }
- close(fd);
- return 0;
- }
复制代码
|