• LCD驱动 15-3


    测试:
    1:make menuconfig去掉原来的驱动程序
        Device Drivers  --->    
            Graphics support  ---> 
               <M> S3C2410 LCD framebuffer support                 
    2: make uImage
      make modules
      cp arch/arm/boot/uImage  /work/nfs_root/uImage_nolcd

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

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

    insmod lcd.ko

    4.

    ech0 hello > /dev/tty1         //可以看到LCD上有hello

    cat lcd.ko > /dev/fb0        //有花屏

     

    5.修改/etc/inittab
      tty1::askfirst:-/bin/sh

    insmod cfbcopyarea.ko

    insmod cfbfillrect.ko 

    insmod cfbimgblt.ko

    insmod lcd.ko

    insmod buttons.ko

    通过按键控制另一个sh控制台

      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 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 };
     47 
     48 static struct fb_info *s3c_lcd;
     49 /* gpbon,gpbdat,c,d,g, */
     50 volatile unsigned long *gpbcon;
     51 volatile unsigned long *gpbdat;
     52 volatile unsigned long *gpccon;
     53 volatile unsigned long *gpdcon;
     54 volatile unsigned long *gpgcon;
     55 static volatile  struct lcd_regs* lcd_regs;
     56 static u32    pseudo_palette[16];
     57 
     58 static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
     59 {
     60     chan &= 0xffff;
     61     chan >>= 16 - bf->length;
     62     return chan << bf->offset;
     63 }
     64 
     65 static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
     66                  unsigned int green, unsigned int blue,
     67                  unsigned int transp, struct fb_info *info)
     68 {
     69     unsigned int val;
     70     
     71     if (regno > 16)
     72         return 1;
     73 
     74     /* 用red,green,blue三原色构造出val */
     75     val  = chan_to_field(red,    &info->var.red);
     76     val |= chan_to_field(green, &info->var.green);
     77     val |= chan_to_field(blue,    &info->var.blue);
     78     
     79     //((u32 *)(info->pseudo_palette))[regno] = val;
     80     pseudo_palette[regno] = val;
     81     return 0;
     82 }
     83 
     84 static struct fb_ops s3c_lcdfb_ops = {
     85     .owner        = THIS_MODULE,
     86     .fb_setcolreg    = s3c_lcdfb_setcolreg,
     87     .fb_fillrect    = cfb_fillrect,
     88     .fb_copyarea    = cfb_copyarea,
     89     .fb_imageblit    = cfb_imageblit,
     90 };
     91 
     92 
     93 static int lcd_init(void)
     94 {
     95 
     96     /* 1. 分配一个fb_info */
     97     s3c_lcd = framebuffer_alloc(0, NULL);
     98     
     99     /* 2. 设置 */
    100     /* 2.1 设置固定的参数 */
    101     strcpy(s3c_lcd->fix.id, "mylcd");
    102     s3c_lcd->fix.smem_len = 480 * 272 * 16 / 8;
    103     s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
    104     s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR;  /*TFT*/
    105     s3c_lcd->fix.line_length = 480 * 2;
    106     
    107     /* 2.2 设置可变的参数 */
    108     s3c_lcd->var.xres           = 480;
    109     s3c_lcd->var.yres           = 272;
    110     s3c_lcd->var.xres_virtual   = 480;
    111     s3c_lcd->var.yres_virtual   = 272;
    112     s3c_lcd->var.bits_per_pixel = 16;
    113 
    114     /* RGB:565 */
    115     s3c_lcd->var.red.offset     = 11;
    116     s3c_lcd->var.red.length     = 5;
    117 
    118     s3c_lcd->var.green.offset   = 5;
    119     s3c_lcd->var.green.length   = 6;
    120 
    121     s3c_lcd->var.blue.offset    = 0;
    122     s3c_lcd->var.blue.length    = 5;
    123     
    124     s3c_lcd->var.activate       = FB_ACTIVATE_NOW;
    125     
    126     /* 2.3 设置操作函数 */
    127     s3c_lcd->fbops = &s3c_lcdfb_ops;
    128     
    129     /* 2.4 其他设置 */
    130     s3c_lcd->pseudo_palette = pseudo_palette;    //假的调色板    
    131 
    132     s3c_lcd->screen_size = 480 * 272 * 16 / 8;
    133     
    134     /* 3. 硬件相关的设置 */
    135     /* 3.1 配置GPIO用于LCD */
    136     //0x56000010 ,8
    137     gpbcon = ioremap(0x56000010, 8);
    138     gpbdat = gpbcon + 1;
    139     gpccon = ioremap(0x56000020, 4);
    140     gpdcon = ioremap(0x56000030, 4);
    141     gpgcon = ioremap(0x56000060, 4);
    142     //映射是一页一页映射,不用担心不足  
    143     *gpccon  = 0xaaaaaaaa;   // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND 
    144     *gpdcon  = 0xaaaaaaaa;   // GPIO管脚用于VD[23:8]
    145     *gpbcon &= ~(3);  // Power enable pin
    146     *gpbcon |= (0x01);
    147     *gpbdat &= ~(1<<0);            // Power off
    148     *gpgcon |=  (3<<8);   // GPG4用作LCD_PWREN
    149     
    150     /* 3.2 根据LCD手册设置LCD控制器,比如VCLK的频率等 */
    151     lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs));
    152 
    153         /* 
    154          * 设置LCD控制器的控制寄存器LCDCON1~5
    155          * 1. LCDCON1:
    156          *    设置VCLK的频率:VCLK(Hz) = HCLK/[(CLKVAL+1)x2]
    157          *    选择LCD类型: TFT LCD   
    158          *    设置显示模式: 16BPP
    159          *    先禁止LCD信号输出
    160          * 2. LCDCON2/3/4:
    161          *    设置控制信号的时间参数
    162          *    设置分辨率,即行数及列数
    163          * 现在,可以根据公式计算出显示器的频率:
    164          * 当HCLK=100MHz时,
    165          * Frame Rate = 1/[{(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)}x
    166          *              {(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)}x
    167          *              {2x(CLKVAL+1)/(HCLK)}]
    168          *            = 60Hz
    169          * 3. LCDCON5:
    170          *    设置显示模式为16BPP时的数据格式: 5:6:5
    171          *    设置HSYNC、VSYNC脉冲的极性(这需要参考具体LCD的接口信号): 反转
    172          *    半字(2字节)交换使能
    173          */
    174          
    175     lcd_regs->lcdcon1 = (4<<8) | (0x3<<5) | 
    176                   (0xC<<1) | (0<<0);
    177     lcd_regs->lcdcon2 = (1<<24) | (271<<14) | 
    178                   (1<<6) | (10-1);
    179     lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1);
    180     lcd_regs->lcdcon4 = 40;
    181     lcd_regs->lcdcon5 = (1<<11) | (1<<9) | (1<<8) | 
    182                   (1<<1);
    183     /* 3.3 分配显存(framebuffer),并把地址告诉LCD控制器 */
    184     s3c_lcd->screen_base = dma_alloc_writecombine(NULL,        
    185                 s3c_lcd->fix.smem_len, &s3c_lcd->fix.smem_start, GFP_KERNEL);
    186     lcd_regs->lcdsaddr1 = (s3c_lcd->fix.smem_start>>1) & ~(3 << 30);
    187     lcd_regs->lcdsaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1)    
    188                 & ( 0X1fffff );
    189     lcd_regs->lcdsaddr3 = (0<<11) | (480 *16/16);
    190     
    191     /* 启动LCD */
    192     lcd_regs->lcdcon1 |= (1 << 0);        //使能LCD本身
    193     lcd_regs->lcdcon5 |=  (1<<3);     // 设置是否输出LCD_PWREN
    194     *gpbdat |= (1<<0);            // Power on
    195     
    196     /* 4. 注册 */
    197     
    198     register_framebuffer(s3c_lcd);
    199     
    200     return 0;
    201 }
    202 
    203 static int lcd_exit(void)
    204 {
    205     unregister_framebuffer(s3c_lcd);
    206     lcd_regs->lcdcon1 &= ~(1 << 0);        //关闭LCD本身
    207     *gpbdat &= ~(1<<0);            // Power off
    208     dma_free_writecombine(NULL, s3c_lcd->fix.smem_len, 
    209     s3c_lcd->screen_base, s3c_lcd->fix.smem_start);
    210 
    211     iounmap(gpbcon);
    212     iounmap(gpccon);
    213     iounmap(gpdcon);
    214     iounmap(gpgcon);
    215 
    216     framebuffer_release(&s3c_lcd);
    217     return 0;
    218 }
    219 
    220 module_init(lcd_init);
    221 module_exit(lcd_exit);
    222 
    223 MODULE_LICENSE("GPL");

     

  • 相关阅读:
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    SpringMVC--->注解开发(各种注解的适应方法)
    SpringMVC--->入门(理解)
    SpringMVC--->Servlet回顾
    IDEA--->Maven不能继承HttpServlet
  • 原文地址:https://www.cnblogs.com/CZM-/p/5170323.html
Copyright © 2020-2023  润新知