linux IIC子系统框架
2017-03-16 15:37
190 查看
一、基本知识:
1、cpu一般只有一个iic_core,有几条IIC总线,就会有几个adapter;
2、板上有多少个外围IIC设备,就会有多少个iic_client;
3、ls -l /dev/i*就会看到主设备号只有一个(89),有几条IIC总线,就会有多少个次设备号;
4、IIC驱动其实包括两方面:适配器驱动(或者叫IIC总线驱动)和iic设备驱动。
适配器驱动:可能是linux内核本身还不包含的,需提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。提供I2C适配器的algorithm,具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。
设备驱动:实现I2C设备驱动中的i2c_driver接口,具体设备yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、resume和id_table指针。
二、框架图
二、probe函数什么执行?
从driver_register看起,此处我的这里是:
klist_init不相关,不用管他,具体再去看bus_add_driver:
真正起作用的是__driver_attach:
really_probe才是我们要找的函数:
参考:
1、http://blog.csdn.net/bhfantasy/article/details/46045605
2、http://blog.chinaunix.net/uid-22030783-id-1710998.html
3、http://www.linuxidc.com/Linux/2014-05/101648p2.htm
4、http://www.linuxidc.com/Linux/2011-03/33863p2.htm
1、cpu一般只有一个iic_core,有几条IIC总线,就会有几个adapter;
2、板上有多少个外围IIC设备,就会有多少个iic_client;
3、ls -l /dev/i*就会看到主设备号只有一个(89),有几条IIC总线,就会有多少个次设备号;
4、IIC驱动其实包括两方面:适配器驱动(或者叫IIC总线驱动)和iic设备驱动。
适配器驱动:可能是linux内核本身还不包含的,需提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。提供I2C适配器的algorithm,具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。
设备驱动:实现I2C设备驱动中的i2c_driver接口,具体设备yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、resume和id_table指针。
二、框架图
二、probe函数什么执行?
从driver_register看起,此处我的这里是:
int driver_register(struct device_driver * drv) { if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) { printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); } klist_init(&drv->klist_devices, NULL, NULL); return bus_add_driver(drv); }
klist_init不相关,不用管他,具体再去看bus_add_driver:
int bus_add_driver(struct device_driver *drv) { //1.先kobject_set_name(&drv->kobj, "%s", drv->name); //2.再kobject_register(&drv->kobj) //3.然后调用了:driver_attach(drv) }
int driver_attach(struct device_driver * drv) { return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); }
真正起作用的是__driver_attach:
static int __driver_attach(struct device * dev, void * data) { ... if (!dev->driver) driver_probe_device(drv, dev); ... } int driver_probe_device(struct device_driver * drv, struct device * dev) { ... //1.先是判断bus是否match: if (drv->bus->match && !drv->bus->match(dev, drv)) goto done; //2.再具体执行probe: ret = really_probe(dev, drv); ... }
really_probe才是我们要找的函数:
static int really_probe(struct device *dev, struct device_driver *drv) { ... //1.先是调用的驱动所属总线的probe函数: if (dev->bus->probe) { ret = dev->bus->probe(dev); if (ret) goto probe_failed; } else if (drv->probe) { //2.再调用你的驱动中的probe函数: ret = drv->probe(dev); if (ret) goto probe_failed; } ... }
参考:
1、http://blog.csdn.net/bhfantasy/article/details/46045605
2、http://blog.chinaunix.net/uid-22030783-id-1710998.html
3、http://www.linuxidc.com/Linux/2014-05/101648p2.htm
4、http://www.linuxidc.com/Linux/2011-03/33863p2.htm
相关文章推荐
- linux设备之输入子系统框架及API
- Linux输入子系统框架
- 【Linux高级驱动】input子系统框架
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- Linux的input输入子系统:总体框架
- 利用linux中iic子系统做IIC驱动
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- 学习笔记 --- LINUX TTY子系统框架分析
- 学习笔记 --- LINUX MTD子系统框架分析
- Linux驱动修炼之道-RTC子系统框架与源码分析
- 一 linux spi子系统(框架)
- Linux输入子系统(1):总体框架
- 输入服务子系统框架代码分析(韦东山的视频总结及针对linux-2.6.30.4)
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- LINUX驱动之IIC子系统之三I2C的数…
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless) .
- Linux IIC驱动框架理解
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)