I2c-dev.c的作用是创建了适配器的节点,为用户空间访问i2c适配器的方法。路径:drivers\i2c\I2c-dev.c
一、适配器驱动的初始化卸载:
static int __init i2c_dev_init(void) { int res; printk(KERN_INFO "i2c /dev entries driver\n"); 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)) goto out_unreg_chrdev; res = i2c_add_driver(&i2cdev_driver); if (res) goto out_unreg_class; return 0; out_unreg_class: class_destroy(i2c_dev_class); out_unreg_chrdev: unregister_chrdev(I2C_MAJOR, "i2c"); out: printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__); return res; } static void __exit i2c_dev_exit(void) { i2c_del_driver(&i2cdev_driver); class_destroy(i2c_dev_class); unregister_chrdev(I2C_MAJOR,"i2c"); } MODULE_AUTHOR("Frodo Looijaard <[email protected]> and " "Simon G. Vogl <[email protected]>"); MODULE_DESCRIPTION("I2C /dev entries driver"); MODULE_LICENSE("GPL"); module_init(i2c_dev_init); module_exit(i2c_dev_exit);1.res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
“i2c” :注册的字符设备名字,
i2cdev_fops : 用户空间访问i2c适配器的读写
验证:cat /proc/devices
Character devices: 1 mem 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 10 misc 13 input 14 sound/mixer 14 sound/dsp 14 sound/audio 14 sound/mixer1 14 sound/dsp1 14 sound/audio1 14 sound/adsp1 14 sound/mixer2 14 sound/dsp2 14 sound/audio2 14 sound/adsp2 29 fb 81 video4linux 89 i2c //前面号为主设备号,后面就是i2c的名字 90 mtd 108 ppp 116 alsa 125 pixcir_i2c_ts 128 ptm 136 pts 153 spi 216 rfcomm 220 ttyNK 223 vbpipe 250 ts0710mux 251 mali 252 ump 253 ttyGS 254 rtci2cdev_fops的实现( 对于i2c适配器的读写以后再分析):
static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, .llseek = no_llseek,//查找 .read = i2cdev_read,//读 .write = i2cdev_write,//写 .ioctl = i2cdev_ioctl,//ioctl .open = i2cdev_open,//打开 .release = i2cdev_release,//释放 };2.i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
# cd /sys/class # ls i2c-dev i2c-0 i2c-1 i2c-2 i2c-33.res = i2c_add_driver(&i2cdev_driver);
将i2cdev_driver添加进内核,这段代码的执行会导致i2ccdev_driver->attach_adapter的执行。先看下i2cdev_driver的定义:
static struct i2c_driver i2cdev_driver = { .driver = { .name = "dev_driver", }, .id = I2C_DRIVERID_I2CDEV, .attach_adapter = i2cdev_attach_adapter,//这个会被执行 .detach_adapter = i2cdev_detach_adapter, .detach_client = i2cdev_detach_client, };i2cdev_attach_adapter
static int i2cdev_attach_adapter(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; int res; i2c_dev = get_free_i2c_dev(adap); if (IS_ERR(i2c_dev)) return PTR_ERR(i2c_dev); /* register this i2c device with the driver core */ i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, MKDEV(I2C_MAJOR, adap->nr), "i2c-%d", adap->nr);//在/dev下面创建i2c-*节点 if (IS_ERR(i2c_dev->dev)) { res = PTR_ERR(i2c_dev->dev); goto error; } res = device_create_file(i2c_dev->dev, &dev_attr_name); if (res) goto error_destroy; pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", adap->name, adap->nr); return 0; error_destroy: device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); error: return_i2c_dev(i2c_dev); return res; }