Linux I2C子系统分析-I2C设备驱动 2

接下来以一个实际的例子来看I2C设备驱动,就以drivers/i2c/i2c-dev.c为例。

先看它的初始化和注销函数

  1. static int __init i2c_dev_init(void)  
  2. {  
  3.     int res;  
  4.   
  5.     printk(KERN_INFO "i2c /dev entries driver\n");  
  6.   
  7.     res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);  
  8.     if (res)  
  9.         goto out;  
  10.   
  11.     i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");  
  12.     if (IS_ERR(i2c_dev_class)) {  
  13.         res = PTR_ERR(i2c_dev_class);  
  14.         goto out_unreg_chrdev;  
  15.     }  
  16.   
  17.     res = i2c_add_driver(&i2cdev_driver);  
  18.     if (res)  
  19.         goto out_unreg_class;  
  20.   
  21.     return 0;  
  22.   
  23. out_unreg_class:  
  24.     class_destroy(i2c_dev_class);  
  25. out_unreg_chrdev:  
  26.     unregister_chrdev(I2C_MAJOR, "i2c");  
  27. out:  
  28.     printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);  
  29.     return res;  
  30. }  
  31.   
  32. static void __exit i2c_dev_exit(void)  
  33. {  
  34.     i2c_del_driver(&i2cdev_driver);  
  35.     class_destroy(i2c_dev_class);  
  36.     unregister_chrdev(I2C_MAJOR,"i2c");  
  37. }  

首先调用register_chrdev注册了一个字符设备,这是老的字符驱动注册方式。然后到了接下来的主角,i2c_add_driver,在I2C子系统中,I2C设备驱动就是采用这个函数注册,注销一个I2C设备驱动使用下面的i2c_del_driver函数,那就具体看看这个I2C设备驱动注册函数。

  1. static inline int i2c_add_driver(struct i2c_driver *driver)  
  2. {  
  3.     return i2c_register_driver(THIS_MODULE, driver);  
  4. }  
  5. int i2c_register_driver(struct module *owner, struct i2c_driver *driver)  
  6. {  
  7.     int res;  
  8.   
  9.     /* Can't register until after driver model init */  
  10.     if (unlikely(WARN_ON(!i2c_bus_type.p)))  
  11.         return -EAGAIN;  
  12.   
  13.     /* add the driver to the list of i2c drivers in the driver core */  
  14.     driver->driver.owner = owner;  
  15.     driver->driver.bus = &i2c_bus_type; /*指定驱动的总线类型*/  
  16.   
  17.     /* When registration returns, the driver core 
  18.      * will have called probe() for all matching-but-unbound devices. 
  19.      */  
  20.     res = driver_register(&driver->driver); /*注册驱动*/  
  21.     if (res)  
  22.         return res;  
  23.   
  24.     pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);  
  25.   
  26.     INIT_LIST_HEAD(&driver->clients);  
  27.     /* Walk the adapters that are already present */  
  28.     mutex_lock(&core_lock);  
  29.     bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);  
  30.     mutex_unlock(&core_lock);  
  31.   
  32.     return 0;  
  33. }  

再来看看i2c设备驱动注销函数

  1. void i2c_del_driver(struct i2c_driver *driver)  
  2. {  
  3.     mutex_lock(&core_lock);  
  4.     bus_for_each_dev(&i2c_bus_type, NULL, driver, __detach_adapter);  
  5.     mutex_unlock(&core_lock);  
  6.   
  7.     driver_unregister(&driver->driver);  
  8.     pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);  
  9. }  

也没什么,最后调用的就是驱动的注销函数driver_unregister函数。

来看传递给注册和注销i2c驱动函数的参数什么,i2cdev_driver它是structi2c_driver结构类型,i2c设备驱动就是使用这个结构类型描述,这个结构类型定义在include/linux/i2c.h

  1. struct i2c_driver {  
  2.     unsigned int class;  
  3.   
  4.     /* Notifies the driver that a new bus has appeared or is about to be 
  5.      * removed. You should avoid using this if you can, it will probably 
  6.      * be removed in a near future. 
  7.      */  
  8.     int (*attach_adapter)(struct i2c_adapter *);  
  9.     int (*detach_adapter)(struct i2c_adapter *);  
  10.   
  11.     /* Standard driver model interfaces */  
  12.     int (*probe)(struct i2c_client *, const struct i2c_device_id *);  
  13.     int (*remove)(struct i2c_client *);  
  14.   
  15.     /* driver model interfaces that don't relate to enumeration  */  
  16.     void (*shutdown)(struct i2c_client *);  
  17.     int (*suspend)(struct i2c_client *, pm_message_t mesg);  
  18.     int (*resume)(struct i2c_client *);  
  19.   
  20.     /* a ioctl like command that can be used to perform specific functions 
  21.      * with the device. 
  22.      */  
  23.     int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);  
  24.   
  25.     struct device_driver driver;  
  26.     const struct i2c_device_id *id_table;  
  27.   
  28.     /* Device detection callback for automatic device creation */  
  29.     int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);  
  30.     const struct i2c_client_address_data *address_data;  
  31.     struct list_head clients;  
  32. };  

来看i2c-dev.c中是怎么定义的

  1. static struct i2c_driver i2cdev_driver = {  
  2.     .driver = {  
  3.         .name   = "dev_driver",  
  4.     },  
  5.     .attach_adapter = i2cdev_attach_adapter,  
  6.     .detach_adapter = i2cdev_detach_adapter,  
  7. };  

这是老的方式,所以它只是给attach_adapterdetach_adapter赋了值,由于这里是老的方式,所以我们也就不去具体看这个函数了,我们直接去看它的数据传输部分吧。

  1. static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,  
  2.                             loff_t *offset)  
  3. {  
  4.     char *tmp;  
  5.     int ret;  
  6.   
  7.     struct i2c_client *client = (struct i2c_client *)file->private_data;  
  8.   
  9.     if (count > 8192)  
  10.         count = 8192;  
  11.   
  12.     tmp = kmalloc(count,GFP_KERNEL);  
  13.     if (tmp==NULL)  
  14.         return -ENOMEM;  
  15.   
  16.     pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",  
  17.         iminor(file->f_path.dentry->d_inode), count);  
  18.   
  19.     ret = i2c_master_recv(client,tmp,count);  
  20.     if (ret >= 0)  
  21.         ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;  
  22.     kfree(tmp);  
  23.     return ret;  
  24. }  

这是i2c设备读函数,我们看它是调用的i2c_master_recv函数去操作的,去看这个函数

  1. int i2c_master_recv(struct i2c_client *client, char *buf ,int count)  
  2. {  
  3.     struct i2c_adapter *adap=client->adapter;  
  4.     struct i2c_msg msg;  
  5.     int ret;  
  6.   
  7.     msg.addr = client->addr;  
  8.     msg.flags = client->flags & I2C_M_TEN;  
  9.     msg.flags |= I2C_M_RD;  
  10.     msg.len = count;  
  11.     msg.buf = buf;  
  12.   
  13.     ret = i2c_transfer(adap, &msg, 1);  
  14.   
  15.     /* If everything went ok (i.e. 1 msg transmitted), return #bytes 
  16.        transmitted, else error code. */  
  17.     return (ret == 1) ? count : ret;  
  18. }  

