作者:刘昊昱

博客:http://blog.csdn.net/liuhaoyutz

内核版本:3.10.1

 
I2C体系架构的硬件实体包括两部分:
  • 硬件I2C Adapter:硬件I2C Adapter表示一个硬件I2C适配器,也就是I2C控制器。一般是SOC中的一个接口,也可以用GPIO模拟。硬件I2C Adapter主要用来在I2C接口上产生I2C时钟信号和数据信号。
  • 硬件I2C Device:表示一个I2C从设备,I2C从设备并行的挂接在I2C总线上,通过I2C接口与I2C主控制器通信。
Linux的I2C体系架构包括6个部分:
  • I2C Core,定义了一些函数和数据结构,用于支持I2C控制器驱动(I2C Adapter drvier)和I2C设备驱动(I2C client driver)。I2C Core的存在使I2C控制器驱动和I2C设备驱动独立开来,具有更好的可移置性,同时简化了驱动开发的工作量。但是,I2C Core的存在也使Linux I2C体系结构理解起来更有难度。
  • I2C Adapter,代表一个I2C控制器,用struct i2c_adapter来表示。
  • Algorithm,访问I2C控制器的接口,Algorithm直接操作I2C控制器的硬件寄存器来执行数据的发送和接收。它提供操作I2C控制器的最底层操作函数。每个I2C Adapter都有自己的Algorithm,每个I2C Adapter通过自己的Algorithm与挂接在该控制器上的I2C从设备进行通信。
  • I2C Client,代表一个挂接在I2C总线上的I2C设备。
  • I2C设备驱动(I2C client driver)
  • I2C-dev,I2C控制器的设备文件,通常命名为i2c-0、i2c-1等等,是I2C控制器的应用层访问接口。
 
一、I2C相关数据结构
I2C控制器(例如S3C2440 I2C控制器)对应的数据结构是i2c_adapter,i2c_adapter结构定义在include/linux/i2c.h文件中,从注释可以看出,i2c_adapter代表一条物理的I2C总线,同时还包括访问该I2C总线的方法。其内容如下:
409/*
410 * i2c_adapter is the structure used to identify a physical i2c bus along
411 * with the access algorithms necessary to access it.
412 */
413struct i2c_adapter {
414    struct module *owner;
415    unsigned int class;       /* classes to allow probing for */
416    const struct i2c_algorithm *algo; /* the algorithm to access the bus */
417    void *algo_data;
418
419    /* data fields that are valid for all devices   */
420    struct rt_mutex bus_lock;
421
422    int timeout;            /* in jiffies */
423    int retries;
424    struct device dev;      /* the adapter device */
425
426    int nr;
427    char name[48];
428    struct completion dev_released;
429
430    struct mutex userspace_clients_lock;
431    struct list_head userspace_clients;
432
433    struct i2c_bus_recovery_info *bus_recovery_info;
434};

i2c_algorithm定义在include/linux/i2c.h文件中,其内容如下:
347/*
348 * The following structs are for those who like to implement new bus drivers:
349 * i2c_algorithm is the interface to a class of hardware solutions which can
350 * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
351 * to name two of the most common.
352 */
353struct i2c_algorithm {
354    /* If an adapter algorithm can't do I2C-level access, set master_xfer
355       to NULL. If an adapter algorithm can do SMBus access, set
356       smbus_xfer. If set to NULL, the SMBus protocol is simulated
357       using common I2C messages */
358    /* master_xfer should return the number of messages successfully
359       processed, or a negative value on error */
360    int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
361               int num);
362    int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
363               unsigned short flags, char read_write,
364               u8 command, int size, union i2c_smbus_data *data);
365
366    /* To determine what the adapter supports */
367    u32 (*functionality) (struct i2c_adapter *);
368};

struct i2c_client代表一个I2C设备,该结构体定义在include/linux/i2c.h文件中,其内容如下:
200/**
201 * struct i2c_client - represent an I2C slave device
202 * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
203 *  I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
204 * @addr: Address used on the I2C bus connected to the parent adapter.
205 * @name: Indicates the type of the device, usually a chip name that's
206 *  generic enough to hide second-sourcing and compatible revisions.
207 * @adapter: manages the bus segment hosting this I2C device
208 * @driver: device's driver, hence pointer to access routines
209 * @dev: Driver model device node for the slave.
210 * @irq: indicates the IRQ generated by this device (if any)
211 * @detected: member of an i2c_driver.clients list or i2c-core's
212 *  userspace_devices list
213 *
214 * An i2c_client identifies a single device (i.e. chip) connected to an
215 * i2c bus. The behaviour exposed to Linux is defined by the driver
216 * managing the device.
217 */
218struct i2c_client {
219    unsigned short flags;       /* div., see below      */
220    unsigned short addr;        /* chip address - NOTE: 7bit    */
221                    /* addresses are stored in the  */
222                    /* _LOWER_ 7 bits       */
223    char name[I2C_NAME_SIZE];
224    struct i2c_adapter *adapter;    /* the adapter we sit on    */
225    struct i2c_driver *driver;  /* and our access routines  */
226    struct device dev;      /* the device structure     */
227    int irq;            /* irq issued by device     */
228    struct list_head detected;
229};

