免费注册 查看新帖 |

Chinaunix

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

i2c eeprom driver [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-30 15:31 |只看该作者 |倒序浏览
10可用积分
在linux/drivers/i2c/chips 下有eeprom.c driver, 本人想试着锻炼i2c driver编写能力。但是遇到问题了。 望高手赐教。
我的步骤
1. 在arch/arm/mach-s3c2410/mach-smdk2410.c
static struct i2c_board_info __initdata i2c_devices[] =
{
    {   
        I2C_BOARD_INFO("rtc-s35390a", 0x30),
        .platform_data = &s35390a,
    },  
    {   
        I2C_BOARD_INFO("eeprom",0x50),
    },  

};
并且在smdk2410_init()函数后面调用
i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
添加i2c device信息

2. 在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };

3. 在insmod eeprom.ko时
在eeprom.c 调用了
i2c_probe(adapter, &addr_data, eeprom_detect);
并且返回0,但是并没有运行 static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind), lsmod可知道模块已经加入。 为什么不会调用eeprom_detect函数?

问题1
为什么没有调用eeprom_detect函数?

问题2
每个i2cdevice都需要在arch/mach-s3c2410/下加入i2c_board_info信息结构吗?那样device变了一下都要重新编译内核的,挺麻烦的。

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2008-12-30 16:04 |只看该作者

回复 #1 studyboy_3w 的帖子

看看这个文档吧

I2C设备与驱动的关联.rar

28.13 KB, 下载次数: 1407

论坛徽章:
0
3 [报告]
发表于 2008-12-30 17:00 |只看该作者
Very useful. So thanks.

但是它只是详细介绍如何注册和注销device/driver。 并没有涉及到我上面的几个问题?

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
4 [报告]
发表于 2008-12-30 17:12 |只看该作者
问题1:你期望的是在什么情况下会调用eeprom_detect?程序的执行调度很大程度上取决于你编写的代码,而即使是内核的调度点,你也可以控制的;
问题2:不需要编译内核,编译模块再加载就ok了。这个是静态的信息,所以,怎么写在于你程序中赋予它什么样的功能和作用。

论坛徽章:
0
5 [报告]
发表于 2008-12-31 09:08 |只看该作者
问题1:你期望的是在什么情况下会调用eeprom_detect?程序的执行调度很大程度上取决于你编写的代码,而即使是内核的调度点,你也可以控制的;

模块一加载, 根据eeprom.c,它的流程应该是,
eeprom_init->i2c_add_driver->eeprom_attach_adapter->i2c_probe->eeprom_detect.
但是我这里不知道为什么不会调用eeprom_detect。
如果我加入多个地址,那么就会调用eeprom_detect。如:
static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
                      0x55, 0x56, 0x57, I2C_CLIENT_END };

问题2:不需要编译内核,编译模块再加载就ok了。这个是静态的信息,所以,怎么写在于你程序中赋予它什么样的功能和作用。

由于在arch/arm/mach-s3c2410/mach-smdk2410.c增加了代码(如下),那么应该要重新一次编译内核。
static struct i2c_board_info __initdata i2c_devices[] =
{
    {   
        I2C_BOARD_INFO("rtc-s35390a", 0x30),
        .platform_data = &s35390a,
    },  
    {   
        I2C_BOARD_INFO("eeprom",0x50),
    },  

};
如果不需要重新编译内核,除非上面代码不用添加进去。如果这样,那么i2c_probe(adapter, &addr_data, eeprom_detect)又如何找到设备呢?我想版主意思是编译eeprom.ko不需要重新编译内核,是不?

还有另外一个问题:
要增加i2c 和spi设备,必须在系统启动前就加入设备信息吗?
如spi要在arch/mach-**/mach-**.c 加入spi_board_info 然后就调用spi_register_board_info
如i2c要在arch/mach-**/mach-**.c 加入i2c_board_info 然后就调用i2c_register_board_info
如果这样,那么增加一个i2c/spi设备,就需要重新编译更新一起内核,是这样的吗?

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
6 [报告]
发表于 2008-12-31 09:49 |只看该作者

回复 #5 studyboy_3w 的帖子

第一个问题,你加一些调试打印信息,看一下执行流程中,为什么没有到达你需要调用的函数;
第二个问题,其实你完全没有必要重新编译内核,除非内核中有很多地方都引用到了你的这个静态结构信息,模块加载就足以实现了。

后面的问题:
在什么时候加入信息,关键在于你对这个程序的理解。它需要什么时候被调用?其他模块是否会引用到它?内核启动的时候是不是会配置它?这些搞明白了就知道了,如果只是一个独立的模块,没有其他的依赖关系,那加载点就可以随心所欲了。

论坛徽章:
0
7 [报告]
发表于 2009-01-05 15:17 |只看该作者
Thanks a lot.

论坛徽章:
0
8 [报告]
发表于 2009-01-05 17:05 |只看该作者
原帖由 studyboy_3w 于 2008-12-30 15:31 发表
在linux/drivers/i2c/chips 下有eeprom.c driver, 本人想试着锻炼i2c driver编写能力。但是遇到问题了。 望高手赐教。
我的步骤
1. 在arch/arm/mach-s3c2410/mach-smdk2410.c
static struct i2c_board_info ...



你设备的地址是0x50吗?
I2C核心会根据你提供的这个地址去呼叫你的设备,如果收到设备返回的ACK,这是才会调用eeprom_detect函数来向sys子系统注册接口。

尝试一下不同的地址,记得I2C核心吧设备地址做偏移。

论坛徽章:
0
9 [报告]
发表于 2009-01-06 08:37 |只看该作者
对, 我加多一个地址,就会调用那个函数。如:
在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51,I2C_CLIENT_END };

为什么0x50不可以呢? 这个0x50地址是如何得来的?

论坛徽章:
0
10 [报告]
发表于 2009-01-06 09:05 |只看该作者
原帖由 studyboy_3w 于 2009-1-6 08:37 发表
对, 我加多一个地址,就会调用那个函数。如:
在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51,I2C_CLIENT_END };

为什么0x50不可以呢? 这个0x50地址是如 ...


配合电路图,你看器件手册上是怎么说的,一般I2C设备根据外部一两个引脚的高低电平选择不同的地址,避免和总线上其它设备地址冲突。

怀疑你的地址是0X51,可以试试把0X50去掉,只要0x51来验证一下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP