zoukankan      html  css  js  c++  java
  • linux驱动之I2C

    include/linux/i2c.h

    struct i2c_msg;
    struct i2c_algorithm;
    struct i2c_adapter;
    struct i2c_client;
    struct i2c_driver;
    union i2c_smbus_data;

    I2C驱动主要包含三部分:I2C核心、I2C总线驱动、I2C设备驱动,它们主要的数据结构在目录:/include/linux/i2c.h

      struct i2c_driver

     1 /*
     2  * A driver is capable of handling one or more physical devices present on
     3  * I2C adapters. This information is used to inform the driver of adapter
     4  * events.
     5  *
     6  * The driver.owner field should be set to the module owner of this driver.
     7  * The driver.name field should be set to the name of this driver.
     8  */
     9 struct i2c_driver {
    10     int id;
    11     unsigned int class;
    12 
    13     /* Notifies the driver that a new bus has appeared. This routine
    14      * can be used by the driver to test if the bus meets its conditions
    15      * & seek for the presence of the chip(s) it supports. If found, it
    16      * registers the client(s) that are on the bus to the i2c admin. via
    17      * i2c_attach_client.  (LEGACY I2C DRIVERS ONLY)
    18      */
    19     int (*attach_adapter)(struct i2c_adapter *);
    20     int (*detach_adapter)(struct i2c_adapter *);
    21 
    22     /* tells the driver that a client is about to be deleted & gives it
    23      * the chance to remove its private data. Also, if the client struct
    24      * has been dynamically allocated by the driver in the function above,
    25      * it must be freed here.  (LEGACY I2C DRIVERS ONLY)
    26      */
    27     int (*detach_client)(struct i2c_client *);
    28 
    29     /* Standard driver model interfaces, for "new style" i2c drivers.
    30      * With the driver model, device enumeration is NEVER done by drivers;
    31      * it's done by infrastructure.  (NEW STYLE DRIVERS ONLY)
    32      */
    33     int (*probe)(struct i2c_client *);
    34     int (*remove)(struct i2c_client *);
    35 
    36     /* driver model interfaces that don't relate to enumeration  */
    37     void (*shutdown)(struct i2c_client *);
    38     int (*suspend)(struct i2c_client *, pm_message_t mesg);
    39     int (*resume)(struct i2c_client *);
    40 
    41     /* a ioctl like command that can be used to perform specific functions
    42      * with the device.
    43      */
    44     int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
    45 
    46     struct device_driver driver;
    47     struct list_head list;
    48 };

      struct i2c_client

     1 /**
     2  * struct i2c_client - represent an I2C slave device
     3  * @addr: Address used on the I2C bus connected to the parent adapter.
     4  * @name: Indicates the type of the device, usually a chip name that's
     5  *    generic enough to hide second-sourcing and compatible revisions.
     6  * @dev: Driver model device node for the slave.
     7  * @driver_name: Identifies new-style driver used with this device; also
     8  *    used as the module name for hotplug/coldplug modprobe support.
     9  *
    10  * An i2c_client identifies a single device (i.e. chip) connected to an
    11  * i2c bus. The behaviour is defined by the routines of the driver.
    12  */
    13 struct i2c_client {
    14     unsigned short flags;        /* div., see below        */
    15     unsigned short addr;        /* chip address - NOTE: 7bit    */
    16                     /* addresses are stored in the    */
    17                     /* _LOWER_ 7 bits        */
    18     char name[I2C_NAME_SIZE];
    19     struct i2c_adapter *adapter;    /* the adapter we sit on    */
    20     struct i2c_driver *driver;    /* and our access routines    */
    21     int usage_count;        /* How many accesses currently  */
    22                     /* to the client        */
    23     struct device dev;        /* the device structure        */
    24     int irq;            /* irq issued by device (or -1) */
    25     char driver_name[KOBJ_NAME_LEN];
    26     struct list_head list;
    27     struct completion released;
    28 };

      struct i2c_algorithm

     1 /*
     2  * The following structs are for those who like to implement new bus drivers:
     3  * i2c_algorithm is the interface to a class of hardware solutions which can
     4  * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
     5  * to name two of the most common.
     6  */
     7 struct i2c_algorithm {
     8     /* If an adapter algorithm can't do I2C-level access, set master_xfer
     9        to NULL. If an adapter algorithm can do SMBus access, set
    10        smbus_xfer. If set to NULL, the SMBus protocol is simulated
    11        using common I2C messages */
    12     /* master_xfer should return the number of messages successfully
    13        processed, or a negative value on error */
    14     int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
    15                        int num);
    16     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
    17                        unsigned short flags, char read_write,
    18                        u8 command, int size, union i2c_smbus_data * data);
    19 
    20     /* --- ioctl like call to set div. parameters. */
    21     int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);
    22 
    23     /* To determine what the adapter supports */
    24     u32 (*functionality) (struct i2c_adapter *);
    25 };

      struct i2c_adapter

      

     1 /*
     2  * i2c_adapter is the structure used to identify a physical i2c bus along
     3  * with the access algorithms necessary to access it.
     4  */
     5 struct i2c_adapter {
     6     struct module *owner;
     7     unsigned int id;
     8     unsigned int class;
     9     const struct i2c_algorithm *algo; /* the algorithm to access the bus */
    10     void *algo_data;
    11 
    12     /* --- administration stuff. */
    13     int (*client_register)(struct i2c_client *);
    14     int (*client_unregister)(struct i2c_client *);
    15 
    16     /* data fields that are valid for all devices    */
    17     u8 level;             /* nesting level for lockdep */
    18     struct mutex bus_lock;
    19     struct mutex clist_lock;
    20 
    21     int timeout;
    22     int retries;
    23     struct device dev;        /* the adapter device */
    24 
    25     int nr;
    26     struct list_head clients;
    27     struct list_head list;
    28     char name[48];
    29     struct completion dev_released;
    30 }

    I2C核心

      I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(algorithm)上层的与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。

    I2C总线驱动

      I2C总线驱动是对I2C硬件体系结构中适配器段端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。I2C总线驱动主要包括I2C适配器数据结构i2c_adapter、I2C适配器的Algorithm数据结构i2c_algorithm和控制I2C适配器产生通信信号的函数。经由I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生开始位、停止位、读写周期,以及从设备方式读写、产生ACK等。

    I2C设备驱动

         I2C设备驱动即客户驱动时对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。I2C设备驱动主要包含数据结构i2c_driver和i2c_client,我们需要具体设备实现其中的成员函数。

      在linux2.6内核中,所有设备都在sysfs文件系统中显示,在sysfs虚拟文件系统中存放了驱动挂载的总线以及device、driver,当我们注册一个driver后,内核会将我们注册的这个driver添加到这类驱动总线上这类总线的拥有一个共同的类似于一个基类kobject,而kset就是koject的一个集合。我们在写驱动的时候一般不会去分析kobject、kset,毕竟他们在内核里面是非常顶层的软件抽象层,但是对于内核整个驱动框架,却不能不分析这类抽象层,下图是我在树莓派所做的截图:

      我们可以看到在sys文件目录下面有bus、class等,进入bus后会看到各种设备驱动,如在I2C中我们可以看到device、drivers,当然这些目录下面都没有什么内容应为sysfs是一个虚拟文件系统主要是记录各个进程和内核方面的信息。我们的驱动设备如何和虚拟文件系统产生关系了呢,就是kobject在这儿起了作用,我们的device、driver最终都会挂载一个总线上,后面我们会看到sysfs申请内存为device或者driver建立节点。

      同样注册一个device后也会挂载在总线上。其实I2C我们也可以看成设备-总线-驱动模型,

      i2c_register_driver(THIS_MODULE, driver)

     1 /*
     2  * An i2c_driver is used with one or more i2c_client (device) nodes to access
     3  * i2c slave chips, on a bus instance associated with some i2c_adapter.  There
     4  * are two models for binding the driver to its device:  "new style" drivers
     5  * follow the standard Linux driver model and just respond to probe() calls
     6  * issued if the driver core sees they match(); "legacy" drivers create device
     7  * nodes themselves.
     8  */
     9 
    10 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
    11 {
    12     int res;
    13 
    14     /* new style driver methods can't mix with legacy ones */
    15     if (is_newstyle_driver(driver)) {
    16         if (driver->attach_adapter || driver->detach_adapter
    17                 || driver->detach_client) {
    18             printk(KERN_WARNING
    19                     "i2c-core: driver [%s] is confused
    ",
    20                     driver->driver.name);
    21             return -EINVAL;
    22         }
    23     }
    24 
    25     /* add the driver to the list of i2c drivers in the driver core */
    26     driver->driver.owner = owner;
    27     driver->driver.bus = &i2c_bus_type;
    28 
    29     /* for new style drivers, when registration returns the driver core
    30      * will have called probe() for all matching-but-unbound devices.
    31      */
    32     res = driver_register(&driver->driver);
    33     if (res)
    34         return res;
    35 
    36     mutex_lock(&core_lists);
    37 
    38     list_add_tail(&driver->list,&drivers);
    39     pr_debug("i2c-core: driver [%s] registered
    ", driver->driver.name);
    40 
    41     /* legacy drivers scan i2c busses directly */
    42     if (driver->attach_adapter) {
    43         struct i2c_adapter *adapter;
    44 
    45         list_for_each_entry(adapter, &adapters, list) {
    46             driver->attach_adapter(adapter);
    47         }
    48     }
    49 
    50     mutex_unlock(&core_lists);
    51     return 0;
    52 }

      driver_register(&driver->driver);

      

     1 /**
     2  *    driver_register - register driver with bus
     3  *    @drv:    driver to register
     4  *
     5  *    We pass off most of the work to the bus_add_driver() call,
     6  *    since most of the things we have to do deal with the bus
     7  *    structures.
     8  */
     9 int driver_register(struct device_driver * drv)
    10 {
    11     if ((drv->bus->probe && drv->probe) ||
    12         (drv->bus->remove && drv->remove) ||
    13         (drv->bus->shutdown && drv->shutdown)) {
    14         printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods
    ", drv->name);
    15     }
    16     klist_init(&drv->klist_devices, NULL, NULL);
    17     return bus_add_driver(drv);
    18 }

      klist_init(&drv->klist_devices, NULL, NULL);

      

     1 /**
     2  *    driver_register - register driver with bus
     3  *    @drv:    driver to register
     4  *
     5  *    We pass off most of the work to the bus_add_driver() call,
     6  *    since most of the things we have to do deal with the bus
     7  *    structures.
     8  */
     9 int driver_register(struct device_driver * drv)
    10 {
    11     if ((drv->bus->probe && drv->probe) ||
    12         (drv->bus->remove && drv->remove) ||
    13         (drv->bus->shutdown && drv->shutdown)) {
    14         printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods
    ", drv->name);
    15     }
    16     klist_init(&drv->klist_devices, NULL, NULL);
    17     return bus_add_driver(drv);
    18 }
      bus_add_driver(drv);
     1 /**
     2  *    bus_add_driver - Add a driver to the bus.
     3  *    @drv:    driver.
     4  *
     5  */
     6 int bus_add_driver(struct device_driver *drv)
     7 {
     8     struct bus_type * bus = get_bus(drv->bus);
     9     int error = 0;
    10 
    11     if (!bus)
    12         return -EINVAL;
    13 
    14     pr_debug("bus %s: add driver %s
    ", bus->name, drv->name);
    15     error = kobject_set_name(&drv->kobj, "%s", drv->name);
    16     if (error)
    17         goto out_put_bus;
    18     drv->kobj.kset = &bus->drivers;
    19     if ((error = kobject_register(&drv->kobj)))
    20         goto out_put_bus;
    21 
    22     if (drv->bus->drivers_autoprobe) {
    23         error = driver_attach(drv);
    24         if (error)
    25             goto out_unregister;
    26     }
    27     klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
    28     module_add_driver(drv->owner, drv);
    29 
    30     error = driver_add_attrs(bus, drv);
    31     if (error) {
    32         /* How the hell do we get out of this pickle? Give up */
    33         printk(KERN_ERR "%s: driver_add_attrs(%s) failed
    ",
    34             __FUNCTION__, drv->name);
    35     }
    36     error = add_bind_files(drv);
    37     if (error) {
    38         /* Ditto */
    39         printk(KERN_ERR "%s: add_bind_files(%s) failed
    ",
    40             __FUNCTION__, drv->name);
    41     }
    42 
    43     return error;
    44 out_unregister:
    45     kobject_unregister(&drv->kobj);
    46 out_put_bus:
    47     put_bus(bus);
    48     return error;
    49 }

      kobject_register(&drv->kobj)

     1 /**
     2  *    kobject_register - initialize and add an object.
     3  *    @kobj:    object in question.
     4  */
     5 
     6 int kobject_register(struct kobject * kobj)
     7 {
     8     int error = -EINVAL;
     9     if (kobj) {
    10         kobject_init(kobj);
    11         error = kobject_add(kobj);
    12         if (!error)
    13             kobject_uevent(kobj, KOBJ_ADD);
    14     }
    15     return error;
    16 }
     kobject_add(kobj);
    1 /**
    2  *    kobject_add - add an object to the hierarchy.
    3  *    @kobj:    object.
    4  */
    5 int kobject_add(struct kobject * kobj)
    6 {
    7     return kobject_shadow_add(kobj, NULL);
    8 }
      kobject_shadow_add(kobj, NULL);
      
     1 /**
     2  *    kobject_shadow_add - add an object to the hierarchy.
     3  *    @kobj:    object.
     4  *    @shadow_parent: sysfs directory to add to.
     5  */
     6 
     7 int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
     8 {
     9     int error = 0;
    10     struct kobject * parent;
    11 
    12     if (!(kobj = kobject_get(kobj)))
    13         return -ENOENT;
    14     if (!kobj->k_name)
    15         kobj->k_name = kobj->name;
    16     if (!*kobj->k_name) {
    17         pr_debug("kobject attempted to be registered with no name!
    ");
    18         WARN_ON(1);
    19         kobject_put(kobj);
    20         return -EINVAL;
    21     }
    22     parent = kobject_get(kobj->parent);
    23 
    24     pr_debug("kobject %s: registering. parent: %s, set: %s
    ",
    25          kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>", 
    26          kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
    27 
    28     if (kobj->kset) {
    29         spin_lock(&kobj->kset->list_lock);
    30 
    31         if (!parent)
    32             parent = kobject_get(&kobj->kset->kobj);
    33 
    34         list_add_tail(&kobj->entry,&kobj->kset->list);
    35         spin_unlock(&kobj->kset->list_lock);
    36         kobj->parent = parent;
    37     }
    38 
    39     error = create_dir(kobj, shadow_parent);
    40     if (error) {
    41         /* unlink does the kobject_put() for us */
    42         unlink(kobj);
    43         kobject_put(parent);
    44 
    45         /* be noisy on error issues */
    46         if (error == -EEXIST)
    47             printk(KERN_ERR "kobject_add failed for %s with "
    48                    "-EEXIST, don't try to register things with "
    49                    "the same name in the same directory.
    ",
    50                    kobject_name(kobj));
    51         else
    52             printk(KERN_ERR "kobject_add failed for %s (%d)
    ",
    53                    kobject_name(kobj), error);
    54         dump_stack();
    55     }
    56 
    57     return error;
    58 }

      create_dir(kobj, shadow_parent); 

     1 static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
     2 {
     3     int error = 0;
     4     if (kobject_name(kobj)) {
     5         error = sysfs_create_dir(kobj, shadow_parent);
     6         if (!error) {
     7             if ((error = populate_dir(kobj)))
     8                 sysfs_remove_dir(kobj);
     9         }
    10     }
    11     return error;
    12 }

      sysfs_create_dir(kobj, shadow_parent);

     1 /**
     2  *    sysfs_create_dir - create a directory for an object.
     3  *    @kobj:        object we're creating directory for. 
     4  *    @shadow_parent:    parent parent object.
     5  */
     6 
     7 int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
     8 {
     9     struct dentry * dentry = NULL;
    10     struct dentry * parent;
    11     int error = 0;
    12 
    13     BUG_ON(!kobj);
    14 
    15     if (shadow_parent)
    16         parent = shadow_parent;
    17     else if (kobj->parent)
    18         parent = kobj->parent->dentry;
    19     else if (sysfs_mount && sysfs_mount->mnt_sb)
    20         parent = sysfs_mount->mnt_sb->s_root;
    21     else
    22         return -EFAULT;
    23 
    24     error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
    25     if (!error)
    26         kobj->dentry = dentry;
    27     return error;
    28 }

      create_dir(kobj,parent,kobject_name(kobj),&dentry);

      
     1 static int create_dir(struct kobject * k, struct dentry * p,
     2               const char * n, struct dentry ** d)
     3 {
     4     int error;
     5     umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
     6 
     7     mutex_lock(&p->d_inode->i_mutex);
     8     *d = lookup_one_len(n, p, strlen(n));
     9     if (!IS_ERR(*d)) {
    10          if (sysfs_dirent_exist(p->d_fsdata, n))
    11               error = -EEXIST;
    12           else
    13             error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
    14                                 SYSFS_DIR);
    15         if (!error) {
    16             error = sysfs_create(*d, mode, init_dir);
    17             if (!error) {
    18                 inc_nlink(p->d_inode);
    19                 (*d)->d_op = &sysfs_dentry_ops;
    20                 d_rehash(*d);
    21             }
    22         }
    23         if (error && (error != -EEXIST)) {
    24             struct sysfs_dirent *sd = (*d)->d_fsdata;
    25             if (sd) {
    26                  list_del_init(&sd->s_sibling);
    27                 sysfs_put(sd);
    28             }
    29             d_drop(*d);
    30         }
    31         dput(*d);
    32     } else
    33         error = PTR_ERR(*d);
    34     mutex_unlock(&p->d_inode->i_mutex);
    35     return error;
    36 }
      
      sysfs_create(*d, mode, init_dir);
      
     1 int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
     2 {
     3     int error = 0;
     4     struct inode * inode = NULL;
     5     if (dentry) {
     6         if (!dentry->d_inode) {
     7             struct sysfs_dirent * sd = dentry->d_fsdata;
     8             if ((inode = sysfs_new_inode(mode, sd))) {
     9                 if (dentry->d_parent && dentry->d_parent->d_inode) {
    10                     struct inode *p_inode = dentry->d_parent->d_inode;
    11                     p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
    12                 }
    13                 goto Proceed;
    14             }
    15             else 
    16                 error = -ENOMEM;
    17         } else
    18             error = -EEXIST;
    19     } else 
    20         error = -ENOENT;
    21     goto Done;
    22 
    23  Proceed:
    24     if (init)
    25         error = init(inode);
    26     if (!error) {
    27         d_instantiate(dentry, inode);
    28         if (S_ISDIR(mode))
    29             dget(dentry);  /* pin only directory dentry in core */
    30     } else
    31         iput(inode);
    32  Done:
    33     return error;
    34 }

      sysfs_create(*d, mode, init_dir);

      

     1 int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
     2 {
     3     int error = 0;
     4     struct inode * inode = NULL;
     5     if (dentry) {
     6         if (!dentry->d_inode) {
     7             struct sysfs_dirent * sd = dentry->d_fsdata;
     8             if ((inode = sysfs_new_inode(mode, sd))) {
     9                 if (dentry->d_parent && dentry->d_parent->d_inode) {
    10                     struct inode *p_inode = dentry->d_parent->d_inode;
    11                     p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
    12                 }
    13                 goto Proceed;
    14             }
    15             else 
    16                 error = -ENOMEM;
    17         } else
    18             error = -EEXIST;
    19     } else 
    20         error = -ENOENT;
    21     goto Done;
    22 
    23  Proceed:
    24     if (init)
    25         error = init(inode);
    26     if (!error) {
    27         d_instantiate(dentry, inode);
    28         if (S_ISDIR(mode))
    29             dget(dentry);  /* pin only directory dentry in core */
    30     } else
    31         iput(inode);
    32  Done:
    33     return error;
    34 }

      

      sysfs_new_inode(mode, sd))
      
     1 struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
     2 {
     3     struct inode * inode = new_inode(sysfs_sb);
     4     if (inode) {
     5         inode->i_blocks = 0;
     6         inode->i_mapping->a_ops = &sysfs_aops;
     7         inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
     8         inode->i_op = &sysfs_inode_operations;
     9         inode->i_ino = sd->s_ino;
    10         lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
    11 
    12         if (sd->s_iattr) {
    13             /* sysfs_dirent has non-default attributes
    14              * get them for the new inode from persistent copy
    15              * in sysfs_dirent
    16              */
    17             set_inode_attr(inode, sd->s_iattr);
    18         } else
    19             set_default_inode_attr(inode, mode);
    20     }
    21     return inode;
    22 }

      

      new_inode(sysfs_sb);
     1 /**
     2  *    new_inode     - obtain an inode
     3  *    @sb: superblock
     4  *
     5  *    Allocates a new inode for given superblock.
     6  */
     7 struct inode *new_inode(struct super_block *sb)
     8 {
     9     /*
    10      * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
    11      * error if st_ino won't fit in target struct field. Use 32bit counter
    12      * here to attempt to avoid that.
    13      */
    14     static unsigned int last_ino;
    15     struct inode * inode;
    16 
    17     spin_lock_prefetch(&inode_lock);
    18     
    19     inode = alloc_inode(sb);
    20     if (inode) {
    21         spin_lock(&inode_lock);
    22         inodes_stat.nr_inodes++;
    23         list_add(&inode->i_list, &inode_in_use);
    24         list_add(&inode->i_sb_list, &sb->s_inodes);
    25         inode->i_ino = ++last_ino;
    26         inode->i_state = 0;
    27         spin_unlock(&inode_lock);
    28     }
    29     return inode;
    30 }
      alloc_inode(sb);
     1 static struct inode *alloc_inode(struct super_block *sb)
     2 {
     3     static const struct address_space_operations empty_aops;
     4     static struct inode_operations empty_iops;
     5     static const struct file_operations empty_fops;
     6     struct inode *inode;
     7 
     8     if (sb->s_op->alloc_inode)
     9         inode = sb->s_op->alloc_inode(sb);
    10     else
    11         inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL);
    12 
    13     if (inode) {
    14         struct address_space * const mapping = &inode->i_data;
    15 
    16         inode->i_sb = sb;
    17         inode->i_blkbits = sb->s_blocksize_bits;
    18         inode->i_flags = 0;
    19         atomic_set(&inode->i_count, 1);
    20         inode->i_op = &empty_iops;
    21         inode->i_fop = &empty_fops;
    22         inode->i_nlink = 1;
    23         atomic_set(&inode->i_writecount, 0);
    24         inode->i_size = 0;
    25         inode->i_blocks = 0;
    26         inode->i_bytes = 0;
    27         inode->i_generation = 0;
    28 #ifdef CONFIG_QUOTA
    29         memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
    30 #endif
    31         inode->i_pipe = NULL;
    32         inode->i_bdev = NULL;
    33         inode->i_cdev = NULL;
    34         inode->i_rdev = 0;
    35         inode->dirtied_when = 0;
    36         if (security_inode_alloc(inode)) {
    37             if (inode->i_sb->s_op->destroy_inode)
    38                 inode->i_sb->s_op->destroy_inode(inode);
    39             else
    40                 kmem_cache_free(inode_cachep, (inode));
    41             return NULL;
    42         }
    43 
    44         mapping->a_ops = &empty_aops;
    45          mapping->host = inode;
    46         mapping->flags = 0;
    47         mapping_set_gfp_mask(mapping, GFP_HIGHUSER);
    48         mapping->assoc_mapping = NULL;
    49         mapping->backing_dev_info = &default_backing_dev_info;
    50 
    51         /*
    52          * If the block_device provides a backing_dev_info for client
    53          * inodes then use that.  Otherwise the inode share the bdev's
    54          * backing_dev_info.
    55          */
    56         if (sb->s_bdev) {
    57             struct backing_dev_info *bdi;
    58 
    59             bdi = sb->s_bdev->bd_inode_backing_dev_info;
    60             if (!bdi)
    61                 bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
    62             mapping->backing_dev_info = bdi;
    63         }
    64         inode->i_private = NULL;
    65         inode->i_mapping = mapping;
    66     }
    67     return inode;
    68 }

       kmem_cache_alloc(inode_cachep, GFP_KERNEL);这儿就是最底层为sys虚拟文件系统分配内存的函数,就是采用了高速页缓存方法,在内存中为节点分配了一块内存。

     1 **
     2  * kmem_cache_alloc - Allocate an object
     3  * @cachep: The cache to allocate from.
     4  * @flags: See kmalloc().
     5  *
     6  * Allocate an object from this cache.  The flags are only relevant
     7  * if the cache has no available objects.
     8  */
     9 void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
    10 {
    11     return __cache_alloc(cachep, flags, __builtin_return_address(0));
    12 }

          上面是关于sysfs虚拟文件系统的分析,与i2c驱动没有太大的关系,但是我们可以看出来i2c的driver和device最后都是挂在总线上的,这些都是可以归纳为:总线---设备-----驱动模型的,我们可以看出来从i2c_add_driver()函数开始内核不光是在建立一个driver同时也在忙着将这个dirver挂在这个总线上,前面贴出的代码描述了这个过程,下面在看看流程:

      i2c_add_driver()----------->i2c_register_driver()  

                        |

                        |

                        driver->driver.bus = &i2c_bus_type

     1 struct bus_type i2c_bus_type = {
     2     .name        = "i2c",
     3     .dev_attrs    = i2c_dev_attrs,
     4     .match        = i2c_device_match,
     5     .uevent        = i2c_device_uevent,
     6     .probe        = i2c_device_probe,
     7     .remove        = i2c_device_remove,
     8     .shutdown    = i2c_device_shutdown,
     9     .suspend    = i2c_device_suspend,
    10     .resume        = i2c_device_resume,
    11 };

      i2c_driver与i2c_client关系:

      i2c_driver对应于一套驱动方法,主要成员函数是probe()、remove()、suspend()、resume()。      

      i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述,i2c_driver与i2c_client的关系是一对多,一个i2c_drvier可以支持多个同类型的i2c_client。

      i2c_adpater与i2c_client关系

      i2c_adpater与i2c_client的关系与I2C硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adapter。一个适配器可以连接多个I2C设备,所以一个i2c_adapter也可以被多个i2c_client依附,i2c_adapter中包括依附于它的i2c_client的链表。

      刚开始没搞懂其实i2c_client、i2c_adpater这两个数据结构都是内核抽象出来的便于对多平台的适应,每一个i2c_adpater对应于一条总线,i2c_client每一个对应于一个具体设备。

      网上的解释:简单点了, 你的开发板上有几个I2C接口,就有几个adapter , 也就是有几条I2C bus ,  I2C CLIENT 对应的就是你的外围I2C 设备,有几个就有几个CLIENT , 把这些设备插入开发板, 对应其中的一条BUS, 那么相应的就对应了其中的一个ADAPTER , 接下来的就是  CLIENT 与 ADAPTER 勾搭成对了, 后面就是做该做的事了
      
    在编写I2C驱动的时候我们需要实现两个方面的内容:
      1、提供I2C适配器的硬件驱动,探测、初始化I2C适配器、驱动CPU控制的I2C适配器从硬件上产生各种信号及处理I2C中断。
      2、提供I2C适配器的算法,用具体适配器的xxx_dfer()函数填充i2c_algorithm的master_xfer指针。
      3、对I2C core的接口,必须实现 struct i2c_drvier数据结构中的几个特定的功能函数。这些函数是I2C驱动与I2C总线物理层(I2C控制器)和I2C设备器件之间通信的基础。
      4、 对用户应用层的接口,必须实现struct file_operation数据结构中的一些特定功能的函数,如 open ,release , read ,write,lseek等函数。以上两类接口中,对I2C core的接口是对I2C设备访问的基础,实现对I2C总线具体的访问方法;对用户应用层的接口则是方便应用程序开发,实现设备特定功能的必不可少的部分。例如,如果是字符设备,就实现文件操作接口,实现具体设备yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等;如果是声卡,就实现ALSA驱动。


      下面的函数流程就是i2c注册的过程,在注册的过程中会把i2c添加到总线上去,同时完成match过程(目前没有弄清楚的流程),难道是在这儿进行了dev和driver的比较?
      i2c_add_driver()---------->i2c_register_driver()------------>driver_register()------------------->bus_add_driver()-------->driver_attach()--------->bus_for_each_dev()-------------->__driver_attach()----------------->driver_probe_device()----------------->int (*match)(struct device * dev, struct device_driver * drv)

       
       总结一下I2C驱动的流程:
      1、首先,在i2c_client_address_data的normal_i2c属性中定义好我们设备的设备地址。
      2、接下来,i2c_driver就出场了,它的功能是定义i2c设备的名字,探测函数,卸载函数三个属性。
      3、当程序在入口函数中注册i2c-driver驱动之后,系统就会根据我们第一步中定义的设备地址,调用attach_adapter函数进行匹配设备地址是否支持,在attach_adapter函数中主要的功能是在调用i2c_probe函数,当系统检测到设备地址匹配时,就会进入i2c_probe函数中干一些重要的事,接着就进入i2c-probe传入的at24cxx_detect函数中实现我们自己的事。

      其实总结一下就下面一个流程:at24cxx_attach_adapter -> i2c_probe -> at24cxx_detect

        当我们卸载设备时,会自动调用i2c_driver中定义的卸载函数at24cxx_detach_adapter进行卸载设备。

          最后一步自然就是在出口函数中卸载i2c-driver驱动。

         因为I2C只是一种通信的方式,所以在完成前面的工作后我们需要完成我们要在I2C这种通信方式山所做的工作,我们一般在at24cxx_detect()中完成设备register_chrdev()的注册,然后填写read()、write()等函数。

         没有弄得很清楚的就是为什么没有注册i2c_add_adapter()---------->i2c_register_adapter(),适配器和device的匹配是在driver中完成的吗?

         参考的比较经典的博文:http://www.cnblogs.com/lihaiyan/p/4452875.html

                  http://blog.csdn.net/chocolate001/article/details/7470873

                  http://blog.sina.com.cn/s/blog_63f31f340101byb2.html

                  http://www.embedu.org/Column/Column213.htm

  • 相关阅读:
    查找字符串中特定字符最后出现的位置
    C# List中的ForEach
    tensorflow中一个矩阵和一个向量相加
    Hibernate-ORM:16.Hibernate中的二级缓存Ehcache的配置
    Hibernate-ORM:15.Hibernate中的Criteria查询
    Hibernate-ORM:14.Hibernate中的命名查询
    Hibernate-ORM:12.Hibernate中的多对多关联关系
    Hibernate-ORM:10.Hibernate中的分页
    Hibernate-ORM:09.Hibernate中的getCurrentSession()
    Hibernate-ORM:08.Hibernate中的投影查询
  • 原文地址:https://www.cnblogs.com/qiuheng/p/5761865.html
Copyright © 2011-2022 走看看