struct i2c_driver代表一个I2C设备驱动程序,该结构体定义在include/linux/i2c.h文件中,其内容如下:
124/**
125 * struct i2c_driver - represent an I2C device driver
126 * @class: What kind of i2c device we instantiate (for detect)
127 * @attach_adapter: Callback for bus addition (deprecated)
128 * @probe: Callback for device binding
129 * @remove: Callback for device unbinding
130 * @shutdown: Callback for device shutdown
131 * @suspend: Callback for device suspend
132 * @resume: Callback for device resume
133 * @alert: Alert callback, for example for the SMBus alert protocol
134 * @command: Callback for bus-wide signaling (optional)
135 * @driver: Device driver model driver
136 * @id_table: List of I2C devices supported by this driver
137 * @detect: Callback for device detection
138 * @address_list: The I2C addresses to probe (for detect)
139 * @clients: List of detected clients we created (for i2c-core use only)
140 *
141 * The driver.owner field should be set to the module owner of this driver.
142 * The driver.name field should be set to the name of this driver.
143 *
144 * For automatic device detection, both @detect and @address_list must
145 * be defined. @class should also be set, otherwise only devices forced
146 * with module parameters will be created. The detect function must
147 * fill at least the name field of the i2c_board_info structure it is
148 * handed upon successful detection, and possibly also the flags field.
149 *
150 * If @detect is missing, the driver will still work fine for enumerated
151 * devices. Detected devices simply won't be supported. This is expected
152 * for the many I2C/SMBus devices which can't be detected reliably, and
153 * the ones which can always be enumerated in practice.
154 *
155 * The i2c_client structure which is handed to the @detect callback is
156 * not a real i2c_client. It is initialized just enough so that you can
157 * call i2c_smbus_read_byte_data and friends on it. Don't do anything
158 * else with it. In particular, calling dev_dbg and friends on it is
159 * not allowed.
160 */
161struct i2c_driver {
162    unsigned int class;
163
164    /* Notifies the driver that a new bus has appeared. You should avoid
165     * using this, it will be removed in a near future.
166     */
167    int (*attach_adapter)(struct i2c_adapter *) __deprecated;
168
169    /* Standard driver model interfaces */
170    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
171    int (*remove)(struct i2c_client *);
172
173    /* driver model interfaces that don't relate to enumeration  */
174    void (*shutdown)(struct i2c_client *);
175    int (*suspend)(struct i2c_client *, pm_message_t mesg);
176    int (*resume)(struct i2c_client *);
177
178    /* Alert callback, for example for the SMBus alert protocol.
179     * The format and meaning of the data value depends on the protocol.
180     * For the SMBus alert protocol, there is a single bit of data passed
181     * as the alert response's low bit ("event flag").
182     */
183    void (*alert)(struct i2c_client *, unsigned int data);
184
185    /* a ioctl like command that can be used to perform specific functions
186     * with the device.
187     */
188    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
189
190    struct device_driver driver;
191    const struct i2c_device_id *id_table;
192
193    /* Device detection callback for automatic device creation */
194    int (*detect)(struct i2c_client *, struct i2c_board_info *);
195    const unsigned short *address_list;
196    struct list_head clients;
197};

 
二、i2c_adapter的注册
i2c_add_adapter和i2c_add_numbered_adapter函数都可以注册I2C adapter,这两个函数的区别是,i2c_add_adapter动态分配一个bus number,而i2c_add_numbered_adapter使用i2c_adapter.nr指定的bus number。
下面是i2c_add_adapter函数的定义,它定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1099/**
1100 * i2c_add_adapter - declare i2c adapter, use dynamic bus number
1101 * @adapter: the adapter to add
1102 * Context: can sleep
1103 *
1104 * This routine is used to declare an I2C adapter when its bus number
1105 * doesn't matter or when its bus number is specified by an dt alias.
1106 * Examples of bases when the bus number doesn't matter: I2C adapters
1107 * dynamically added by USB links or PCI plugin cards.
1108 *
1109 * When this returns zero, a new bus number was allocated and stored
1110 * in adap->nr, and the specified adapter became available for clients.
1111 * Otherwise, a negative errno value is returned.
1112 */
1113int i2c_add_adapter(struct i2c_adapter *adapter)
1114{
1115    struct device *dev = &adapter->dev;
1116    int id;
1117
1118    if (dev->of_node) {
1119        id = of_alias_get_id(dev->of_node, "i2c");
1120        if (id >= 0) {
1121            adapter->nr = id;
1122            return __i2c_add_numbered_adapter(adapter);
1123        }
1124    }
1125
1126    mutex_lock(&core_lock);
1127    id = idr_alloc(&i2c_adapter_idr, adapter,
1128               __i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
1129    mutex_unlock(&core_lock);
1130    if (id < 0)
1131        return id;
1132
1133    adapter->nr = id;
1134
1135    return i2c_register_adapter(adapter);
1136}

1118-1124行,跳过。
1127-1128行,调用idr_alloc动态分配一个idr entry,并用返回的id作为bus number。
1135行,调用i2c_register_adapter函数。这个函数我们后面再分析。
下面是i2c_add_numbered_adapter函数的定义,它同样定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1139/**
1140 * i2c_add_numbered_adapter - declare i2c adapter, use static bus number
1141 * @adap: the adapter to register (with adap->nr initialized)
1142 * Context: can sleep
1143 *
1144 * This routine is used to declare an I2C adapter when its bus number
1145 * matters.  For example, use it for I2C adapters from system-on-chip CPUs,
1146 * or otherwise built in to the system's mainboard, and where i2c_board_info
1147 * is used to properly configure I2C devices.
1148 *
1149 * If the requested bus number is set to -1, then this function will behave
1150 * identically to i2c_add_adapter, and will dynamically assign a bus number.
1151 *
1152 * If no devices have pre-been declared for this bus, then be sure to
1153 * register the adapter before any dynamically allocated ones.  Otherwise
1154 * the required bus ID may not be available.
1155 *
1156 * When this returns zero, the specified adapter became available for
1157 * clients using the bus number provided in adap->nr.  Also, the table
1158 * of I2C devices pre-declared using i2c_register_board_info() is scanned,
1159 * and the appropriate driver model device nodes are created.  Otherwise, a
1160 * negative errno value is returned.
1161 */
1162int i2c_add_numbered_adapter(struct i2c_adapter *adap)
1163{
1164    if (adap->nr == -1) /* -1 means dynamically assign bus id */
1165        return i2c_add_adapter(adap);
1166
1167    return __i2c_add_numbered_adapter(adap);
1168}

可以看到如果adap->nr的值为-1,则调用i2c_add_adapter动态分配一个bus number并注册。否则,调用__i2c_add_numbered_adapter函数,该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1078/**
1079 * __i2c_add_numbered_adapter - i2c_add_numbered_adapter where nr is never -1
1080 * @adap: the adapter to register (with adap->nr initialized)
1081 * Context: can sleep
1082 *
1083 * See i2c_add_numbered_adapter() for details.
1084 */
1085static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
1086{
1087    int id;
1088
1089    mutex_lock(&core_lock);
1090    id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
1091               GFP_KERNEL);
1092    mutex_unlock(&core_lock);
1093    if (id < 0)
1094        return id == -ENOSPC ? -EBUSY : id;
1095
1096    return i2c_register_adapter(adap);
1097}

