您的位置:首页 > 运维架构 > Linux

linux-2.6.22.6 i2c总线驱动分析

2011-11-24 13:26 519 查看
 
I2C总线驱动模型:

       用户空间     应用程序

---------------------system_call-----------------

             I2C 设备驱动(设备一般挂在i2c适配器上,通过i2c适配器与cpu交换数据)

             I2C核心(i2c-core.c)

             I2C总线驱动层(I2C适配器数据结构I2C_adapter,)

                    \\

内核空间             I2C适配器

-----------------------------------------------------

硬件                 I2C适配器

                   //          \\

                  I2C设备     I2C设备

 

Busses文件夹 i2c总线驱动。

注意:i2c_dev.c实现了i2c适配器设备文件的功能,每个i2c适配器都被分配一个设备。

 

/drivers/i2c/chips/ds1337.c (chips文件中包含i2c设备驱动)

 

 

i2c_add_driver(&ds1337_driver) //添加driver到i2c driver_list

       i2c_register_driver(THIS_MODULE, driver);

              driver->driver.bus = &i2c_bus_type;

list_add_tail(&driver->list,&drivers);  //添加到list末尾

 

/**遍历adpaters_list,调用attach_adapter()进行匹配**/

list_for_each_entry(adapter, &adapters, list) {

                     driver->attach_adapter(adapter);

}                        \\

                        i2c_driver结构体中的attach_adapter()

                  

 

 //构造 i2cdriver结构体

static struct i2c_driver at24c02_driver = {

       .driver = {

 

 

              .name      = "at24c02",

       },

     /*识别枚举i2c设备*/

       .attach_adapter       = at24c02_attach_adapter,

       .detach_client  = at24c02_detach_client,

};

 

     at24c02_attach_adapter(struct i2c_adapter *adapter)

          //调用i2c_probe,判断设备地址是否存在……

          //若存在,则调用at24c02_detect()进一步处理(通过adapter发送设备地址)

          i2c_probe(adapter, &at24c02_addr_data, at24c02_detect);

                 i2c_probe_address(); //匹配地址

                            i2c_smbus_xfer();//传递信息、地址

                                   i2c_smbus_xfer_emulated(); //传递信息/地址

                                          i2c_transfer(adapter, msg, num);//

 

       i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)

                     adap->algo->master_xfer(adap,msgs,num);

    注意:i2c_transfer()不具备驱动适配器完成消息交互的能力;最终它会找到匹配i2c_adapter对应的i2c_algorithm的master_xfer的函数指针,调用相关总线驱动来发送数据。

 

master_xfer();传输数据

 master_xfer()调用i2c_s3c2410.c 中的 .master_xfer

       /driver/i2c/busses/i2c_s3c2410.c

 

       static const struct i2c_algorithm s3c24xx_i2c_algorithm = {

       .master_xfer          = s3c24xx_i2c_xfer,

       .functionality          = s3c24xx_i2c_func,

};

 

static struct s3c24xx_i2c s3c24xx_i2c = {

       .lock              = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),

       .wait              = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),

       .tx_setup = 50,

       .adap              = {

              .name                    = "s3c2410-i2c",

              .owner                  = THIS_MODULE,

              .algo                     = &s3c24xx_i2c_algorithm,

              .retries           = 2,

              .class                    = I2C_CLASS_HWMON,

       },

};

 

s3c24xx_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)

              3c24xx_i2c_doxfer(i2c, msgs, num);

                     s3c24xx_i2c_message_start(i2c, msgs); //向底层硬件传递信息

 

底层硬件,操作相关的寄存器来完成数据的发送……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息