2440 lcd驱动

  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. #include <linux/types.h>  
  21. #include <asm/mach/map.h>  
  22. #include <mach/regs-lcd.h>  
  23. #include <mach/regs-gpio.h>  
  24. #include <mach/fb.h>  
  25.   
  26. struct lcd_regs{  
  27.     unsigned long   lcdcon1;  
  28.     unsigned long   lcdcon2;  
  29.     unsigned long   lcdcon3;  
  30.     unsigned long   lcdcon4;  
  31.     unsigned long   lcdcon5;  
  32.     unsigned long   lcdsaddr1;  
  33.     unsigned long   lcdsaddr2;  
  34.     unsigned long   lcdsaddr3;  
  35.     unsigned long   redlut;  
  36.     unsigned long   greenlut;  
  37.     unsigned long   bluelut;   
  38.     unsigned long   reserved[9];  
  39.     unsigned long   dithmode;  
  40.     unsigned long   tpal;  
  41.     unsigned long   lcdintpnd;  
  42.     unsigned long   lcdsrcpnd;  
  43.     unsigned long   lcdintmsk;  
  44.     unsigned long   lpcsel;  
  45. };  
  46. static volatile struct lcd_regs *lcd_regs_base;  
  47.   
  48. static struct fb_info *fb_x35;  
  49.   
  50. static volatile unsigned long *gpbcon;  
  51. static volatile unsigned long *gpbdat;  
  52. static volatile unsigned long *gpccon;  
  53. static volatile unsigned long *gpdcon;  
  54. static volatile unsigned long *gpgcon;  
  55.   
  56. static u32 pseudo_palette[16];  
  57.   
  58. static inline unsigned int chan_to_field(unsigned int chan,  
  59.     struct fb_bitfield* bf)  
  60. {  
  61.     chan &= 0xffff;  
  62.     chan >>= 16 - bf->length;  
  63.       
  64.     return chan << bf->offset;  
  65. }  
  66.   
  67.   
  68. //设置颜色  
  69. static int x35_setcolreg(unsigned int regno, unsigned int red,   
  70.         unsigned int green, unsigned int blue,  
  71.         unsigned int transp, struct fb_info *info)  
  72. {  
  73.     unsigned int val;  
  74.       
  75.     if (regno > 16)  
  76.         return 1;  
  77.   
  78.     val  = chan_to_field(red,   &info->var.red);  
  79.     val |= chan_to_field(green, &info->var.green);  
  80.     val |= chan_to_field(blue,  &info->var.blue);  
  81.       
  82.     pseudo_palette[regno] = val;  
  83.       
  84.     return 0;  
  85.   
  86. }  
  87.   
  88.   
  89. static struct fb_ops mini_fb_ops = {  
  90.     .owner          = THIS_MODULE,  
  91.     .fb_setcolreg   = x35_setcolreg,  
  92.     .fb_fillrect    = cfb_fillrect,  
  93.     .fb_copyarea    = cfb_copyarea,  
  94.     .fb_imageblit   = cfb_imageblit,  
  95. };  
  96.   
  97.   
  98.   
  99. static int lcd_init(void)  
  100. {  
  101.     //1)分配一个fb_info  
  102.     fb_x35 = framebuffer_alloc(0, NULL);  
  103.   
  104.     //2)填充fb_info结构  
  105.     // 1 设置固定参数  
  106.     // 2 设置可变参数  
  107.     // 3 设置操作函数  
  108.     // 4 其他的设置  
  109.     strcpy(fb_x35->fix.id, "mylcd");   
  110.     fb_x35->fix.smem_len         = 240 * 320 * 32 / 8;  // frambuffer的大小  
  111.   
  112.     fb_x35->fix.type             = FB_TYPE_PACKED_PIXELS;//扫描方式,以像素点扫描 非隔行扫描   
  113.     fb_x35->fix.visual           = FB_VISUAL_TRUECOLOR; //色阶 真彩色  
  114.     fb_x35->fix.line_length  = 240 * 4;  
  115.   
  116.     fb_x35->var.xres             = 240;  
  117.     fb_x35->var.yres             = 320;  
  118.     fb_x35->var.xres_virtual     = 240;  
  119.     fb_x35->var.yres_virtual     = 320;  
  120.     fb_x35->var.bits_per_pixel   = 32;  //每个像素点占有的字节数  
  121.   
  122.   
  123.     //颜色放置的方式,这里是真彩色为 8:8:8,每种颜色占用8位  
  124.     fb_x35->var.red.offset       = 16;  
  125.     fb_x35->var.red.length       = 8;  
  126.     fb_x35->var.blue.offset  = 8;  
  127.     fb_x35->var.blue.length  = 8;  
  128.     fb_x35->var.green.offset     = 0;  
  129.     fb_x35->var.green.length     = 8;  
  130.       
  131.     fb_x35->var.activate         = FB_ACTIVATE_NOW; //设置颜色立即生效  
  132.   
  133.     //设置操作函数  
  134.     fb_x35->fbops                = &mini_fb_ops;  
  135.   
  136.     fb_x35->pseudo_palette       = pseudo_palette; //调色板  
  137.     fb_x35->screen_size      = 240 * 320 * 32 / 8;  //屏幕尺寸的大小  
  138.   
  139.   
  140.     //3)设置硬件,驱动lcd  
  141.     // 1 设置lcd引脚可用  
  142.     // 2 设置lcd控制器寄存器  
  143.     // 3 设置其他的  
  144.     gpbcon = ioremap(0x56000010, 8);      
  145.     gpbdat = gpbcon+1;  
  146.     gpccon      =   ioremap(0x5600020, 4);  
  147.     gpdcon      =   ioremap(0x5600030, 4);    
  148.     gpgcon      =   ioremap(0x5600060, 4);  
  149.   
  150.     *gpccon     =   0xaaaaaaaa;  
  151.     *gpdcon     =   0xaaaaaaaa;  
  152.     *gpgcon     |=  (0x3 << (4 * 2));  //lcd_pwren lcd电源引脚  
  153.       
  154.     lcd_regs_base   = ioremap(0x4d000000, sizeof(struct lcd_regs));  
  155.       
  156.     lcd_regs_base->lcdcon1 = (9 << 8) | (3 << 5) | (0xd << 1);  
  157.     lcd_regs_base->lcdcon2 = (8 << 24) | (319 << 14) | (4 << 6) | (9 << 0);  
  158.     lcd_regs_base->lcdcon3 = (15 << 19) | (239 << 8) | (16 << 0) ;  
  159.     lcd_regs_base->lcdcon4 = 5;  
  160.     lcd_regs_base->lcdcon5 = (0 << 12) | (0 << 10) | (1<<6) | (0 << 1) | (0 << 0) ;  
  161.             //vsync swap set error  
  162.   
  163.     //分配显存,将显存地址告诉framebuffer  
  164.     fb_x35->screen_base      = dma_alloc_writecombine(NULL, fb_x35->fix.smem_len,   
  165.                         &(fb_x35->fix.smem_start), GFP_KERNEL);//fb_x35->fix.smem_start = xxx;  /* 显存的物理地址 */  
  166.     lcd_regs_base->lcdsaddr1     = (fb_x35->fix.smem_start >> 1) & (~(3 << 30)); //[31~0]=0b00xx xxxx ... 30误写成20  
  167.     lcd_regs_base->lcdsaddr2     = ((fb_x35->fix.smem_start + fb_x35->fix.smem_len) >> 1) & 0x1fffff;  
  168.     lcd_regs_base->lcdsaddr3     = (0 << 11) | ((240 * 32 / 16) << 0); //行的长度有错  
  169.   
  170.   
  171.     //启动lcd  
  172.     lcd_regs_base->lcdcon1       |= (1 << 0);  
  173.     lcd_regs_base->lcdcon5       |= (1 << 3);  
  174.     /* MINI2440的背光电路也是通过LCD_PWREN来控制的, 不需要单独的背光引脚 */  
  175.       
  176.     //4)注册framebuffer  
  177.     register_framebuffer(fb_x35);  
  178.       
  179.     return 0;  
  180. }  
  181.   
  182. static void lcd_exit(void)  
  183. {  
  184.     //注销framebuffer结构  
  185.     //释放分配的frambuffer显存  
  186.     //关闭lcd控制器以及电源  
  187.     //取消映射地址  
  188.     //释放framebuffer结构  
  189.     unregister_framebuffer(fb_x35);  
  190.     lcd_regs_base->lcdcon1       &= ~(1 << 0);  
  191.     lcd_regs_base->lcdcon5       &= ~(1 << 3);  
  192.       
  193.     dma_free_writecombine(NULL, fb_x35->fix.smem_len, fb_x35->screen_base, fb_x35->fix.smem_start);  
  194.   
  195.     iounmap(lcd_regs_base);  
  196.     iounmap(gpccon);  
  197.     iounmap(gpdcon);  
  198.     iounmap(gpgcon);  
  199.   
  200.     framebuffer_release(fb_x35);  
  201. }  
  202.   
  203.   
  204. module_init(lcd_init);  
  205. module_exit(lcd_exit);  
  206.   
  207. MODULE_LICENSE("GPL");  
  208. MODULE_AUTHOR("LCL");  

如何测试:

1. make menuconfig去掉原来的驱动程序
-> Device Drivers
  -> Graphics support
<M> S3C2410 LCD framebuffer support

2. make uImage
   make modules 

3. 使用新的uImage启动开发板:

4. 先将之前module下编译出来的几个文件拷到开发板上cfbcopyarea.ko cfbfillrect.ko cfbimgblt.ko(/drivers/video/*)

5.

insmod cfbcopyarea.ko 
insmod cfbfillrect.ko 
insmod cfbimgblt.ko 
insmod lcd.ko

6.

echo hello > /dev/tty1  // 可以在LCD上看见hello
cat lcd.ko > /dev/fb0   // 花屏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值