1090行,调用idr_alloc函数用指定的daap->nr作为bus number分配一个idr entry。
1096行,调用i2c_register_adapter函数。
所以,不论是用i2c_add_adapter还是用i2c_add_numbered_adapter函数注册i2c_adapter,最终都会调用i2c_register_adapter函数完成注册。
i2c_register_adapter函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
 980static int i2c_register_adapter(struct i2c_adapter *adap)981{982    int res = 0;983984    /* Can't register until after driver model init */985    if (unlikely(WARN_ON(!i2c_bus_type.p))) {986        res = -EAGAIN;987        goto out_list;988    }989990    /* Sanity checks */991    if (unlikely(adap->name[0] == '\0')) {992        pr_err("i2c-core: Attempt to register an adapter with "993               "no name!\n");994        return -EINVAL;995    }996    if (unlikely(!adap->algo)) {997        pr_err("i2c-core: Attempt to register adapter '%s' with "998               "no algo!\n", adap->name);999        return -EINVAL;
1000    }
1001
1002    rt_mutex_init(&adap->bus_lock);
1003    mutex_init(&adap->userspace_clients_lock);
1004    INIT_LIST_HEAD(&adap->userspace_clients);
1005
1006    /* Set default timeout to 1 second if not already set */
1007    if (adap->timeout == 0)
1008        adap->timeout = HZ;
1009
1010    dev_set_name(&adap->dev, "i2c-%d", adap->nr);
1011    adap->dev.bus = &i2c_bus_type;
1012    adap->dev.type = &i2c_adapter_type;
1013    res = device_register(&adap->dev);
1014    if (res)
1015        goto out_list;
1016
1017    dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
1018
1019#ifdef CONFIG_I2C_COMPAT
1020    res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,
1021                       adap->dev.parent);
1022    if (res)
1023        dev_warn(&adap->dev,
1024             "Failed to create compatibility class link\n");
1025#endif
1026
1027    /* bus recovery specific initialization */
1028    if (adap->bus_recovery_info) {
1029        struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
1030
1031        if (!bri->recover_bus) {
1032            dev_err(&adap->dev, "No recover_bus() found, not using recovery\n");
1033            adap->bus_recovery_info = NULL;
1034            goto exit_recovery;
1035        }
1036
1037        /* Generic GPIO recovery */
1038        if (bri->recover_bus == i2c_generic_gpio_recovery) {
1039            if (!gpio_is_valid(bri->scl_gpio)) {
1040                dev_err(&adap->dev, "Invalid SCL gpio, not using recovery\n");
1041                adap->bus_recovery_info = NULL;
1042                goto exit_recovery;
1043            }
1044
1045            if (gpio_is_valid(bri->sda_gpio))
1046                bri->get_sda = get_sda_gpio_value;
1047            else
1048                bri->get_sda = NULL;
1049
1050            bri->get_scl = get_scl_gpio_value;
1051            bri->set_scl = set_scl_gpio_value;
1052        } else if (!bri->set_scl || !bri->get_scl) {
1053            /* Generic SCL recovery */
1054            dev_err(&adap->dev, "No {get|set}_gpio() found, not using recovery\n");
1055            adap->bus_recovery_info = NULL;
1056        }
1057    }
1058
1059exit_recovery:
1060    /* create pre-declared device nodes */
1061    if (adap->nr < __i2c_first_dynamic_bus_num)
1062        i2c_scan_static_board_info(adap);
1063
1064    /* Notify drivers */
1065    mutex_lock(&core_lock);
1066    bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
1067    mutex_unlock(&core_lock);
1068
1069    return 0;
1070
1071out_list:
1072    mutex_lock(&core_lock);
1073    idr_remove(&i2c_adapter_idr, adap->nr);
1074    mutex_unlock(&core_lock);
1075    return res;
1076}

