linux驱动之i2c子系统device注册driver注册简单分析

Linux 驱动设计主要是根据分层分离思想,i2c子系统分为i2cocre、adapter、及device_driver层,其实adapter也是个device,只不过是我们主控芯片的I2C控制接口而已,我们的主控芯片有几个I2C接口就有几个adapter;

 

i2ccore这一层linux已经帮我们实现,主要的工做是类似platform总线的作用,负责drvier及设备的注册,相比platform多了个adapter的注册管理工作,以及i2c的数据发送接收等等算法,说算法有点夸大,其实就是按照i2c的通讯协议做的收发时序而已;

 

adapter这一层一般主控芯片厂家会提供,所以也不需自己编写,s3c2440芯片这一层是采用的s3c2410的适配器驱动,大致框架是采用platform虚拟总线,向i2ccore注册adapter驱动;

 

device_driver这端的驱动就要求自己编写了,这主要是我们外接设备的驱动,比如一些i2c接口的三轴加速度计、at24c0x系列的eeprom等等……这部分代码其实就是实现如何操作他们,比如发什么数据给他们可以启动他们、发什么数据给他们可以读到数据。

 

按照i2ccore的框架,device_driver 分为两部分内容,一个是device的注册,另一部分是driver的注册,在两边分别完成注册的时候,会分别调用i2ccore的match函数,进行匹配,匹配和platform的匹配方式一致,是通过名字进行匹配,不过这个名字和platform的名字不一样而已;如下列出device及driver注册在i2ccore中的调用过程,从过程中可以看出匹配、绑定及调用driver端的probe函数过程:

 

注册device:

 

i2c_new_device
    device_register
        device_add
            bus_probe_device
                /* 判断device与driver是否匹配 */
                device_attach
                    /* 匹配成功,调用bind函数绑定 */
                    device_bind_driver
                        /* 绑定成功,调用driver端的probe函数 */
                         driver_deferred_probe_del ( dev );
                        driver_deferred_probe_trigger();

 

注册driver:

i2c_register_driver
    driver_register
        bus_add_driver
            driver_attach
                /* 在总线上的没个设备轮训匹配,实际是调用__driver_attach函数进行匹配 */
                bus_for_each_dev ( drv->bus, NULL, drv, __driver_attach );
                    if ( !dev->driver )                            // 如果设备还未绑定driver
                  driver_probe_device ( drv, dev );
                      ret = really_probe ( dev, drv );
                          dev->driver = drv;                      // 设备和driver绑定
                          ret = drv->probe ( dev );          // 调用driver的probe
                             driver_bound ( dev );              // device和driver绑定

 

总结下就是编写i2c设备驱动,和platform虚拟总线一致,只不过最后是注册到了i2c总线而已;linux驱动还是采用分离分层的思想设计驱动。

以上代码属于3.4.2内核。

posted @ 2017-09-01 18:04  迷途小菜鸟  阅读(1144)  评论(0编辑  收藏  举报