Chinaunix首页 | 论坛 | 博客
  • 博客访问: 143231
  • 博文数量: 60
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-05 15:39
文章存档

2016年(6)

2015年(36)

2014年(13)

2013年(5)

我的朋友

分类: LINUX

2015-06-12 15:48:51

I2C的设备驱动是通过i2c_add_driver(&my_driver)向i2c-core注册的,my_driver中的核心是detach和attach函数,在attach中通过probe探测到总线上的设备并把设备和驱动建立连接以完成设备的初始化。如何探测总线上的设备、Linux中i2c设备地址如何标识并引用?

I2C中, 典型的attach如下所示:
static int my_attach(struct i2c_adapter *adapter)
{
    return i2c_probe(adapter, &addr_data, my_probe);
}
static int my_probe(struct i2c_adapter *adapter, int address, int kind)
{
    ..........
}
addr_data是在 include/linux/i2c.h 中定义的或自己在自己驱动程序中定义的一个i2c_client_address_data结构:
static struct i2c_client_address_data addr_data = {            \
    .normal_i2c    = normal_i2c,                    \
    .probe        = probe,                    \
    .ignore        = ignore,                    \
    .forces        = forces,                    \
}
若自己不定义,则用i2c.h中的默认定义。
struct i2c_client_address_data {
    unsigned short *normal_i2c;
    unsigned short *probe;
    unsigned short *ignore;
    unsigned short **forces;
};
根据作者自行定义设备地址与否,有两种情形:
a. 采用默认定义,一般是不会work,毕竟大多数i2c-core中是不可能提前知道所接设备地址的,这样通过i2c_probe()探测肯定不可能找到,也不可能建立两者之间的联系;
况且,i2c_probe()属于i2c-core中的函数,i2c-core中管理着所有注册过的设备和驱动列表,i2c_probe()中也不能随意传入地址,否则容易导致系统混乱或有潜在的风险,
所以i2c-core也不允许这么做!
b. 作者自行定义地址结构
典型例子如下:
若自行定义,则参考如下:
static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
                       I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};/// 实际设备的地址List
static unsigned short probe[2] =    {I2C_CLIENT_END, I2C_CLIENT_END};
static unsigned short ignore[2] =     {I2C_CLIENT_END, I2C_CLIENT_END};
static struct i2c_client_address_data addr_data = {
    normal_i2c,
    probe,
    ignore,
};
或者根本就不定义完整的i2c_client_address_data结构,只根据需要定义normal_i2c[],probe[],ignore[],forces[][],然后调用
i2c_probe(adapter,&addr_data, &my_probe) 即可。
在my_probe()中把实际的地址赋于i2c_client,调用i2c_set_clientdata()设置i2c_client->dev->drv_data,并调用i2c_attach_client(client)向系统注册设备。
最后,i2c_probe()中探测时的地址优先级:
forces[][], probe[], normal_i2c[](其中忽略ignore[]中的项)。
I2c设备在实际使用中比较广泛,sensor,rtc,audio, codec,etc. 因设备复杂性不同,Linux中有些驱动中对地址的定义不在同一文件,这时多数情况都在arch中对设备作为
platform_device进行初始化并注册的代码中。

阅读(2325) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~