984-1013行,完成基本的检查和初始化工作后,注册i2c_adapter.dev。
1027-1059行,如果有必要,为bus recovery作一些准备工作。
1060-1062行,如果有预先声明的i2c设备,则注册对应的i2c_client。
先看1061行,判断adap->nr是否小于__i2c_first_dynamic_bus_num,只有是使用i2c_add_numbered_adapter注册i2c_adapter时,该判断才会成立。用i2c_add_adapter函数注册i2c_adapter时,动态分配的bus number一定是大于或等于__i2c_first_dynamic_bus_num的。
如果1061行的判断成立,说明是使用预先定义的bus number,因此,就可能会有预置的I2C设备信息。所以1062行,调用i2c_scan_static_board_info函数,遍历预置I2C设备信息列表,创建对应的i2c_client。
i2c_scan_static_board_info函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
 941static void i2c_scan_static_board_info(struct i2c_adapter *adapter)942{943    struct i2c_devinfo  *devinfo;944945    down_read(&__i2c_board_lock);946    list_for_each_entry(devinfo, &__i2c_board_list, list) {947        if (devinfo->busnum == adapter->nr948                && !i2c_new_device(adapter,949                        &devinfo->board_info))950            dev_err(&adapter->dev,951                "Can't create device at 0x%02x\n",952                devinfo->board_info.addr);953    }954    up_read(&__i2c_board_lock);955}

该函数遍历__i2c_board_list链表,如果某个节点的devinfo->busnum等于adapter->nr,即该I2C设备属于这个注册的I2C adapter,则调用i2c_new_device创建并注册该I2C设备对应的i2c_client。
i2c_new_device定义在drivers/i2c/i2c-core.c文件中,其内容如下:
 612/**613 * i2c_new_device - instantiate an i2c device614 * @adap: the adapter managing the device615 * @info: describes one I2C device; bus_num is ignored616 * Context: can sleep617 *618 * Create an i2c device. Binding is handled through driver model619 * probe()/remove() methods.  A driver may be bound to this device when we620 * return from this function, or any later moment (e.g. maybe hotplugging will621 * load the driver module).  This call is not appropriate for use by mainboard622 * initialization logic, which usually runs during an arch_initcall() long623 * before any i2c_adapter could exist.624 *625 * This returns the new i2c client, which may be saved for later use with626 * i2c_unregister_device(); or NULL to indicate an error.627 */628struct i2c_client *629i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)630{631    struct i2c_client   *client;632    int         status;633634    client = kzalloc(sizeof *client, GFP_KERNEL);635    if (!client)636        return NULL;637638    client->adapter = adap;639640    client->dev.platform_data = info->platform_data;641642    if (info->archdata)643        client->dev.archdata = *info->archdata;644645    client->flags = info->flags;646    client->addr = info->addr;647    client->irq = info->irq;648649    strlcpy(client->name, info->type, sizeof(client->name));650651    /* Check for address validity */652    status = i2c_check_client_addr_validity(client);653    if (status) {654        dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",655            client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);656        goto out_err_silent;657    }658659    /* Check for address business */660    status = i2c_check_addr_busy(adap, client->addr);661    if (status)662        goto out_err;663664    client->dev.parent = &client->adapter->dev;665    client->dev.bus = &i2c_bus_type;666    client->dev.type = &i2c_client_type;667    client->dev.of_node = info->of_node;668    ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle);669670    /* For 10-bit clients, add an arbitrary offset to avoid collisions */671    dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),672             client->addr | ((client->flags & I2C_CLIENT_TEN)673                     ? 0xa000 : 0));674    status = device_register(&client->dev);675    if (status)676        goto out_err;677678    dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",679        client->name, dev_name(&client->dev));680681    return client;682683out_err:684    dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "685        "(%d)\n", client->name, client->addr, status);686out_err_silent:687    kfree(client);688    return NULL;689}

这个函数很直接,就是初始化i2c_client的各个成员,并最终注册client->dev,从而完成对i2c设备的注册。
这里要说明一下,预置的i2c设备信息是通过调用i2c_register_board_info函数完成的,该函数定义在drivers/i2c/i2c-boardinfo.c文件中,其内容如下:
42/**
43 * i2c_register_board_info - statically declare I2C devices
44 * @busnum: identifies the bus to which these devices belong
45 * @info: vector of i2c device descriptors
46 * @len: how many descriptors in the vector; may be zero to reserve
47 *  the specified bus number.
48 *
49 * Systems using the Linux I2C driver stack can declare tables of board info
50 * while they initialize.  This should be done in board-specific init code
51 * near arch_initcall() time, or equivalent, before any I2C adapter driver is
52 * registered.  For example, mainboard init code could define several devices,
53 * as could the init code for each daughtercard in a board stack.
54 *
55 * The I2C devices will be created later, after the adapter for the relevant
56 * bus has been registered.  After that moment, standard driver model tools
57 * are used to bind "new style" I2C drivers to the devices.  The bus number
58 * for any device declared using this routine is not available for dynamic
59 * allocation.
60 *
61 * The board info passed can safely be __initdata, but be careful of embedded
62 * pointers (for platform_data, functions, etc) since that won't be copied.
63 */
64int __init
65i2c_register_board_info(int busnum,
66    struct i2c_board_info const *info, unsigned len)
67{
68    int status;
69
70    down_write(&__i2c_board_lock);
71
72    /* dynamic bus numbers will be assigned after the last static one */
73    if (busnum >= __i2c_first_dynamic_bus_num)
74        __i2c_first_dynamic_bus_num = busnum + 1;
75
76    for (status = 0; len; len--, info++) {
77        struct i2c_devinfo  *devinfo;
78
79        devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
80        if (!devinfo) {
81            pr_debug("i2c-core: can't register boardinfo!\n");
82            status = -ENOMEM;
83            break;
84        }
85
86        devinfo->busnum = busnum;
87        devinfo->board_info = *info;
88        list_add_tail(&devinfo->list, &__i2c_board_list);
89    }
90
91    up_write(&__i2c_board_lock);
92
93    return status;
94}

可以看到,该函数将预置的i2c设备信息保存在__i2c_board_list链表中。
回到i2c_register_adapter函数:
1066行,调用bus_for_each_drv函数,该函数定义在drivers/base/bus.c文件中,其内容如下:
 417/**418 * bus_for_each_drv - driver iterator419 * @bus: bus we're dealing with.420 * @start: driver to start iterating on.421 * @data: data to pass to the callback.422 * @fn: function to call for each driver.423 *424 * This is nearly identical to the device iterator above.425 * We iterate over each driver that belongs to @bus, and call426 * @fn for each. If @fn returns anything but 0, we break out427 * and return it. If @start is not NULL, we use it as the head428 * of the list.429 *430 * NOTE: we don't return the driver that returns a non-zero431 * value, nor do we leave the reference count incremented for that432 * driver. If the caller needs to know that info, it must set it433 * in the callback. It must also be sure to increment the refcount434 * so it doesn't disappear before returning to the caller.435 */436int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,437             void *data, int (*fn)(struct device_driver *, void *))438{439    struct klist_iter i;440    struct device_driver *drv;441    int error = 0;442443    if (!bus)444        return -EINVAL;445446    klist_iter_init_node(&bus->p->klist_drivers, &i,447                 start ? &start->p->knode_bus : NULL);448    while ((drv = next_driver(&i)) && !error)449        error = fn(drv, data);450    klist_iter_exit(&i);451    return error;452}

