您的位置:首页 > 其它

i2c_probe()及I2C设备地址

2015-01-22 17:03 302 查看
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中的默认定义。

/* i2c_client_address_data is the struct for holding default client addresses for a driver and for the parameters supplied on the command line */
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. 作者自行定义地址结构
典型例子如下:
若自行定义,则参考如下:
/* Addresses to scan */
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进行初始化并注册的代码中。

结构体:

struct i2c_client_address_data {    

 const unsigned short *normal_i2c;                //该数组指定对每个适配器上的指定地址都进行探测
 const unsigned short *probe;                          //该数组是匹对出现的只对指定适配器的指定地址进行探测,前一个数是适配器后面是指该适配器的上的一个地址
 const unsigned short *ignore;                        //在进行normal_i2c探测是看看此中是否忽略,若忽略则放弃探测,其也是成对出现的,前者指适配器后者指地址
 const unsigned short * const *forces;          //强制使用的地址,确定某个地址代  表 的设备已经连接在总线上了。这个指针指向一个指针数组,每一个成员所

//指的内容也是每个适配器号后紧跟一个地址。

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: