微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)

S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)

时间:08-15 来源:互联网 点击:

= 1;

}

}

}

/*LCD各寄存器进行初始化*/

static int my2440fb_init_registers(struct fb_info *fbinfo)

{

unsigned long flags;

void __iomem *tpal;

void __iomem *lpcsel;

/*从lcd_fb_probe探测函数设置的私有变量结构体中再获得LCD相关信息的数据*/

struct my2440fb_var *fbvar = fbinfo->par;

struct s3c2410fb_mach_info *mach_info = fbvar->dev->platform_data;

/*获得临时调色板寄存器基地址,S3C2410_TPAL宏定义在mach-s3c2410/include/mach/regs-lcd.h中。

注意对于lpcsel这是一个针对三星TFT屏的一个专用寄存器,如果用的不是三星的TFT屏应该不用管它。*/

tpal = fbvar->lcd_base + S3C2410_TPAL;

lpcsel = fbvar->lcd_base + S3C2410_LPCSEL;

/*在修改下面寄存器值之前先屏蔽中断,将中断状态保存到flags中*/

local_irq_save(flags);

/*这里就是在上一篇章中讲到的把IO端口C和D配置成LCD模式*/

modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask);

modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask);

modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask);

modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask);

/*恢复被屏蔽的中断*/

local_irq_restore(flags);

writel(0x00, tpal);/*临时调色板寄存器使能禁止*/

writel(mach_info->lpcsel, lpcsel);/*在上一篇中讲到过,它是三星TFT屏的一个寄存器,这里可以不管*/

return 0;

}

/*该函数实现修改GPIO端口的值,注意第三个参数mask的作用是将要设置的寄存器值先清零*/

static inline void modify_gpio(void __iomem *reg, unsigned long set, unsigned long mask)

{

unsigned long tmp;

tmp = readl(reg) & ~mask;

writel(tmp | set, reg);

}

/*检查fb_info中的可变参数*/

static int my2440fb_check_var(struct fb_info *fbinfo)

{

unsigned i;

/*从lcd_fb_probe探测函数设置的平台数据中再获得LCD相关信息的数据*/

struct fb_var_screeninfo *var = &fbinfo->var;/*fb_info中的可变参数*/

struct my2440fb_var *fbvar = fbinfo->par;/*在lcd_fb_probe探测函数中设置的私有结构体数据*/

struct s3c2410fb_mach_info *mach_info = fbvar->dev->platform_data;/*LCD的配置结构体数据,这个配置结构体的赋值在上一篇章的"3. 帧缓冲设备作为平台设备"中*/

struct s3c2410fb_display *display = NULL;

struct s3c2410fb_display *default_display = mach_info->displays + mach_info->default_display;

int type = default_display->type;/*LCD的类型,看上一篇章的"3. 帧缓冲设备作为平台设备"中的type赋值是TFT类型*/

/*验证X/Y解析度*/

if (var->yres == default_display->yres &&

var->xres == default_display->xres &&

var->bits_per_pixel == default_display->bpp)

{

display = default_display;

}

else

{

for (i = 0; i < mach_info->num_displays; i++)

{

if (type == mach_info->displays[i].type &&

var->yres == mach_info->displays[i].yres &&

var->xres == mach_info->displays[i].xres &&

var->bits_per_pixel == mach_info->displays[i].bpp)

{

display = mach_info->displays + i;

break;

}

}

}

if (!display)

{

return -EINVAL;

}

/*配置LCD配置寄存器1中的5-6位(配置成TFT类型)和配置LCD配置寄存器5*/

fbvar->regs.lcdcon1 = display->type;

fbvar->regs.lcdcon5 = display->lcdcon5;

/* 设置屏幕的虚拟解析像素和高度宽度 */

var->xres_virtual = display->xres;

var->yres_virtual = display->yres;

var->height = display->height;

var->width = display->width;

/* 设置时钟像素,行、帧切换值,水平同步、垂直同步长度值 */

var->pixclock = display->pixclock;

var->left_margin = display->left_margin;

var->right_margin = display->right_margin;

var->upper_margin = display->upper_margin;

var->lower_margin = display->lower_margin;

var->vsync_len = display->vsync_len;

var->hsync_len = display->hsync_len;

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top