Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1323628
  • 博文数量: 168
  • 博客积分: 2124
  • 博客等级: 大尉
  • 技术积分: 2590
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-16 23:51
文章分类

全部博文(168)

文章存档

2014年(6)

2013年(74)

2012年(71)

2011年(17)

分类: LINUX

2012-09-25 15:28:16

     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "failed to get memory registers\n");
ret = -ENXIO;
goto dealloc_fb;
}

size = (res->end - res->start) + 1;
info->mem = request_mem_region(res->start, size, pdev->name);
if (info->mem == NULL) {
dev_err(&pdev->dev, "failed to get memory region\n");
ret = -ENOENT;
goto dealloc_fb;
}
info->io = ioremap(res->start, size);
if (info->io == NULL) {
dev_err(&pdev->dev, "ioremap() of registers failed\n");
ret = -ENXIO;
goto release_mem;
}

最终得到了fb的基地址:info->io

以后只需要在基地址的基础上加上偏移量即可得到相应的寄存器,

偏移量和寄存器操作宏 定义在arch/arm/mach-s3c2410/include/mach/regs-lcd.h

(板级支持包,我们还可以看到其他很多的模块的地址寄存器)


#define S3C2410_LCDREG(x) (x)


/* LCD control registers */

#define S3C2410_LCDCON1    S3C2410_LCDREG(0x00)

#define S3C2410_LCDCON2    S3C2410_LCDREG(0x04)

#define S3C2410_LCDCON3    S3C2410_LCDREG(0x08)

#define S3C2410_LCDCON4    S3C2410_LCDREG(0x0C)

#define S3C2410_LCDCON5    S3C2410_LCDREG(0x10)


#define S3C2410_LCDCON1_CLKVAL(x)  ((x) << 8)

#define S3C2410_LCDCON1_MMODE   (1<<7)

#define S3C2410_LCDCON1_DSCAN4   (0<<5)

#define S3C2410_LCDCON1_STN4   (1<<5)

#define S3C2410_LCDCON1_STN8   (2<<5)

#define S3C2410_LCDCON1_TFT   (3<<5)

......balabala......


现在遇到的问题是:为什么通过platform_get_resource、ioremap等一系列函数就能得到lcd寄存器的基地址呢?

解答:

 因为通过platform_get_resource,返回一个resource结构指针,我们来看一下这个结构指针:

struct resource {
 resource_size_t start;
 resource_size_t end;
 const char *name;
 unsigned long flags;
 struct resource *parent, *sibling, *child;
};

再来看一下arch\arm\plat-s3c24xx目录下的devs.c文件是如何定义lcd资源的:

/* LCD Controller */

static struct resource s3c_lcd_resource[] = {

[0] = {

.start = S3C24XX_PA_LCD,

.end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,

.flags = IORESOURCE_MEM,

},

[1] = {

.start = IRQ_LCD,//中断号

.end   = IRQ_LCD,

.flags = IORESOURCE_IRQ,

}


};


static u64 s3c_device_lcd_dmamask = 0xffffffffUL;


struct platform_device s3c_device_lcd = {

.name  = "s3c2410-lcd",

.id  = -1,

.num_resources  = ARRAY_SIZE(s3c_lcd_resource),

.resource  = s3c_lcd_resource,

.dev              = {

.dma_mask = &s3c_device_lcd_dmamask,

.coherent_dma_mask = 0xffffffffUL

}

};


EXPORT_SYMBOL(s3c_device_lcd);


void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)

{

struct s3c2410fb_mach_info *npd;


npd = kmalloc(sizeof(*npd), GFP_KERNEL);

if (npd) {

memcpy(npd, pd, sizeof(*npd));

s3c_device_lcd.dev.platform_data = npd;

} else {

printk(KERN_ERR "no memory for LCD platform data\n");

}

}


其中,S3C24XX_PA_IIC就是S3C24XX系列芯片的I2c基地址,它的定义在arch\arm\mach-s3c2410\include\mach目录下的map.h文件中,具体如下

/* LCD controller */

#define S3C24XX_PA_LCD      S3C2410_PA_LCD

#define S3C2410_PA_LCD   (0x4D000000)


基地址为0x4D000000,这样就和数据手册对应起来了

阅读(4287) | 评论(0) | 转发(0) |
0

上一篇:BITS_TO_LONGS

下一篇:platform_get_irq()

给主人留下些什么吧!~~