免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2045 | 回复: 0
打印 上一主题 下一主题

[驱动] mini2440开发板写NEC 3.5寸TFT屏的驱动程序有问题,请教大神。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-04 17:10 |只看该作者 |倒序浏览
编译,加载到内核后。执行echo hello > /dev/tty1 LCD屏幕上没有反应。纠结几天了。麻烦大家抽空指导一下。内核版本linux-2.6.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/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <asm/io.h>
#include <asm/div64.h>
#include <asm/mach/map.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
#include <mach/fb.h>

#define M5D(n) ((n)&0x1fffff)

static volatile unsigned long * GPCCON;
static volatile unsigned long * GPCDAT;
static volatile unsigned long *        GPDCON;
static volatile unsigned long * GPGCON;
static volatile unsigned long *        GPGUP;
                 
/*由于LCD寄存器太多,逐个映射比较复杂,这里我们设置一个寄存器结构体 */
struct lcd_reg{
                        unsigned long LCDCON1;
                        unsigned long LCDCON2;
                        unsigned long LCDCON3;
                        unsigned long LCDCON4;
                        unsigned long LCDCON5;
                        unsigned long LCDSADDR1;
                        unsigned long LCDSADDR2;
                        unsigned long LCDSADDR3;
                        unsigned long REDLUT;
                        unsigned long GREENLUT;
                        unsigned long BLUELUT;
                        unsigned long UNUSED[8];
                        unsigned long DITHMOD;
                        unsigned long TPAL;
                        unsigned long LCDINTPND;
                        unsigned long LCDSRCPND;
                        unsigned long LCDINTMSK;
                        unsigned long TCONSEL;
};

static u32        pseudo_pal[16];
static volatile struct lcd_reg * lcdreg;
static struct fb_info * fbinfo;

static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
        chan &= 0xffff;
        chan >>= 16 - bf->length;
        return chan << bf->offset;
}

static int lcd_setcolreg(unsigned regno,unsigned red, unsigned green, unsigned blue,unsigned transp, struct fb_info *info){
                unsigned int val;
                u32 *pal = fbinfo->pseudo_palette;
                if (regno > 16)
                                return 1;
                               
                val |= chan_to_field(red,   &info->var.red);
                val |= chan_to_field(green, &info->var.green);
                val |= chan_to_field(blue,  &info->var.blue);
                pal[regno] = val;
//                printk("pal[%d] = %d\n",regno,val);
                return 0;
}

static struct fb_ops lcd_ops = {
        .owner                = THIS_MODULE,
        .fb_setcolreg        = lcd_setcolreg,                        //虚拟调色板的设置
        .fb_fillrect        = cfb_fillrect,
        .fb_copyarea        = cfb_copyarea,
        .fb_imageblit        = cfb_imageblit,
};