这个函数我们在《Linux设备模型分析之device(基于3.10.1内核)》一文中已经分析过了。448-449行,这个while循环依次遍历bus->p->klist_drivers中的所有device_driver,对于每个device_driver,调用fn(drv,data)函数。这里,传递过来的fn参数是__process_new_adapter,data参数是adap。这个循环是一个关键点,注册一个新的i2c_adapter后,要为该i2c_adapter上的i2c设备匹配驱动程序,这个匹配过程就是通过这个循环调用__process_new_adapter函数完成的。
__process_new_adapter函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
 975static int __process_new_adapter(struct device_driver *d, void *data)976{977    return i2c_do_add_adapter(to_i2c_driver(d), data);978}

注意i2c_do_add_adapter函数的第一个参数,从device_driver转换为i2c_driver。
i2c_do_add_adapter函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
 957static int i2c_do_add_adapter(struct i2c_driver *driver,958                  struct i2c_adapter *adap)959{960    /* Detect supported devices on that bus, and instantiate them */961    i2c_detect(adap, driver);962963    /* Let legacy drivers scan this bus for matching devices */964    if (driver->attach_adapter) {965        dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",966             driver->driver.name);967        dev_warn(&adap->dev, "Please use another way to instantiate "968             "your i2c_client\n");969        /* We ignore the return code; if it fails, too bad */970        driver->attach_adapter(adap);971    }972    return 0;973}

961行,调用i2c_detect函数,探测并初始化该i2c总线上的i2c设备。该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1730static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
1731{
1732    const unsigned short *address_list;
1733    struct i2c_client *temp_client;
1734    int i, err = 0;
1735    int adap_id = i2c_adapter_id(adapter);
1736
1737    address_list = driver->address_list;
1738    if (!driver->detect || !address_list)
1739        return 0;
1740
1741    /* Stop here if the classes do not match */
1742    if (!(adapter->class & driver->class))
1743        return 0;
1744
1745    /* Set up a temporary client to help detect callback */
1746    temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1747    if (!temp_client)
1748        return -ENOMEM;
1749    temp_client->adapter = adapter;
1750
1751    for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
1752        dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
1753            "addr 0x%02x\n", adap_id, address_list[i]);
1754        temp_client->addr = address_list[i];
1755        err = i2c_detect_address(temp_client, driver);
1756        if (unlikely(err))
1757            break;
1758    }
1759
1760    kfree(temp_client);
1761    return err;
1762}

1755行,调用i2c_detect_address,探测指定的地址上的I2C设备是否存在,如果存在,注册该i2c设备。i2c_detect_address函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1675static int i2c_detect_address(struct i2c_client *temp_client,
1676                  struct i2c_driver *driver)
1677{
1678    struct i2c_board_info info;
1679    struct i2c_adapter *adapter = temp_client->adapter;
1680    int addr = temp_client->addr;
1681    int err;
1682
1683    /* Make sure the address is valid */
1684    err = i2c_check_addr_validity(addr);
1685    if (err) {
1686        dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
1687             addr);
1688        return err;
1689    }
1690
1691    /* Skip if already in use */
1692    if (i2c_check_addr_busy(adapter, addr))
1693        return 0;
1694
1695    /* Make sure there is something at this address */
1696    if (!i2c_default_probe(adapter, addr))
1697        return 0;
1698
1699    /* Finally call the custom detection function */
1700    memset(&info, 0, sizeof(struct i2c_board_info));
1701    info.addr = addr;
1702    err = driver->detect(temp_client, &info);
1703    if (err) {
1704        /* -ENODEV is returned if the detection fails. We catch it
1705           here as this isn't an error. */
1706        return err == -ENODEV ? 0 : err;
1707    }
1708
1709    /* Consistency check */
1710    if (info.type[0] == '\0') {
1711        dev_err(&adapter->dev, "%s detection function provided "
1712            "no name for 0x%x\n", driver->driver.name,
1713            addr);
1714    } else {
1715        struct i2c_client *client;
1716
1717        /* Detection succeeded, instantiate the device */
1718        dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
1719            info.type, info.addr);
1720        client = i2c_new_device(adapter, &info);
1721        if (client)
1722            list_add_tail(&client->detected, &driver->clients);
1723        else
1724            dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
1725                info.type, info.addr);
1726    }
1727    return 0;
1728}

