i2c_driver的detect函数的调用

来源:互联网 发布:森海塞尔大馒头 知乎 编辑:程序博客网 时间:2024/05/16 05:36
在i2c_register_adapter 中会调用
    /* Notify drivers */
    mutex_lock(&core_lock);
    bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
    mutex_unlock(&core_lock);
来通知所有总线类型是i2c_bus_type的driver,现在已经增加新增加了adapter了
static int __process_new_adapter(struct device_driver *d, void *data)
{
    return i2c_do_add_adapter(to_i2c_driver(d), data);
}
i2c_do_add_adapter->i2c_detect->i2c_detect_address 中有一段关键code    
    err = driver->detect(temp_client, &info);
    if (err) {
        /* -ENODEV is returned if the detection fails. We catch it
           here as this isn't an error. */
        return err == -ENODEV ? 0 : err;
    }

来检测是否有i2c_driver 存在。这里的detect是在定义i2c_driver的时候定义的。

static struct i2c_driver ssif_i2c_driver = {
    .class        = I2C_CLASS_HWMON,
    .driver        = {
        .name            = DEVICE_NAME
    },
    .probe        = ssif_probe,
    .remove        = ssif_remove,
    .alert        = ssif_alert,
    .id_table    = ssif_id,
    .detect        = ssif_detect
};



static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info)
{
    unsigned char *resp;
    unsigned char msg[3];
    int           rv;
    int           len;

    resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
    if (!resp)
        return -ENOMEM;

    /* Do a Get Device ID command, since it is required. */
    msg[0] = IPMI_NETFN_APP_REQUEST << 2;
    msg[1] = IPMI_GET_DEVICE_ID_CMD;
    rv = do_cmd(client, 2, msg, &len, resp);
    if (rv)
        rv = -ENODEV;
    else
        strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE);
    kfree(resp);
    return rv;
}
可以看到是通过i2c_client 来发送命令的