I2C驱动框架(五)

参考:I2C子系统之 adapter driver注册——I2C_dev_init()

i2c的操作在内核中是当做字符设备来操作的,相关初始化在由i2c_dev_init函数来初始化。

static int __init i2c_dev_init(void)
{
    int res;
    printk(KERN_INFO "i2c /dev entries driver
");
    register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);//注册字符设备 主设备号89
    i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
    /* Keep track of adapters which will be added or removed later */
    res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
    /* Bind to already existing adapters right away */
    i2c_for_each_dev(NULL, i2cdev_attach_adapter);
    return 0;
}

i2c_for_each_dev(NULL, i2cdev_attach_adapter)遍历i2c_bus_type总线上的设备,对找到的设备执行i2cdev_attach_adapter()函数绑定adapter并在/dev/目录下创建设备节点。

i2c_for_each_dev(NULL, i2cdev_attach_adapter);
    -->i2cdev_attach_adapter(struct device *dev, void *dummy)
        -->if (dev->type != &i2c_adapter_type)    return 0; //只操作i2c_adapter_type类型的设备
        -->struct i2c_adapter *adap = to_i2c_adapter(dev); //找到对应的i2c_adapter结构体
        -->struct i2c_dev *i2c_dev = get_free_i2c_dev(adap);
            -->struct i2c_dev *i2c_dev->adap = adap;
            -->list_add_tail(&i2c_dev->list, &i2c_dev_list);
        -->i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, MKDEV(I2C_MAJOR, adap->nr), NULL,"i2c-%d", adap->nr);

因为分析的代码中只注册了一个i2c_adapter设备,所以只生成一个设备节点/dev/i2c-0

读设备的流程,最终调用的是i2c_adapter结构体中的成员函数master_xfer。

static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,loff_t *offset)
    -->ret = i2c_master_recv(client, tmp, count);
        -->i2c_transfer(adap, &msg, 1);
            -->adap->algo->master_xfer(adap, msgs, num);
                -->s3c24xx_i2c_xfer
    --> copy_to_user(buf, tmp, count) 
原文地址:https://www.cnblogs.com/yangjiguang/p/6220600.html