1702行,调用driver->detect。
1720行,如果探测到i2c设备确实存在,调用i2c_new_device函数初始化对应的i2c_client结构体并注册。i2c_new_device函数我们在前面已经分析过。
至此,i2c_adapter的注册过程我们就清楚了。
 
三、i2c_driver的注册
i2c_driver的注册是通过调用i2c_add_driver宏完成的,该宏定义在include/linux/i2c.h文件中:
497/* use a define to avoid include chaining to get THIS_MODULE */
498#define i2c_add_driver(driver) \
499    i2c_register_driver(THIS_MODULE, driver)

i2c_register_driver函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1307/*
1308 * An i2c_driver is used with one or more i2c_client (device) nodes to access
1309 * i2c slave chips, on a bus instance associated with some i2c_adapter.
1310 */
1311
1312int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
1313{
1314    int res;
1315
1316    /* Can't register until after driver model init */
1317    if (unlikely(WARN_ON(!i2c_bus_type.p)))
1318        return -EAGAIN;
1319
1320    /* add the driver to the list of i2c drivers in the driver core */
1321    driver->driver.owner = owner;
1322    driver->driver.bus = &i2c_bus_type;
1323
1324    /* When registration returns, the driver core
1325     * will have called probe() for all matching-but-unbound devices.
1326     */
1327    res = driver_register(&driver->driver);
1328    if (res)
1329        return res;
1330
1331    /* Drivers should switch to dev_pm_ops instead. */
1332    if (driver->suspend)
1333        pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
1334            driver->driver.name);
1335    if (driver->resume)
1336        pr_warn("i2c-core: driver [%s] using legacy resume method\n",
1337            driver->driver.name);
1338
1339    pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
1340
1341    INIT_LIST_HEAD(&driver->clients);
1342    /* Walk the adapters that are already present */
1343    i2c_for_each_dev(driver, __process_new_driver);
1344
1345    return 0;
1346}

1327行,调用driver_register注册i2c_driver.driver。参考《Linux设备模型分析之device_driver(基于3.10.1内核)》对Linux设备模型的分析,在driver_register执行过程中,如果I2C总线上找到了与该驱动匹配的I2C设备,则i2c_driver.probe函数会被调用执行。
1343行,调用i2c_for_each_dev遍历所有已存在的i2c_adapter。该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:
1288int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
1289{
1290    int res;
1291
1292    mutex_lock(&core_lock);
1293    res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);
1294    mutex_unlock(&core_lock);
1295
1296    return res;
1297}

1293行,调用bus_for_each_dev,这个函数定义在drivers/base/bus.c文件中,其内容如下:

 286intbus_for_each_dev(struct bus_type *bus, struct device *start,287            void *data, int (*fn)(struct device *, void *))288{289   struct klist_iter i;290   struct device *dev;291   int error = 0;292293   if (!bus || !bus->p)294       return -EINVAL;295296   klist_iter_init_node(&bus->p->klist_devices, &i,297                 (start ?&start->p->knode_bus : NULL));298   while ((dev = next_device(&i)) && !error)299       error = fn(dev, data);300   klist_iter_exit(&i);301   return error;302}

我们在《 Linux设备模型分析之device_driver(基于3.10.1内核)》一文中已经分析过这个函数。这里,传递过来的data参数是要注册的i2c_driver,fn参数是__process_new_driver函数,所以我们来看__process_new_driver函数,该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:

1300static int __process_new_driver(structdevice *dev, void *data)
1301{
1302   if (dev->type != &i2c_adapter_type)
1303       return 0;
1304   return i2c_do_add_adapter(data, to_i2c_adapter(dev));
1305}

i2c_do_add_adapter函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:

 957static int i2c_do_add_adapter(structi2c_driver *driver,958                  struct i2c_adapter *adap)959{960   /* Detect supported devices on that bus, and instantiate them */961   i2c_detect(adap, driver);962963   /* Let legacy drivers scan this bus for matching devices */964   if (driver->attach_adapter) {965       dev_warn(&adap->dev, "%s: attach_adapter method isdeprecated\n",966            driver->driver.name);967       dev_warn(&adap->dev, "Please use another way to instantiate"968            "your i2c_client\n");969       /* We ignore the return code; if it fails, too bad */970       driver->attach_adapter(adap);971    }972   return 0;973}

这个函数我们在分析i2c_adapter的注册过程时已经分析过了,它主要完成i2c_driver与i2c_adapter上的i2c设备的匹配工作,如果匹配成功,初始化并注册对应的i2c_client。

至此,i2c_driver的注册过程我们就清楚了。

四、i2c_bus_type分析

i2c_init 函数完成Linux i2c框架的初始化工作,该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:

