接下来以一个实际的例子来看I2C设备驱动,就以drivers/i2c/i2c-dev.c为例。
先看它的初始化和注销函数
- static int __init i2c_dev_init(void)
- {
- int res;
- printk(KERN_INFO "i2c /dev entries driver\n");
- res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
- if (res)
- goto out;
- i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
- if (IS_ERR(i2c_dev_class)) {
- res = PTR_ERR(i2c_dev_class);
- goto out_unreg_chrdev;
- }
- res = i2c_add_driver(&i2cdev_driver);
- if (res)
- goto out_unreg_class;
- return 0;
- out_unreg_class:
- class_destroy(i2c_dev_class);
- out_unreg_chrdev:
- unregister_chrdev(I2C_MAJOR, "i2c");
- out:
- printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
- return res;
- }
- static void __exit i2c_dev_exit(void)
- {
- i2c_del_driver(&i2cdev_driver);
- class_destroy(i2c_dev_class);
- unregister_chrdev(I2C_MAJOR,"i2c");
- }
首先调用register_chrdev注册了一个字符设备,这是老的字符驱动注册方式。然后到了接下来的主角,i2c_add_driver,在I2C子系统中,I2C设备驱动就是采用这个函数注册,注销一个I2C设备驱动使用下面的i2c_del_driver函数,那就具体看看这个I2C设备驱动注册函数。
- static inline int i2c_add_driver(struct i2c_driver *driver)
- {
- return i2c_register_driver(THIS_MODULE, driver);
- }
- int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
- {
- int res;
- /* Can't register until after driver model init */
- if (unlikely(WARN_ON(!i2c_bus_type.p)))
- return -EAGAIN;
- /* add the driver to the list of i2c drivers in the driver core */
- driver->driver.owner = owner;
- driver->driver.bus = &i2c_bus_type; /*指定驱动的总线类型*/
- /* When registration returns, the driver core
- * will have called probe() for all matching-but-unbound devices.
- */
- res = driver_register(&driver->driver); /*注册驱动*/
- if (res)
- return res;
- pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
- INIT_LIST_HEAD(&driver->clients);
- /* Walk the adapters that are already present */
- mutex_lock(&core_lock);
- bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
- mutex_unlock(&core_lock);
- return 0;
- }
再来看看i2c设备驱动注销函数
- void i2c_del_driver(struct i2c_driver *driver)
- {
- mutex_lock(&core_lock);
- bus_for_each_dev(&i2c_bus_type, NULL, driver, __detach_adapter);
- mutex_unlock(&core_lock);
- driver_unregister(&driver->driver);
- pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
- }
也没什么,最后调用的就是驱动的注销函数driver_unregister函数。
来看传递给注册和注销i2c驱动函数的参数什么,i2cdev_driver它是structi2c_driver结构类型,i2c设备驱动就是使用这个结构类型描述,这个结构类型定义在include/linux/i2c.h
- struct i2c_driver {
- unsigned int class;
- /* Notifies the driver that a new bus has appeared or is about to be
- * removed. You should avoid using this if you can, it will probably
- * be removed in a near future.
- */
- int (*attach_adapter)(struct i2c_adapter *);
- int (*detach_adapter)(struct i2c_adapter *);
- /* Standard driver model interfaces */
- int (*probe)(struct i2c_client *, const struct i2c_device_id *);
- int (*remove)(struct i2c_client *);
- /* driver model interfaces that don't relate to enumeration */
- void (*shutdown)(struct i2c_client *);
- int (*suspend)(struct i2c_client *, pm_message_t mesg);
- int (*resume)(struct i2c_client *);
- /* a ioctl like command that can be used to perform specific functions
- * with the device.
- */
- int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- struct device_driver driver;
- const struct i2c_device_id *id_table;
- /* Device detection callback for automatic device creation */
- int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);
- const struct i2c_client_address_data *address_data;
- struct list_head clients;
- };
来看i2c-dev.c中是怎么定义的
- static struct i2c_driver i2cdev_driver = {
- .driver = {
- .name = "dev_driver",
- },
- .attach_adapter = i2cdev_attach_adapter,
- .detach_adapter = i2cdev_detach_adapter,
- };
这是老的方式,所以它只是给attach_adapter和detach_adapter赋了值,由于这里是老的方式,所以我们也就不去具体看这个函数了,我们直接去看它的数据传输部分吧。
- static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
- loff_t *offset)
- {
- char *tmp;
- int ret;
- struct i2c_client *client = (struct i2c_client *)file->private_data;
- if (count > 8192)
- count = 8192;
- tmp = kmalloc(count,GFP_KERNEL);
- if (tmp==NULL)
- return -ENOMEM;
- pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
- iminor(file->f_path.dentry->d_inode), count);
- ret = i2c_master_recv(client,tmp,count);
- if (ret >= 0)
- ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
- kfree(tmp);
- return ret;
- }
这是i2c设备读函数,我们看它是调用的i2c_master_recv函数去操作的,去看这个函数
- int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
- {
- struct i2c_adapter *adap=client->adapter;
- struct i2c_msg msg;
- int ret;
- msg.addr = client->addr;
- msg.flags = client->flags & I2C_M_TEN;
- msg.flags |= I2C_M_RD;
- msg.len = count;
- msg.buf = buf;
- ret = i2c_transfer(adap, &msg, 1);
- /* If everything went ok (i.e. 1 msg transmitted), return #bytes
- transmitted, else error code. */
- return (ret == 1) ? count : ret;
- }
i2c设备写函数
- static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,
- loff_t *offset)
- {
- int ret;
- char *tmp;
- struct i2c_client *client = (struct i2c_client *)file->private_data;
- if (count > 8192)
- count = 8192;
- tmp = kmalloc(count,GFP_KERNEL);
- if (tmp==NULL)
- return -ENOMEM;
- if (copy_from_user(tmp,buf,count)) {
- kfree(tmp);
- return -EFAULT;
- }
- pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
- iminor(file->f_path.dentry->d_inode), count);
- ret = i2c_master_send(client,tmp,count);
- kfree(tmp);
- return ret;
- }
- int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
- {
- int ret;
- struct i2c_adapter *adap=client->adapter;
- struct i2c_msg msg;
- msg.addr = client->addr;
- msg.flags = client->flags & I2C_M_TEN;
- msg.len = count;
- msg.buf = (char *)buf;
- ret = i2c_transfer(adap, &msg, 1);
- /* If everything went ok (i.e. 1 msg transmitted), return #bytes
- transmitted, else error code. */
- return (ret == 1) ? count : ret;
- }
这两个函数最终都是调用的i2c_transfer函数去完成数据的传输,只是他们的msg的flags不一样,读操作的flags要加上I2C_M_RD这个标志。
再看它们两个共同的i2c_transfer函数
- int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
- {
- unsigned long orig_jiffies;
- int ret, try;
- /* REVISIT the fault reporting model here is weak:
- *
- * - When we get an error after receiving N bytes from a slave,
- * there is no way to report "N".
- *
- * - When we get a NAK after transmitting N bytes to a slave,
- * there is no way to report "N" ... or to let the master
- * continue executing the rest of this combined message, if
- * that's the appropriate response.
- *
- * - When for example "num" is two and we successfully complete
- * the first message but get an error part way through the
- * second, it's unclear whether that should be reported as
- * one (discarding status on the second message) or errno
- * (discarding status on the first one).
- */
- if (adap->algo->master_xfer) {
- #ifdef DEBUG
- for (ret = 0; ret < num; ret++) {
- dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
- "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
- ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
- (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
- }
- #endif
- if (in_atomic() || irqs_disabled()) {
- ret = mutex_trylock(&adap->bus_lock);
- if (!ret)
- /* I2C activity is ongoing. */
- return -EAGAIN;
- } else {
- mutex_lock_nested(&adap->bus_lock, adap->level);
- }
- /* Retry automatically on arbitration loss */
- orig_jiffies = jiffies;
- for (ret = 0, try = 0; try <= adap->retries; try++) {
- ret = adap->algo->master_xfer(adap, msgs, num);
- if (ret != -EAGAIN)
- break;
- if (time_after(jiffies, orig_jiffies + adap->timeout))
- break;
- }
- mutex_unlock(&adap->bus_lock);
- return ret;
- } else {
- dev_dbg(&adap->dev, "I2C level transfers not supported\n");
- return -EOPNOTSUPP;
- }
- }
我们看就是调用总线的master_xfer方法,我们在前面分析使用gpio模拟i2c总线时,看过这样一句 .master_xfer =bit_xfer, ,所以最终调用的是这个函数来完成数据传输。使用i2c_master_recv和i2c_master_send函数一次只能传输一个msg,由于它一次只能传输一个msg,所以它的传输方向不能改变,也就是一次只能完成读或写操作,并且读操作时还不能传递设备的基地址,所以通常是不会用这两个函数的,直接的做法时,构造两个msg,一个msg的数据为操作设备基地址,另外一个msg才是我们真正要读写的数据,最后调用i2c_transfer函数去完成数据的传送。
http://blog.csdn.net/mcgrady_tracy/article/details/7211048