Linux 驱动i2c -- Gsenser(一)

本文深入剖析了Linux平台下I2C子系统的设备驱动模型,从初始化到具体函数调用,详细介绍了lis3lv02d_i2c_driver的结构与功能,并探讨了i2c_add_driver的工作原理。
看linux平台的驱动程序,一切都从那对欢喜冤家开始。
    且看代码:
323 module_init(lis3lv02d_i2c_init);
324 module_exit(lis3lv02d_i2c_exit);

了解与不了解linux设备驱动模型的弟兄们都知道,这两行的意思,就不多说了。
根据前面代码的指示前去阅读lis3lv02d_i2c_init函数。

306 static int __init lis3lv02d_i2c_init(void)
307 {
308   return i2c_add_driver(&lis3lv02d_i2c_driver);
309 }

这个函数看起来似乎没什么内容,只是一句简单的i2c_add_driver调用。调用的是什么东东呢?
&lis3lv02d_i2c_driver,跟谭浩强大哥学过几天c的兄弟都知道,这是一个指针变量,
指向的东西可能是康庄大道也可能是万丈深渊,不去看,永远不知道下一步到底是什么。
如诗所云,劝君更进一杯酒,西出阳关无故人!
将要开始的征程,对于初学的我们而言,全都是未知的x。
对于大神之辈,这连小儿科都不算……
方才说到i2c_add_driver()调用的参数是&lis3lv02d_i2c_driver,我们来看看它的定义和赋值
且看代码:
295 static struct i2c_driver lis3lv02d_i2c_driver = {
296   .driver = {
297     .name = "lis3lv02d",
298   },
299   .id_table   = lis3lv02d_i2c_id,
300   .probe    = lis3lv02d_i2c_probe,
301   .remove   = lis3lv02d_i2c_remove,
302   .suspend  = lis3lv02d_i2c_suspend,
303   .resume   = lis3lv02d_i2c_resume,
304 };

光看这么一堆东东,如果刚开始学习的兄弟,可能会一头雾水,这都在“闹啥捏”。
所以,必须把这个结构体变量的母体(定义)列出来给大家瞅瞅。
定义在文件kernel/incluce/linux/i2c.h中:
99 /**
100  * struct i2c_driver - represent an I2C device driver
101  * @class: What kind of i2c device we instantiate (for detect)
102  * @attach_adapter: Callback for bus addition (for legacy drivers)
103  * @detach_adapter: Callback for bus removal (for legacy drivers)
104  * @probe: Callback for device binding
105  * @remove: Callback for device unbinding
106  * @shutdown: Callback for device shutdown
107  * @suspend: Callback for device suspend
108  * @resume: Callback for device resume
109  * @command: Callback for bus-wide signaling (optional)
110  * @driver: Device driver model driver
111  * @id_table: List of I2C devices supported by this driver
112  * @detect: Callback for device detection
113  * @address_data: The I2C addresses to probe, ignore or force (for detect)
114  * @clients: List of detected clients we created (for i2c-core use only)
115  *
116 * The driver.owner field should be set to the module owner of this driver.
117  * The driver.name field should be set to the name of this driver.
118  *
119  * For automatic device detection, both @detect and @address_data must
120  * be defined. @class should also be set, otherwise only devices forced
121  * with module parameters will be created. The detect function must
122  * fill at least the name field of the i2c_board_info structure it is
123  * handed upon successful detection, and possibly also the flags field.
124  *
125  * If @detect is missing, the driver will still work fine for enumerated
126  * devices. Detected devices simply won't be supported. This is expected
127  * for the many I2C/SMBus devices which can't be detected reliably, and
128  * the ones which can always be enumerated in practice.
129  *
130  * The i2c_client structure which is handed to the @detect callback is
131  * not a real i2c_client. It is initialized just enough so that you can
132  * call i2c_smbus_read_byte_data and friends on it. Don't do anything
133  * else with it. In particular, calling dev_dbg and friends on it is
134  * not allowed.
135  */
136 struct i2c_driver {
137   unsigned int class;
138
139   /* Notifies the driver that a new bus has appeared or is about to be
140    * removed. You should avoid using this if you can, it will probably
141    * be removed in a near future.
142    */
143   int (*attach_adapter)(struct i2c_adapter *);
144   int (*detach_adapter)(struct i2c_adapter *);
145
146   /* Standard driver model interfaces */
147   int (*probe)(struct i2c_client *, const struct i2c_device_id *);
148   int (*remove)(struct i2c_client *);
149
150   /* driver model interfaces that don't relate to enumeration  */
151   void (*shutdown)(struct i2c_client *);
152   int (*suspend)(struct i2c_client *, pm_message_t mesg);
153   int (*resume)(struct i2c_client *);
154
155   /* a ioctl like command that can be used to perform specific functions
156    * with the device.
157    */
158   int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
159
160   struct device_driver driver;
161   const struct i2c_device_id *id_table;
162
163   /* Device detection callback for automatic device creation */
164   int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);
165   const struct i2c_client_address_data *address_data;
166   struct list_head clients;
167 };
168 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)

这个结构体,相比它在USB子系统里的各位兄弟姐妹而言,可谓小巧玲珑,聊聊数十行而已,
可别小看了这么简单一个结构体,i2c子系统中的设备端驱动,全靠他来实现与i2c core
进行交互,实现通信功能,可谓小而强大!人不可貌相,结构体不能行量,就是这个道理。

看完了这个结构体,我们来看看这个结构体变量被添加到了哪里。
来找找i2c_add_driver()这个函数的定义。
也在kernel/incluce/linux/i2c.h中:

429 static inline int i2c_add_driver(struct i2c_driver *driver)
430 {
431   return i2c_register_driver(THIS_MODULE, driver);
432 }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值