在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 来发送命令的
/* 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 来发送命令的