mini210开发板H43电阻屏驱动程序

来源:互联网 发布:360主机卫士 apache 编辑:程序博客网 时间:2024/05/20 16:32

把代码粘上来,肯定能用,照着裸机改的,我刚刚试过的


#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>#include <plat/fb.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);static struct fb_ops s3c_lcdfb_ops = {.owner= THIS_MODULE,.fb_setcolreg= s3c_lcdfb_setcolreg,.fb_fillrect= cfb_fillrect,.fb_copyarea= cfb_copyarea,.fb_imageblit= cfb_imageblit,};static struct fb_info *s3c_lcd;struct clk *lcd_clk;static u32 pseudo_palette[16];/*mini210 lcd regs*/static volatile unsigned long *gPF0CON;static volatile unsigned long *gPF1CON;static volatile unsigned long *gPF2CON;static volatile unsigned long *gPF3CON;static volatile unsigned long *gPD0CON;static volatile unsigned long *gPD0DAT;static volatile unsigned long *cLK_SRC1;static volatile unsigned long *cLK_DIV1;static volatile unsigned long *dISPLAY_CONTROL;static volatile unsigned long *vIDCON0;static volatile unsigned long *vIDCON1;static volatile unsigned long *vIDTCON2;static volatile unsigned long *wINCON0;static volatile unsigned long *wINCON2;static volatile unsigned long *sHADOWCON;static volatile unsigned long *vIDOSD0A;static volatile unsigned long *vIDOSD0B;static volatile unsigned long *vIDOSD0C;static volatile unsigned long *vIDW00ADD0B0;static volatile unsigned long *vIDW00ADD1B0;static volatile unsigned long *vIDTCON0;static volatile unsigned long *vIDTCON1;static volatile unsigned long *clk_gate_block;#define HSPW (0)#define HBPD(40 - 1)#define HFPD (5 - 1)#define VSPW(0)#define VBPD (8 - 1)#define VFPD (8 - 1)// FB地址//#define FB_ADDR(0x23000000)#define ROW(272)#define COL(480)#define HOZVAL(COL-1)#define LINEVAL(ROW-1)#define LeftTopX     0#define LeftTopY     0#define RightBotX   479#define RightBotY   271/* from pxafb.c */static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf){chan &= 0xffff;chan >>= 16 - bf->length;return chan << bf->offset;}static void regs_remap(void){gPF0CON= ioremap(0xE0200120, 4);gPF1CON= ioremap(0xE0200140, 4);gPF2CON= ioremap(0xE0200160, 4);gPF3CON= ioremap(0xE0200180, 4);gPD0CON= ioremap(0xE02000A0, 4);gPD0DAT= ioremap(0xE02000A4, 4); cLK_SRC1= ioremap(0xe0100204, 4);cLK_DIV1= ioremap(0xe0100304, 4);dISPLAY_CONTROL= ioremap(0xe0107008, 4);vIDCON0= ioremap(0xF8000000, 4);vIDCON1= ioremap(0xF8000004, 4);vIDTCON2= ioremap(0xF8000018, 4);wINCON0= ioremap(0xF8000020, 4);wINCON2= ioremap(0xF8000028, 4);sHADOWCON= ioremap(0xF8000034, 4);vIDOSD0A= ioremap(0xF8000040, 4);vIDOSD0B= ioremap(0xF8000044, 4);vIDOSD0C= ioremap(0xF8000048, 4);vIDW00ADD0B0= ioremap(0xF80000A0, 4);vIDW00ADD1B0= ioremap(0xF80000D0, 4);vIDTCON0= ioremap(0xF8000010, 4);vIDTCON1= ioremap(0xF8000014, 4);//clk_gate_block= ioremap(0xE0100480, 4);}static void regs_unremap(void){//iounmap(clk_gate_block);iounmap(gPF0CON);iounmap(gPF1CON);iounmap(gPF2CON);iounmap(gPF3CON); iounmap(gPD0CON);iounmap(gPD0DAT);  iounmap(cLK_SRC1); iounmap(cLK_DIV1); iounmap(dISPLAY_CONTROL); iounmap(vIDCON0); iounmap(vIDCON1); iounmap(vIDTCON2); iounmap(wINCON0); iounmap(wINCON2); iounmap(sHADOWCON); iounmap(vIDOSD0A); iounmap(vIDOSD0B); iounmap(vIDOSD0C);iounmap(vIDW00ADD0B0 ); iounmap(vIDW00ADD1B0); iounmap(vIDTCON0); iounmap(vIDTCON1);}static void lcd_hadinit(void){// 配置引脚用于LCD功能*gPF0CON = 0x22222222;*gPF1CON = 0x22222222;*gPF2CON = 0x22222222;*gPF3CON = 0x22222222;// 打开背光*gPD0CON &= ~(0xf<<4);*gPD0CON |= (1<<4);        printk("close backlight\n");*gPD0DAT |= (1<<1);// 10: RGB=FIMD I80=FIMD ITU=FIMD*dISPLAY_CONTROL = 2<<0;// bit[26~28]:使用RGB接口// bit[18]:RGB 并行// bit[2]:选择时钟源为HCLK_DSYS=166MHz*vIDCON0 &= ~( (3<<26)|(1<<18)|(1<<2) );// bit[1]:使能lcd控制器// bit[0]:当前帧结束后使能lcd控制器*vIDCON0 |= ( (1<<0)|(1<<1) );// bit[6]:选择需要分频// bit[6~13]:分频系数为15,即VCLK = 166M/(14+1) = 11M*vIDCON0 |= 14<<6 | 1<<4;// H43-HSD043I9W1.pdf(p13) 时序图:VSYNC和HSYNC都是低脉冲// s5pv210芯片手册(p1207) 时序图:VSYNC和HSYNC都是高脉冲有效,所以需要反转*vIDCON1 |= 1<<5 | 1<<6;// 设置时序*vIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;*vIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;// 设置长宽*vIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);// 设置windows1// bit[0]:使能// bit[2~5]:24bpp// 设置windows1的上下左右*vIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);*vIDOSD0B = (RightBotX<<11) | (RightBotY << 0);*vIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);}static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,     unsigned int green, unsigned int blue,     unsigned int transp, struct fb_info *info){unsigned int val;if (regno > 16)return 1;/* 用red,green,blue三原色构造出val */val  = chan_to_field(red,&info->var.red);val |= chan_to_field(green, &info->var.green);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){        printk("mini210000000  lcd init \n");/* 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*32/8;        /* TQ2440的LCD位宽是24,但是2440里会分配4字节即32位(浪费1字节) */s3c_lcd->fix.type     = FB_TYPE_PACKED_PIXELS;s3c_lcd->fix.visual   = FB_VISUAL_TRUECOLOR; /* TFT */s3c_lcd->fix.line_length = 480*4;/* 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 = 32;/* RGB:565 */s3c_lcd->var.red.offset     = 16;s3c_lcd->var.red.length     = 8;s3c_lcd->var.green.offset   = 8;s3c_lcd->var.green.length   = 8;s3c_lcd->var.blue.offset    = 0;s3c_lcd->var.blue.length    = 8;s3c_lcd->var.activate       = FB_ACTIVATE_NOW;/* 2.3 设置操作函数 */s3c_lcd->fbops              = &s3c_lcdfb_ops;/* 2.4 其他的设置 */s3c_lcd->pseudo_palette = pseudo_palette; //s3c_lcd->screen_base  = ;  /* 显存的虚拟地址 */ s3c_lcd->screen_size   = 480*272*32/8;/* 3. 硬件相关的操作 *//* 3.1 配置GPIO用于LCD */regs_remap();// 配置引脚用于LCD功能*gPF0CON = 0x22222222;*gPF1CON = 0x22222222;*gPF2CON = 0x22222222;*gPF3CON = 0x22222222;// 打开背光*gPD0CON &= ~(0xf<<4);*gPD0CON |= (1<<4);        printk("close backlight\n");*gPD0DAT |= (1<<1);// 10: RGB=FIMD I80=FIMD ITU=FIMD*dISPLAY_CONTROL = 2<<0;     //   *clk_gate_block&=~((1<<3)|(1<<2));      lcd_clk = clk_get(NULL,"lcd");        if(!lcd_clk||IS_ERR(lcd_clk)){        printk(KERN_INFO"FAILED to get lcd clock source\n");        }        clk_enable(lcd_clk);// bit[26~28]:使用RGB接口// bit[18]:RGB 并行// bit[2]:选择时钟源为HCLK_DSYS=166MHz*vIDCON0 &= ~( (3<<26)|(1<<18)|(1<<2) );// bit[1]:使能lcd控制器// bit[0]:当前帧结束后使能lcd控制器 *vIDCON0 |= ( (1<<0)|(1<<1) );// bit[6]:选择需要分频// bit[6~13]:分频系数为15,即VCLK = 166M/(14+1) = 11M*vIDCON0 |= 14<<6 | 1<<4;// H43-HSD043I9W1.pdf(p13) 时序图:VSYNC和HSYNC都是低脉冲// s5pv210芯片手册(p1207) 时序图:VSYNC和HSYNC都是高脉冲有效,所以需要反转*vIDCON1 |= 1<<5 | 1<<6;// 设置时序*vIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;*vIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;// 设置长宽*vIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);                *wINCON0 |= 1<<0;*wINCON0 &= ~(0xf << 2);*wINCON0 |= (0xB<<2) | (1<<15);// 设置windows1的上下左右*vIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);*vIDOSD0B = (RightBotX<<11) | (RightBotY << 0);*vIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);/* 3.3 分配显存(framebuffer), 并把地址告诉LCD控制器 */s3c_lcd->screen_base = dma_alloc_writecombine(NULL, s3c_lcd->fix.smem_len, (dma_addr_t *)&(s3c_lcd->fix.smem_start), GFP_KERNEL);// 设置fb的地址*vIDW00ADD0B0 = s3c_lcd->fix.smem_start;*vIDW00ADD1B0 = s3c_lcd->fix.smem_start+s3c_lcd->fix.smem_len;// 使能channel 0传输数据         *sHADOWCON = 0x1;//s3c_lcd->fix.smem_start = xxx;  /* 显存的物理地址 *//* 启动LCD */             /* 4. 注册 */       register_framebuffer(s3c_lcd);return 0;}static void lcd_exit(void){unregister_framebuffer(s3c_lcd);*vIDCON0&=~(1<<1);*wINCON0 &= ~(1<<0);//lcd_regs->lcdcon1 &= ~(1<<0); /* 关闭LCD控制器 *///lcd_regs->lcdcon1 &= ~(1<<3); /* 关闭LCD本身 *///*gpbdat &= ~1;     /* 关闭背光 */        printk("lcd exit");dma_free_writecombine(NULL, s3c_lcd->fix.smem_len, s3c_lcd->screen_base, s3c_lcd->fix.smem_start);       regs_unremap();framebuffer_release(s3c_lcd);}module_init(lcd_init);module_exit(lcd_exit);MODULE_LICENSE("GPL");

0 0
原创粉丝点击