///////////////////////////////////////////////////postcore_initcall优先级比module_init高postcore_initcall(i2c_init);static int __init i2c_init(void){     retval = bus_register(&i2c_bus_type);    retval = class_register(&i2c_adapter_class);    retval = i2c_add_driver(&dummy_driver);}/////////////////////////////////////////////////static struct i2c_driver dummy_driver = {    .driver.name    = "dummy",    .probe        = dummy_probe,    .remove        = dummy_remove,    .id_table    = dummy_id,};/////////////////////////////////////////////////static struct device_attribute i2c_adapter_attrs[] = {    __ATTR(name, S_IRUGO, show_adapter_name, NULL),    { },};static struct class i2c_adapter_class = {    .owner            = THIS_MODULE,    .name            = "i2c-adapter",    .dev_attrs        = i2c_adapter_attrs,};/////////////////////////////////////////////////struct bus_type i2c_bus_type = {    .name        = "i2c",    .dev_attrs    = i2c_dev_attrs,    .match        = i2c_device_match,    .uevent        = i2c_device_uevent,    .probe        = i2c_device_probe,    .remove        = i2c_device_remove,    .shutdown    = i2c_device_shutdown,    .suspend    = i2c_device_suspend,    .resume        = i2c_device_resume,};总线提供了match和probe方法:match方法的用来进行client device( 是i2c_client 吧)和client driver的配对。在向总线i2c_bus_type注册设备或者驱动时 (i2c_add_driver函数或(i2c_register_driver)函数)会调用此方法/////////////////////////////////////////////////static int i2c_device_match(struct device *dev, struct device_driver *drv){//可以看出匹配的对象是struct i2c_client和  struct i2c_driver实例//也就是struct i2c_client被看成device了?    struct i2c_client    *client = to_i2c_client(dev);    struct i2c_driver    *driver = to_i2c_driver(drv);    /* make legacy i2c drivers bypass driver model probing entirely;     * such drivers scan each i2c adapter/bus themselves.     */    if (!is_newstyle_driver(driver))        return 0;    /* match on an id table if there is one *///匹配//可知//static struct i2c_driver at24_driver//    .id_table = at24_ids,这个ID表是用来匹配的,和i2c client的名字进行匹配    if (driver->id_table)        return i2c_match_id(driver->id_table, client) != NULL;    return 0;}/////////////////////////////////////////////////i2c_bus_type的probe方法是通过传递进来的drv找到包含此drv的i2c_driver驱动,然后再去调用i2c_driver的probe方法,此处就是at24_probe。为什么要这样呢?因为driver_register后,注册的是i2c_driver->drv,而drv中的probe未初始化,我们需要调用的是i2c-driver的probe方法。static int i2c_device_probe(struct device *dev){    struct i2c_client    *client = to_i2c_client(dev);    struct i2c_driver    *driver = to_i2c_driver(dev->driver);    int status;    if (!driver->probe || !driver->id_table)        return -ENODEV;    client->driver = driver;    if (!device_can_wakeup(&client->dev))        device_init_wakeup(&client->dev,                    client->flags & I2C_CLIENT_WAKE);    dev_dbg(dev, "probe\n");    status = driver->probe(client, i2c_match_id(driver->id_table, client));    if (status)        client->driver = NULL;    return status;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////** * i2c_add_numbered_adapter - declare i2c adapter, use static bus number * @adap: the adapter to register (with adap->nr initialized) * Context: can sleep * * This routine is used to declare an I2C adapter when its bus number * matters.  For example, use it for I2C adapters from system-on-chip CPUs, * or otherwise built in to the system's mainboard, and where i2c_board_info * is used to properly configure I2C devices. * * If no devices have pre-been declared for this bus, then be sure to * register the adapter before any dynamically allocated ones.  Otherwise * the required bus ID may not be available. * * When this returns zero, the specified adapter became available for * clients using the bus number provided in adap->nr.  Also, the table * of I2C devices pre-declared using i2c_register_board_info() is scanned, * and the appropriate driver model device nodes are created.  Otherwise, a * negative errno value is returned. *///这个函数在i2c核心层//在匹配完成后调用s3c24xx_i2c_probe函数调用i2c_add_numbered_adapter//执行完i2c_add_numbered_adapter函数后,内核的i2c总线上已有adapter device和client device//只和client匹配,不和adapter匹配,adapter和client已经关联?。 int i2c_add_numbered_adapter(struct i2c_adapter *adap){    int    id;    int    status;    if (adap->nr & ~MAX_ID_MASK)        return -EINVAL;retry:    if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)        return -ENOMEM;    mutex_lock(&core_lock);    /* "above" here means "above or equal to", sigh;     * we need the "equal to" result to force the result     */    status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);    if (status == 0 && id != adap->nr) {        status = -EBUSY;        idr_remove(&i2c_adapter_idr, id);    }    mutex_unlock(&core_lock);    if (status == -EAGAIN)        goto retry;    if (status == 0)//注册adapter设备        status = i2c_register_adapter(adap);    return status;}/////////////////////////////////////////////////////////////////////////////////////static int i2c_register_adapter(struct i2c_adapter *adap){    int res = 0, dummy;    /* Can't register until after driver model init */    if (unlikely(WARN_ON(!i2c_bus_type.p)))        return -EAGAIN;    mutex_init(&adap->bus_lock);    mutex_init(&adap->clist_lock);    INIT_LIST_HEAD(&adap->clients);    mutex_lock(&core_lock);    /* Add the adapter to the driver core.     * If the parent pointer is not set up,     * we add this adapter to the host bus.     */    if (adap->dev.parent == NULL) {        adap->dev.parent = &platform_bus;        pr_debug("I2C adapter driver [%s] forgot to specify "             "physical device\n", adap->name);    }//  /sys/bus/i2c/devices/i2c-0// /sys/bus/i2c/devices/i2c-1//i2c-0 就是adapter device    sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);    adap->dev.release = &i2c_adapter_dev_release;// 看看   driver->driver.bus = &i2c_bus_type;//struct i2c_adapter         ------>绑定i2c_adapter_class//struct i2c_client(i2c_device)------>绑定i2c_bus_type//struct i2c_driver    (at24.c   at24_driver)        ------>绑定i2c_bus_type    adap->dev.class = &i2c_adapter_class;//将名为i2c-0的adapter设备注册    res = device_register(&adap->dev);    /* create pre-declared device nodes for new-style drivers */    if (adap->nr        i2c_scan_static_board_info(adap);    /* Notify drivers *///识别一下,看看有没有///尝试和i2c总线上所有的dev进行一次匹配,只要获取的dev为adapter时,就可执行后续操作//bus_for_each_drv()是对BUS上所有的Driver都进行__device_attach()操作;//同样的,bus_for_each_dev()是对BUS上所有的Device都进行__driver_attach()操作    dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,                 i2c_do_add_adapter);}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////首先从__i2c_board_list链表上获取一个devinfo信息结构体,此结构体由前面的smdk6410_machine_init函数调用i2c_register_board_info()添加到i2c设备链表上的。结构体中包含板上的i2cat24c02设备相关信息。然后在此函数中调用i2c_new_device()以从链表上获取的devinfo作为参数,i2c_new_device函数根据devinfo中的设备相关信息来创建client,内核中使用client来代表at24c02设备。static void i2c_scan_static_board_info(struct i2c_adapter *adapter){    struct i2c_devinfo    *devinfo;    mutex_lock(&__i2c_board_lock);//遍历__i2c_board_list链表////static struct i2c_board_info i2c_devs0[]//smdk6410_machine_init()--->// i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); //  i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));//此处的0和1是+1后就是devinfo->busnum,也就是adapter->nr,应该就是代表第几组寄存器组吧?//i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)    list_for_each_entry(devinfo, &__i2c_board_list, list) {//// s3c24xx_i2c_probe函数    i2c->adap.nr = pdata->bus_num;//如果adapter的号码和节点中的号码相同,才会调用i2c_new_device创建i2c clien        if (devinfo->busnum == adapter->nr                && !i2c_new_device(adapter,                        &devinfo->board_info))            printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",                i2c_adapter_id(adapter),                devinfo->board_info.addr);    }    mutex_unlock(&__i2c_board_lock);}//////////////////////////////////////////////////////////////////////////////////////** * i2c_new_device - instantiate an i2c device for use with a new style driver * @adap: the adapter managing the device * @info: describes one I2C device; bus_num is ignored * Context: can sleep * * Create a device to work with a new style i2c driver, where binding is * handled through driver model probe()/remove() methods.  This call is not * appropriate for use by mainboad initialization logic, which usually runs * during an arch_initcall() long before any i2c_adapter could exist. * * This returns the new i2c client, which may be saved for later use with * i2c_unregister_device(); or NULL to indicate an error. */struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info){    struct i2c_client    *client;    int            status;    client = kzalloc(sizeof *client, GFP_KERNEL);    if (!client)        return NULL;//client 和adap是相互关联到一起的。    client->adapter = adap;    client->dev.platform_data = info->platform_data;    if (info->archdata)        client->dev.archdata = *info->archdata;    client->flags = info->flags;//这里是从设备地址    client->addr = info->addr;    client->irq = info->irq;// i2c_board_info中的名字给了client////static struct i2c_board_info i2c_devs0[] __initdata = {// { I2C_BOARD_INFO("24c08", 0x50), },          //0x50为IIC芯片设备地址  //"24c08"这个名字就是用来创建i2c_client来和里static struct i2c_driver at24_driver进行匹配的。    strlcpy(client->name, info->type, sizeof(client->name));    /* a new style driver may be bound to this device when we     * return from this function, or any later moment (e.g. maybe     * hotplugging will load the driver module).  and the device     * refcount model is the standard driver model one.     */    status = i2c_attach_client(client);    if (status        kfree(client);        client = NULL;    }    return client;}/////////////////////////////////////////////////////////////////////////////////////int i2c_attach_client(struct i2c_client *client){    struct i2c_adapter *adapter = client->adapter;    int res;    /* Check for address business */    res = i2c_check_addr(adapter, client->addr);    if (res)        return res;    client->dev.parent = &client->adapter->dev;//struct i2c_adapter         ------>绑定i2c_adapter_class//struct i2c_client(i2c_device)------>绑定i2c_bus_type//struct i2c_driver    (at24.c   at24_driver)        ------>绑定i2c_bus_type//client被注册到i2c_bus_type总线//static struct i2c_driver dummy_driver 这个也是注册到i2c_bus_type总线    client->dev.bus = &i2c_bus_type;    if (client->driver)        client->dev.driver = &client->driver->driver;    if (client->driver && !is_newstyle_driver(client->driver)) {        client->dev.release = i2c_client_release;        client->dev.uevent_suppress = 1;    } else        client->dev.release = i2c_client_dev_release;///sys/bus/i2c/devices # ls //           0-001b  0-0050  i2c-0   i2c-1   i2c-2//  /sys/bus/i2c/devices/0-001b// /sys/bus/i2c/devices/0-0050//0-001b就是client device    snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),        "%d-%04x", i2c_adapter_id(adapter), client->addr);//注册client的父类到内核//int i2c_register_driver(struct module *owner, struct i2c_driver *driver)//    driver->driver.bus = &i2c_bus_type;//    res = driver_register(&driver->driver);//这么像,应该能猜到client->dev就是device->dev    res = device_register(&client->dev);    if (res)        goto out_err;    mutex_lock(&adapter->clist_lock);    list_add_tail(&client->list, &adapter->clients);    mutex_unlock(&adapter->clist_lock);    dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",        client->name, client->dev.bus_id);    if (adapter->client_register)  {        if (adapter->client_register(client)) {            dev_dbg(&adapter->dev, "client_register "                "failed for client [%s] at 0x%02x\n",                client->name, client->addr);        }    }    return 0;out_err:    dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "        "(%d)\n", client->name, client->addr, res);    return res;}///////////////////////////////////////////////////////////////////////////////////////////////static int i2c_do_add_adapter(struct device_driver *d, void *data){    struct i2c_driver *driver = to_i2c_driver(d);    struct i2c_adapter *adap = data;    /* Detect supported devices on that bus, and instantiate them */    i2c_detect(adap, driver);    /* Let legacy drivers scan this bus for matching devices */    if (driver->attach_adapter) {        /* We ignore the return code; if it fails, too bad *///调用//static struct i2c_driver i2cdev_driver = {//    .attach_adapter    = i2cdev_attach_adapter,//此处调用i2cdev_attach_adapter函数        driver->attach_adapter(adap);    }    return 0;}/////////////////////////////////////////////////////////////////////////////////////////////////和 i2c_do_add_adapter对比一下,就^_^static int __attach_adapter(struct device *dev, void *data){    struct i2c_adapter *adapter = to_i2c_adapter(dev);    struct i2c_driver *driver = data;    i2c_detect(adapter, driver);    /* Legacy drivers scan i2c busses directly */    if (driver->attach_adapter)        driver->attach_adapter(adapter);    return 0;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static inline int i2c_add_driver(struct i2c_driver *driver){    return i2c_register_driver(THIS_MODULE, driver);}/////////////////////////////////////////////* * An i2c_driver is used with one or more i2c_client (device) nodes to access * i2c slave chips, on a bus instance associated with some i2c_adapter.  There * are two models for binding the driver to its device:  "new style" drivers * follow the standard Linux driver model and just respond to probe() calls * issued if the driver core sees they match(); "legacy" drivers create device * nodes themselves. *///对比//static int i2c_register_adapter(struct i2c_adapter *adap)//这两个函数里面是何其形似,所以 i2c_register_adapter相当于 i2c_register_device,和i2c_register_driver匹配int i2c_register_driver(struct module *owner, struct i2c_driver *driver){    int res;    /* Can't register until after driver model init */    if (unlikely(WARN_ON(!i2c_bus_type.p)))        return -EAGAIN;    /* new style driver methods can't mix with legacy ones */    if (is_newstyle_driver(driver)) {        if (driver->attach_adapter || driver->detach_adapter                || driver->detach_client) {            printk(KERN_WARNING                    "i2c-core: driver [%s] is confused\n",                    driver->driver.name);            return -EINVAL;        }    }    /* add the driver to the list of i2c drivers in the driver core */    driver->driver.owner = owner;////int i2c_attach_client(struct i2c_client *client)// client->dev.bus = &i2c_bus_type;//client被注册到i2c_bus_type总线//static struct i2c_driver dummy_driver 这个也是注册到i2c_bus_type总线//struct i2c_adapter         ------>绑定i2c_adapter_class//struct i2c_client(i2c_device)------>绑定i2c_bus_type//struct i2c_driver            ------>绑定i2c_bus_type    driver->driver.bus = &i2c_bus_type; //见//int i2c_attach_client(struct i2c_client *client)//--->    client->dev.parent = &client->adapter->dev;//    client->dev.bus = &i2c_bus_type;//    res = device_register(&client->dev);//这么像,是不是必须client是device.呵呵    /* for new style drivers, when registration returns the driver core     * will have called probe() for all matching-but-unbound devices.     */    res = driver_register(&driver->driver);    if (res)        return res;    mutex_lock(&core_lock);    pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);    INIT_LIST_HEAD(&driver->clients);    /* Walk the adapters that are already present */// i2c_register_adapter里也有一个 bus_for_each_drv    class_for_each_device(&i2c_adapter_class, NULL, driver,                  __attach_adapter);    mutex_unlock(&core_lock);    return 0;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////** * i2c_transfer - execute a single or combined I2C message * @adap: Handle to I2C bus * @msgs: One or more messages to execute before STOP is issued to *    terminate the operation; each message begins with a START. * @num: Number of messages to be executed. * * Returns negative errno, else the number of messages executed. * * Note that there is no requirement that each message be sent to * the same slave address, although that is the most common model. */ at24_eeprom_read调用i2c_transferint i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num){    int ret;    /* REVISIT the fault reporting model here is weak:     *     *  - When we get an error after receiving N bytes from a slave,     *    there is no way to report "N".     *     *  - When we get a NAK after transmitting N bytes to a slave,     *    there is no way to report "N" ... or to let the master     *    continue executing the rest of this combined message, if     *    that's the appropriate response.     *     *  - When for example "num" is two and we successfully complete     *    the first message but get an error part way through the     *    second, it's unclear whether that should be reported as     *    one (discarding status on the second message) or errno     *    (discarding status on the first one).     */    if (adap->algo->master_xfer) {#ifdef DEBUG        for (ret = 0; ret            dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "                "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)                ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,                (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");        }#endif        if (in_atomic() || irqs_disabled()) {            ret = mutex_trylock(&adap->bus_lock);            if (!ret)                /* I2C activity is ongoing. */                return -EAGAIN;        } else {            mutex_lock_nested(&adap->bus_lock, adap->level);        }//发送数据////static const struct i2c_algorithm s3c24xx_i2c_algorithm = {//    .master_xfer        = s3c24xx_i2c_xfer,//此处调用 s3c24xx_i2c_xfer函数        ret = adap->algo->master_xfer(adap,msgs,num);        mutex_unlock(&adap->bus_lock);        return ret;    } else {        dev_dbg(&adap->dev, "I2C level transfers not supported\n");        return -EOPNOTSUPP;    }}
12-10 01:10
查看更多