并且i2c adapter的驱动通过i2cdev_driver这个通用驱动的attach方法来实现注册的。
下面具体分析整个过程。
static int __init i2c_dev_init(void) { 。。。 。。。 res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops); if (res) goto out; i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); if (IS_ERR(i2c_dev_class)) { res = PTR_ERR(i2c_dev_class); goto out_unreg_chrdev; } res = i2c_add_driver(&i2cdev_driver); 。。。 。。。 }函数首先调用register_chardev函数向内核注册主备号为I2C_MAJOR、操作集为i2cdev_fops的字符设备。
register_chrdev函数最终会向系统注册主设备为I2C_MAJOR,此设备号为0~255的设备。这表示系统最多可以容纳256个i2c adapter,adapter的字符操作方法i2cdev_fops如下:
static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, .unlocked_ioctl = i2cdev_ioctl, .open = i2cdev_open, .release = i2cdev_release, };
当read()、write()、open()、close()、ioctl()等系统调用发生时就会调用到这些函数。
但是i2cdev_fops其实是通用的的操作,应为不同的adapter对应的操作方法肯定有区别所以这里的fops只是具体adapter操作方法的一层外壳,具体稍后分析。
字符设备注册完毕后通过class_create()函数初始化一个类i2c_dev_class,这个类稍后需要使用,用于在/dev/i2c-0下自动创建设备,后面分析。
类初始化完毕后,然后调用函数i2c_add_driver函数注册i2c driver。这里所说的i2c其实对应的是系统中所有的i2c类设备。
通过i2c driver中的attach_adapter方法来实现将adapter和对应的驱动绑定。
static struct i2c_driver i2cdev_driver = { .driver = { .name = "dev_driver", }, .attach_adapter = i2cdev_attach_adapter, .detach_adapter = i2cdev_detach_adapter, };
此处注意attach_adapter这个方法,/dev目录下的设备创建是在通过执行此函数实现的。下面具体分析i2c_add_driver注册i2cdev_driver的过程
2.i2c_add_driver
i2c_add_driver函数只是对i2c_register_driver做了简单的封装,下面直接分析i2c_register_driver