i2c设备写函数

  1. static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,  
  2.                              loff_t *offset)  
  3. {  
  4.     int ret;  
  5.     char *tmp;  
  6.     struct i2c_client *client = (struct i2c_client *)file->private_data;  
  7.   
  8.     if (count > 8192)  
  9.         count = 8192;  
  10.   
  11.     tmp = kmalloc(count,GFP_KERNEL);  
  12.     if (tmp==NULL)  
  13.         return -ENOMEM;  
  14.     if (copy_from_user(tmp,buf,count)) {  
  15.         kfree(tmp);  
  16.         return -EFAULT;  
  17.     }  
  18.   
  19.     pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",  
  20.         iminor(file->f_path.dentry->d_inode), count);  
  21.   
  22.     ret = i2c_master_send(client,tmp,count);  
  23.     kfree(tmp);  
  24.     return ret;  
  25. }  
  26. int i2c_master_send(struct i2c_client *client,const char *buf ,int count)  
  27. {  
  28.     int ret;  
  29.     struct i2c_adapter *adap=client->adapter;  
  30.     struct i2c_msg msg;  
  31.   
  32.     msg.addr = client->addr;  
  33.     msg.flags = client->flags & I2C_M_TEN;  
  34.     msg.len = count;  
  35.     msg.buf = (char *)buf;  
  36.   
  37.     ret = i2c_transfer(adap, &msg, 1);  
  38.   
  39.     /* If everything went ok (i.e. 1 msg transmitted), return #bytes 
  40.        transmitted, else error code. */  
  41.     return (ret == 1) ? count : ret;  
  42. }  

这两个函数最终都是调用的i2c_transfer函数去完成数据的传输,只是他们的msgflags不一样,读操作的flags要加上I2C_M_RD这个标志。

再看它们两个共同的i2c_transfer函数

  1. int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  
  2. {  
  3.     unsigned long orig_jiffies;  
  4.     int ret, try;  
  5.   
  6.     /* REVISIT the fault reporting model here is weak: 
  7.      * 
  8.      *  - When we get an error after receiving N bytes from a slave, 
  9.      *    there is no way to report "N". 
  10.      * 
  11.      *  - When we get a NAK after transmitting N bytes to a slave, 
  12.      *    there is no way to report "N" ... or to let the master 
  13.      *    continue executing the rest of this combined message, if 
  14.      *    that's the appropriate response. 
  15.      * 
  16.      *  - When for example "num" is two and we successfully complete 
  17.      *    the first message but get an error part way through the 
  18.      *    second, it's unclear whether that should be reported as 
  19.      *    one (discarding status on the second message) or errno 
  20.      *    (discarding status on the first one). 
  21.      */  
  22.   
  23.     if (adap->algo->master_xfer) {  
  24. #ifdef DEBUG   
  25.         for (ret = 0; ret < num; ret++) {  
  26.             dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "  
  27.                 "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)  
  28.                 ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,  
  29.                 (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");  
  30.         }  
  31. #endif   
  32.   
  33.         if (in_atomic() || irqs_disabled()) {  
  34.             ret = mutex_trylock(&adap->bus_lock);  
  35.             if (!ret)  
  36.                 /* I2C activity is ongoing. */  
  37.                 return -EAGAIN;  
  38.         } else {  
  39.             mutex_lock_nested(&adap->bus_lock, adap->level);  
  40.         }  
  41.   
  42.         /* Retry automatically on arbitration loss */  
  43.         orig_jiffies = jiffies;  
  44.         for (ret = 0, try = 0; try <= adap->retries; try++) {  
  45.             ret = adap->algo->master_xfer(adap, msgs, num);  
  46.             if (ret != -EAGAIN)  
  47.                 break;  
  48.             if (time_after(jiffies, orig_jiffies + adap->timeout))  
  49.                 break;  
  50.         }  
  51.         mutex_unlock(&adap->bus_lock);  
  52.   
  53.         return ret;  
  54.     } else {  
  55.         dev_dbg(&adap->dev, "I2C level transfers not supported\n");  
  56.         return -EOPNOTSUPP;  
  57.     }  
  58. }  

我们看就是调用总线的master_xfer方法,我们在前面分析使用gpio模拟i2c总线时,看过这样一句 .master_xfer =bit_xfer, ,所以最终调用的是这个函数来完成数据传输。使用i2c_master_recvi2c_master_send函数一次只能传输一个msg,由于它一次只能传输一个msg,所以它的传输方向不能改变,也就是一次只能完成读或写操作,并且读操作时还不能传递设备的基地址,所以通常是不会用这两个函数的,直接的做法时,构造两个msg,一个msg的数据为操作设备基地址,另外一个msg才是我们真正要读写的数据,最后调用i2c_transfer函数去完成数据的传送。










http://blog.csdn.net/mcgrady_tracy/article/details/7211048
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值