1429static int __init i2c_init(void)
1430{
1431   int retval;
1432
1433   retval = bus_register(&i2c_bus_type);
1434   if (retval)
1435       return retval;
1436#ifdef CONFIG_I2C_COMPAT
1437   i2c_adapter_compat_class =class_compat_register("i2c-adapter");
1438   if (!i2c_adapter_compat_class) {
1439       retval = -ENOMEM;
1440       goto bus_err;
1441   }
1442#endif
1443   retval = i2c_add_driver(&dummy_driver);
1444   if (retval)
1445       goto class_err;
1446   return 0;
1447
1448class_err:
1449#ifdef CONFIG_I2C_COMPAT
1450   class_compat_unregister(i2c_adapter_compat_class);
1451bus_err:
1452#endif
1453   bus_unregister(&i2c_bus_type);
1454   return retval;
1455}

1433行,调用bus_register注册了i2c_bus_type。i2c_bus_tpye定义在drivers/i2c/i2c-core.c文件中,其内容如下:

 442structbus_type i2c_bus_type = {443   .name       = "i2c",444   .match      = i2c_device_match,445   .probe      = i2c_device_probe,446   .remove     = i2c_device_remove,447   .shutdown   = i2c_device_shutdown,448   .pm     = &i2c_device_pm_ops,449};

其类型是bus_type,所以它代表i2c总线。我们来关注一下i2c_device_match和i2c_device_probe函数。

i2c_device_match函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:

 72static int i2c_device_match(struct device *dev, struct device_driver*drv)73{74    struct i2c_client   *client = i2c_verify_client(dev);75    struct i2c_driver   *driver;7677    if (!client)78        return 0;7980    /* Attempt an OF style match*/81    if(of_driver_match_device(dev, drv))82        return 1;8384    /* Then ACPI style match */85    if(acpi_driver_match_device(dev, drv))86        return 1;8788    driver = to_i2c_driver(drv);89    /* match on an id table ifthere is one */90    if (driver->id_table)91        returni2c_match_id(driver->id_table, client) != NULL;9293    return 0;94}

88行,将device_driver转换为i2c_driver。

90-91行,如果driver->id_table不为空,则调用i2c_match_id函数,该函数定义在drivers/i2c/i2c-core.c文件中,其内容如下:

 61static const struct i2c_device_id *i2c_match_id(const structi2c_device_id *id,62                        const struct i2c_client *client)63{64    while (id->name[0]) {65        if(strcmp(client->name, id->name) == 0)66            return id;67        id++;68    }69    return NULL;70}

可以看到,如果client->name和id->name相同,则匹配成功,返回id。如果返回NULL,则表示匹配失败。

分析到这里,我们要回顾一下分析Linux设备模型时涉及到的一个函数driver_match_device,该函数定义在drivers/base/base.h文件中,其内容如下:

116static inline intdriver_match_device(struct device_driver *drv,
117                      struct device *dev)
118{
119   return drv->bus->match ? drv->bus->match(dev, drv) : 1;
120}

当进行device和device_driver的匹配时,会调用这个函数,该函数返回值为0,表示match失败。只有match成功时,才会进一步进行probe。

可以看到,如果drv->bus->match存在,会调用drv->bus->match(dev,drv)。所以,当i2c设备(i2c_client)和i2c驱动(i2c_driver)进行匹配操作时,就会调用i2c_device_match函数。

在分析i2c_device_probe函数之前,我们要回顾一下分析Linux设备模型时涉及到的一个函数driver_probe_device,device_driver探测支持的device时,会调用到这个函数,它又会进一步调用really_probe函数,really_probe函数定义在drivers/base/dd.c文件中,其内容如下:

265static int really_probe(struct device*dev, struct device_driver *drv)
266{
267   int ret = 0;
268
269   atomic_inc(&probe_count);
270   pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
271        drv->bus->name, __func__, drv->name, dev_name(dev));
272   WARN_ON(!list_empty(&dev->devres_head));
273
274   dev->driver = drv;
275
276   /* If using pinctrl, bind pins now before probing */
277   ret = pinctrl_bind_pins(dev);
278   if (ret)
279       goto probe_failed;
280
281   if (driver_sysfs_add(dev)) {
282       printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
283            __func__, dev_name(dev));
284       goto probe_failed;
285   }
286
287   if (dev->bus->probe) {
288       ret = dev->bus->probe(dev);
289       if (ret)
290            goto probe_failed;
291   } else if (drv->probe) {
292       ret = drv->probe(dev);
293       if (ret)
294            goto probe_failed;
295   }
296
297   driver_bound(dev);
298   ret = 1;
299   pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
300        drv->bus->name, __func__, dev_name(dev), drv->name);
301   goto done;
302
303probe_failed:
304   devres_release_all(dev);
305   driver_sysfs_remove(dev);
306   dev->driver = NULL;
307   dev_set_drvdata(dev, NULL);
308
309   if (ret == -EPROBE_DEFER) {
310       /* Driver requested deferred probing */
311       dev_info(dev, "Driver %s requests probe deferral\n",drv->name);
312       driver_deferred_probe_add(dev);
313   } else if (ret != -ENODEV && ret != -ENXIO) {
314       /* driver matched but the probe failed */
315       printk(KERN_WARNING
316               "%s: probe of %s failedwith error %d\n",
317               drv->name, dev_name(dev),ret);
318   } else {
319       pr_debug("%s: probe of %s rejects match %d\n",
320               drv->name, dev_name(dev),ret);
321   }
322   /*
323    * Ignore errors returned by ->probe so that the next driver can try
324    * its luck.
325    */
326   ret = 0;
327done:
328   atomic_dec(&probe_count);
329   wake_up(&probe_waitqueue);
330   return ret;
331}

这个函数我们现在需要关注的是287-295行,如果dev->bus->probe存在,则调用dev->bus->probe(dev),如果dev->bus->probe不存在,并且drv->probe存在,才会调用drv->probe(dev)。所以,对于i2c设备和i2c驱动,探测设备时会优先调用i2c_bus_type.probe函数。而i2c_bus_type.probe即i2c_device_probe会转而调用i2c_driver.probe函数。

