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\n"); 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)