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 <frodol@dds.nl> and "
"Simon G. Vogl <simon@tk.uni-linz.ac.at>");
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_MAJOR : 89
“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 rtc
i2cdev_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");
创建一个名字为i2c-dev 的类,可以通过cd /sys/class查看
# cd /sys/class
# ls i2c-dev
i2c-0
i2c-1
i2c-2
i2c-3
3.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;
}