• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

linux驱动之I2C

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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\n",
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\n", 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\n", 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\n", 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\n", 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\n",
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\n",
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!\n");
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\n",
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.\n",
50                    kobject_name(kobj));
51         else
52             printk(KERN_ERR "kobject_add failed for %s (%d)\n",
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 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap