Note

载入中...

分类

载入中...

最新文章

载入中...

回复

载入中...

站点统计

载入中...
linux下I2C驱动(三)2007-1-26 9:45:00
linux下I2C驱动(三)
by good02xaut
4中核心的数据结构:
 

3.1 i2c_algorithm解析

Algorithm代表了当前I2C adapter的行为特征,必须能够描述adapter的所有传输行为。

struct i2c_algorithm {

       char name[32];             //算法名称

       unsigned int id;        //算法ID

      

       //master_xfer提供的是i2c_transfer实现部分。更多的I2C adapter工作于I2C总线主机模式。

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

                          int num);

   // smbus_xfer提供i2c_smbus_xfer的实现部分。只有I2C adapter工作于SMBus模式,需要提供。也就是说,I2C adapter必须指定I2C还是SMBus其中的一个。

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

                          unsigned short flags, char read_write,

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

       /* 从机模式,通常adapter不会做从机*/

       int (*slave_send)(struct i2c_adapter *,char*,int);

       int (*slave_recv)(struct i2c_adapter *,char*,int);

 

       /* 类似于ioctl,实现一些设定控制功能 */

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

 

       /* I2C adapter的功能函数,用户自己定义*/

       u32 (*functionality) (struct i2c_adapter *);

};

基于标准I2C busadapter采用的algorithm必须提供master_xfer以描述总线的行为。
 

3.2  struct i2c_adapter解析

struct i2c_adapter {

       char name[32];      /* 适配器的名字*/

       unsigned int id;/* == is algo->id | hwdep.struct->id,          */

                     /* for registered values see below         */

       struct i2c_algorithm *algo;/* adapter对应的算法*/

       void *algo_data;        /*使用标准算法时,提供算法需要的特殊函数入口*/

 

       /* --- These may be NULL, but should increase the module use count */

       void (*inc_use)(struct i2c_adapter *);

       void (*dec_use)(struct i2c_adapter *);

 

       /* --- administration stuff. */

       int (*client_register)(struct i2c_client *);

       int (*client_unregister)(struct i2c_client *);

 

       void *data;      /* private data for the adapter                     */

                     /* some data fields that are used by all types */

                     /* these data fields are readonly to the public       */

                     /* and can be set via the i2c_ioctl call   */

 

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

       struct semaphore lock; 

       unsigned int flags;/* flags specifying div. data             */

 

       struct i2c_client *clients[I2C_CLIENT_MAX]; //adapter对应的I2C bus上的client列表

       int client_count;

 

       int timeout;     //超时时间

       int retries;    //重试次数

 

#ifdef CONFIG_PROC_FS

       /* No need to set this when you initialize the adapter          */

       int inode;

#endif /* def CONFIG_PROC_FS */

}

如何给adapter选择合适的algorithm?内核已经提供了若干标准的algorithm,当我们使用标准algorithm时,必须提供algo_data入口。多数情况,adapter需要的algorithm都是自定义的,这是algo_data可以为空。
 

3.3  i2c_driver解析

struct i2c_driver {

       char name[32];  //驱动的名称

       int id;          //驱动的ID

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

 

       /* 寻找当前client对应的adapter是否存在。

若存在,调用i2c_attach_client更新adapterclient

        */

       int (*attach_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 *);

      

       /* 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);

      

       /* These two are mainly used for bookkeeping & dynamic unloading of

        * kernel modules. inc_use tells the driver that a client is being 

        * used by another module & that it should increase its ref. counter.

        * dec_use is the inverse operation.

        * NB: Make sure you have no circular dependencies, or else you get a

        * deadlock when trying to unload the modules.

       * You should use the i2c_{inc,dec}_use_client functions instead of

       * calling this function directly.

        */

       void (*inc_use)(struct i2c_client *client);

       void (*dec_use)(struct i2c_client *client);

};
 

3.4  i2c_client解析

/*

 * i2c_client identifies a single device (i.e. chip) that is connected to an

 * i2c bus. The behaviour is defined by the routines of the driver. This

 * function is mainly used for lookup & other admin. functions.

 */

struct i2c_client {

       char name[32];    //client 名字

       int id;            //client ID

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

       unsigned int addr;          /* client地址: 7bit        */

                                   /* addresses are stored in the */

                                   /* _LOWER_ 7 bits of this char    */

       /* addr: unsigned int to make lm_sensors i2c-isa adapter work

         more cleanly. It does not take any more memory space, due to

         alignment considerations */

       struct i2c_adapter *adapter;   /* client所在I2C bus对应的adapter   */

       struct i2c_driver *driver;     /* client 使用的驱动     */

       void *data;                    /* for the clients            */

       int usage_count;            /* How many accesses currently  */

                                   /* to the client        */

};

 
发表评论:
载入中...