现在我们可以来看i2c_device_probe函数了,它定义在drivers/i2c/i2c-core.c文件中,其内容如下:

 233staticint i2c_device_probe(struct device *dev)234{235   struct i2c_client   *client =i2c_verify_client(dev);236   struct i2c_driver   *driver;237   int status;238239   if (!client)240       return 0;241242   driver = to_i2c_driver(dev->driver);243   if (!driver->probe || !driver->id_table)244       return -ENODEV;245   client->driver = driver;246   if (!device_can_wakeup(&client->dev))247       device_init_wakeup(&client->dev,248                    client->flags &I2C_CLIENT_WAKE);249   dev_dbg(dev, "probe\n");250251   status = driver->probe(client, i2c_match_id(driver->id_table,client));252   if (status) {253       client->driver = NULL;254        i2c_set_clientdata(client, NULL);255    }256   return status;257}

242行,取得i2c_driver。

243行,如果i2c_driver没有定义probe或者i2c_driver没有定义id_table,则直接退出。所以我们在写i2c驱动时,必须定义i2c_driver.probe和i2c_driver.id_table。

251行,调用i2c_driver.probe。这时,我们的i2c驱动程序定义的probe函数就会执行。

Linux设备驱动程序架构分析之I2C架构(基于3.10.1内核)相关推荐

  1. Linux设备模型分析之kobject(基于3.10.1内核)

    一.kobject结构定义 kobject是Linux设备模型的最底层数据结构,它代表一个内核对象. kobject结构体定义在include/linux/kobject.h文件中: [cpp] vi ...

  2. linux kset subsystem 3.10内核,Linux设备模型分析之kset(基于3.10.1内核)

    作者:刘昊昱 内核版本:3.10.1 一.kset结构定义 kset结构体定义在include/linux/kobject.h文件中,其内容如下: 142/** 143 * struct kset - ...

  3. Linux设备模型分析之kset(基于3.10.1内核)

    一.kset结构定义 kset结构体定义在include/linux/kobject.h文件中,其内容如下: [cpp] view plaincopy 142/** 143 * struct kset ...

  4. Linux设备驱动程序架构分析之一个I2C驱动实例

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 内核版本:3.10.1 编写一个I2C设备驱动程序的工作可分为两部分,一是定义和注册I2C设备,即i2c_clien ...

  5. linux设备驱动程序架构的研究,Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介)...

    Linux设备驱动程序学习(12) -Linux设备模型(底层原理简介) 以<LDD3>的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的.但是我个人认 ...

  6. linux kernel 2.6 i2c设备驱动程序框架介绍,linux设备驱动程序-i2c(2)-adapter和设备树的解析...

    linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 而在linux设备驱动程序--串行通信驱动框架分 ...

  7. 【原创】【专栏】《Linux设备驱动程序》--- LDD3源码目录结构和源码分析经典链接

    http://blog.csdn.net/geng823/article/details/37567557 [原创][专栏]<Linux设备驱动程序>--- LDD3源码目录结构和源码分析 ...

  8. 目前最全面深入的Linux设备驱动程序著作

    <精通Linux驱动程序开发(英文版)> 在Linux内核源代码树提供的各个子系统中,drivers/目录是其中最大的一个分支,它比其他子系统大数倍.随着各种新技术的广泛应用,内核中新的设 ...

  9. Linux 设备驱动程序(二)

    系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核(一) 深入理解 Linux 内核(二) Linux 设备驱动程序(一) Linux 设备驱动程序(二) Linux 设备驱动程序( ...

最新文章

  1. lda 吗 样本中心化 需要_PCA 与 LDA 分析
  2. Python 爬虫面试题 102 道
  3. LNMP一键安装包在安装完成后的一些安全设置
  4. Android之BaseAdapter—convertView回收机制与动态控件响应
  5. Redis实现消息队列和订阅发布模式
  6. ad用户和计算机无法启动,windows 2008AD计算机启动脚本无法执行
  7. tmux鼠标操作配置
  8. AcWing 9. 分组背包问题(分组背包模板)
  9. 有好事?卡巴斯基推出免费杀毒软件
  10. 人工神经网络到底能干什么?到底在干什么?
  11. Kinect + OpenNI + OpenCV + OpenGL 三维重建
  12. powerbi嵌入到HTML5,如何把Power BI嵌入到Web應用中
  13. 坐拥百度/阿里/腾讯,这家车载导航上市公司的营收却一路下挫?
  14. 酒店管理系统(功能结构图、E-R图、用例图)
  15. 4399 html5游戏平台,h5mini-2.0-sample
  16. 朴素和KMP匹配算法(java)
  17. 纯CSS实现超美选项卡
  18. win11 任务栏角溢出里的程序图标记录如何删除(WIN 缓存图标清理)
  19. 最大的成功是成为自己尊重的人
  20. power query连接mysql

热门文章

  1. openpyxl读取单元格填充颜色
  2. 【强化学习】(一)RL基本概念
  3. c#查看服务器的文件是否存在,c#此winform如何判断服务器上文件是否存在
  4. Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)
  5. Kruskal-Wallis test
  6. 百度amis学习笔记汇总
  7. Eyeshot Fem 2023.1.X Crack
  8. APP的登录认证与安全
  9. ​Word怎么转换成PDF格式?这三种方法教你如何转换
  10. telnet出现以下报错Escape character is '^]'. ,