static int __init Mylcd_init(void)
{
                int ret;
                /*1、 分配一个fb_info结构体 */
                fbinfo = framebuffer_alloc(0, NULL);
                       
                /*2、 对fbinfo结构体进行设置 */
                /*2.1 设置固定参数 */
                strcpy(fbinfo->fix.id,"mylcd";                                 /*字符串形式的标示符 */
                fbinfo->fix.smem_len = 240 * 320 * 2;                        //缓存的长度
                fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;                //看FB_TYPE_
                fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;                //设置为真彩色
                fbinfo->fix.line_length = 240 * 2;                                        //一行占有的字节数
                /*2.2 设置可变参数*/
                fbinfo->var.xres = 240;                                //可见屏一行有240个像素点
                fbinfo->var.yres = 320;                                //可见屏一列有320个像素点
                fbinfo->var.bits_per_pixel = 16;                        //每个像素点的位数
                /* 颜色RGB565 */
                fbinfo->var.red.offset = 11;                        //红色的起始bit
                fbinfo->var.red.length = 5;                                //红色所占的位数
                fbinfo->var.red.offset = 5;                        //绿色的起始bit
                fbinfo->var.red.length = 6;                                //绿色所占的位数
                fbinfo->var.red.offset = 0;                        //蓝色的起始bit
                fbinfo->var.red.length = 5;                                //蓝色所占的位数
                fbinfo->var.activate = FB_ACTIVATE_NOW;
               
                /*2.3 设置操作函数 */
                fbinfo->fbops = &lcd_ops;
                /*2.4 其他的设置*/
        //        fbinfo->pseudo_palette;
//                fbinfo->screen_base;                        //显存的虚拟地址
                fbinfo->screen_size = 240*320*16/8;                        //显存的大小
                fbinfo->pseudo_palette = pseudo_pal;                                                //设置虚拟调色板
                /*3、 硬件相关操作,包括1、配置GPIO寄存器,用于LCD;2、根据LCD手册设置LCD控制器;3、分配显存*/
                /* 设置缓存的开始物理地址 */
//                fbinfo->fix.smem_start;
                /* 3.2配置GPIO管脚用于LCD */
                GPCCON = ioremap(0x56000020,4);
//                GPCDAT = GPCCON + 1;
                *GPCCON = 0xaaaaaaaa;                                //VD0~VD7,LEND~LRCPEVB对应的管脚GPC0~GPC15       
               
                GPDCON = ioremap(0x56000030,4);                               
                *GPDCON = 0xaaaaaaaa;                                //VD8~VD23对应的管脚GPD0~GPD15
               
          GPGCON = ioremap(0x56000060,4);
//          GPGUP = GPGCON + 2;
                *GPGCON |= (3 << ;                                 //LCD_PWREN对应管脚GPG4
//                * GPGUP |= (1 << 4);                                        //禁止内部上拉
       
                /* 3.3配置LCD的寄存器 */
                lcdreg = ioremap(0x4d000000,sizeof(struct lcd_reg));
                lcdreg->LCDCON1 |= (0x9 << | (0x0 << 7) | (0x3 << 5) | (0xc << 1) | (0x0 << 0);                //对LCDCON1进行设置,使CLKVAL=9,PNRMODE=3,BPPMODE=C,ENVID=0
//        printk("lcdcon1 = %lx",&lcdreg->LCDCON1);
                lcdreg->LCDCON2 |= (0x1 << 24) | (0x13f << 14) | (0x5 << 6) | (0x1 << 0);                                        //对LCDCON2进行设置,使VSPW=5,VBPD=36,VFPD=5,LINEVAL=319
//        printk("lcdcon2 = %lx",&lcdreg->LCDCON2);
                lcdreg->LCDCON3 |= (0x24 << 19) | (0xef << | (0x13 << 0);                                //对LCDCON3进行设置,使HBPD=36,HFBPD=36,HOZVAL=239
//        printk("lcdcon3 = %lx",&lcdreg->LCDCON3);
                lcdreg->LCDCON4 |= (0x5 << 0);                        //设置LCDCON4的HSPW=5       
//        printk("lcdcon4 = %lx",&lcdreg->LCDCON4);
                lcdreg->LCDCON5 |= (0x1 << 11) | (0x0 << 3) | (0x0 << 1) | (0x1 << 0);                                                        //设置LCDCON5的FRM565=1,BSWP=0,HWSWP=1,PWREN=0 关闭LCD电源
//                lcdreg->TPAL |= (0x1 << 24) | ((0xff0000 & 0xffffff) << 0);                                //打开临时调色板
//                printk("lcdcon5 = %lx",&lcdreg->LCDCON5);
                /* 3.4分配显存 */
                fbinfo->screen_base = dma_alloc_writecombine(NULL, fbinfo->fix.smem_len,(dma_addr_t *)&fbinfo->fix.smem_start, GFP_KERNEL);
                lcdreg->LCDSADDR1 |= ((fbinfo->fix.smem_start >> 22) << 21) | (M5D(fbinfo->fix.smem_start >> 1) << 0); //设置LCDSADDR1
//                printk("lcdsaddr1 = %lx",&lcdreg->LCDSADDR1);
                lcdreg->LCDSADDR2 |= (M5D((fbinfo->fix.smem_start + fbinfo->fix.smem_len) >> 1) << 0);                                //设置LCDBASEL/
//                printk("lcdsaddr2 = %lx",&lcdreg->LCDSADDR2);
                lcdreg->LCDSADDR3 |= (0x0 << 11) | (0xf0 << 0);                        //设置OFFSIZE=0x0,PAGEWIDTH=240*16\16
//                printk("lcdsaddr3= %lx",&lcdreg->LCDSADDR3);

               
                /* 3.5打开LCD电源 */
                lcdreg->LCDCON1 |= 0x1;                                                        //打开LCD控制器,使能LCD
                lcdreg->LCDCON5 |= (0x1 << 3) | (0x1 << 2);                        //打开LCD本身电源

                /*4、 注册平台设备 */
                ret = register_framebuffer(fbinfo);                                                //注册framebuffer
                return 0;
}

static void __exit Mylcd_exit(void)
{
        unregister_framebuffer(fbinfo);                                        //释放帧内存
        lcdreg->LCDCON1 &= ~0x1;                                                        //打开LCD控制器,使能LCD
        lcdreg->LCDCON5 &= ~(0x1 << 3);                                                        //关闭LCD电源,关闭LCD
//        dma_free_writecombine
        dma_free_writecombine(NULL, fbinfo->fix.smem_len,fbinfo->screen_base, fbinfo->fix.smem_start);
//        dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
//                               fb->fb.screen_base, fb->fb.fix.smem_start);
        iounmap(GPDCON);
        iounmap(GPGCON);       
        iounmap(lcdreg);       
        framebuffer_release(fbinfo);
}

module_init(Mylcd_init);
module_exit(Mylcd_exit);

MODULE_AUTHOR("chai hao";
MODULE_DESCRIPTION("My framebuffer driver";
MODULE_LICENSE("GPL";
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP