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

Linux的I2C体系结构

2011-09-14 21:28 197 查看
  
Linux的I2C体系结构分为3个组成部分

1.       I2C核心

2.       I2C总线驱动

3.       I2C设备驱动

 

Linux下实现I2C驱动的主要工作

1.       提供I2C适配器的硬件驱动

2.       提供I2C适配器的algorithm

3.       实现I2C设备驱动与i2c_driver接口

4.       实现I2C设备驱动的文件操作

 

I2C核心主要函数

1.增加/删除i2c_adapter

int i2c_add_adapter(struct i2c_adapter *adap);

int i2c_del_adapter(struct i2c_adapter *adap);

2.增加/删除i2c_driver

int i2c_register_driver(struct module *owner, struct i2c_driver *driver);

int i2c_del_driver(struct i2c_driver *driver);

3.i2c_client依附/脱离

  int i2c_attach_client(struct i2c_client *client);

  int i2c_detach_client(struct i2c_client *client);

4.I2C传输、发送和接收

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

  int i2c_master_send(struct i2c_client *client,const char *buf ,int count);

  int i2c_master_recv(struct i2c_client *client, char *buf ,int count);

5.I2C控制命令分配

  int i2c_control(struct i2c_client *client,unsigned int cmd, unsigned long arg);

  void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg);

 

I2C总线驱动模块加载函数要完成两个工作

1.       初始化I2C适配器所使用的硬件资源

2.       通过i2c_add_adapter()添加i2c _adapter的数据结构

 

I2C总线驱动模块卸载函数要完成两个工作

1.       释放I2C适配器所使用的硬件资源

2.       通过i2c_del_adapter()删除i2c _adapter的数据结构

 

I2C设备驱动模块加载函数要完成两个工作

1.       通过I2C register_chrdev()函数将I2C设备注册为一个字符设备

2.       通过I2C核心的i2c_register_driver()函数添加i2c_driver

 

I2C设备驱动模块卸载函数要完成两个工作

1.       通过I2C核心的i2c_del_driver()函数删除i2c_driver

2.       通过unregister_chrdev()函数注销字符设备

 

关键数据结构

1.struct i2c_adapter {

         struct module *owner;

         unsigned int id;

         unsigned int class;

         const struct i2c_algorithm *algo; /* the algorithm to access the bus */

         void *algo_data;

 

         /* --- administration stuff. */

         int (*client_register)(struct i2c_client *);

         int (*client_unregister)(struct i2c_client *);

 

         /* data fields that are valid for all devices       */

         u8 level;                    /* nesting level for lockdep */

         struct mutex bus_lock;

         struct mutex clist_lock;

 

         int timeout;

         int retries;

         struct device dev;             /* the adapter device */

         struct class_device class_dev;         /* the class device */

 

         int nr;

         struct list_head clients;

         struct list_head list;

         char name[I2C_NAME_SIZE];

         struct completion dev_released;

         struct completion class_dev_released;

};//I2C适配器数据结构

 

 

 

2.struct i2c_algorithm {

         /* If an adapter algorithm can't do I2C-level access, set master_xfer

            to NULL. If an adapter algorithm can do SMBus access, set

            smbus_xfer. If set to NULL, the SMBus protocol is simulated

            using common I2C messages */

         /* master_xfer should return the number of messages successfully

            processed, or a negative value on error */

         int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,

                            int num);

         int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,

                            unsigned short flags, char read_write,

                            u8 command, int size, union i2c_smbus_data * data);

 

         /* --- ioctl like call to set div. parameters. */

         int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);

 

         /* To determine what the adapter supports */

         u32 (*functionality) (struct i2c_adapter *);

};//适配器的algorithm(一套通信方法)数据结构

 

 

 

3.struct i2c_driver {

         int id;

         unsigned int class;

 

         /* Notifies the driver that a new bus has appeared. This routine

          * can be used by the driver to test if the bus meets its conditions

          * & seek for the presence of the chip(s) it supports. If found, it

          * registers the client(s) that are on the bus to the i2c admin. via

          * i2c_attach_client.

          */

         int (*attach_adapter)(struct i2c_adapter *);

         int (*detach_adapter)(struct i2c_adapter *);

 

         /* tells the driver that a client is about to be deleted & gives it

          * the chance to remove its private data. Also, if the client struct

          * has been dynamically allocated by the driver in the function above,

          * it must be freed here.

          */

         int (*detach_client)(struct i2c_client *);

 

         /* driver model interfaces that don't relate to enumeration  */

         void (*shutdown)(struct i2c_client *);

         int (*suspend)(struct i2c_client *, pm_message_t mesg);

         int (*resume)(struct i2c_client *);

 

         /* a ioctl like command that can be used to perform specific functions

          * with the device.

          */

         int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);

 

         struct device_driver driver;

         struct list_head list;

};//对应一套通信方法

 

 

 

4.struct i2c_client {

         unsigned int flags;            /* div., see below              */

         unsigned short addr;                 /* chip address - NOTE: 7bit    */

                                               /* addresses are stored in the         */

                                               /* _LOWER_ 7 bits            */

         struct i2c_adapter *adapter; /* the adapter we sit on */

         struct i2c_driver *driver;         /* and our access routi
4000
nes      */

         int usage_count;               /* How many accesses currently  */

                                               /* to the client                   */

         struct device dev;             /* the device structure             */

         struct list_head list;

         char name[I2C_NAME_SIZE];

         struct completion released;

};//对应真实物理设备
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息