初探linux子系统集之i2c子系统

Posted 东月之神

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初探linux子系统集之i2c子系统相关的知识,希望对你有一定的参考价值。

    大概也是前年了,一直没有把那个i2c的子系统讲解完,这里偷个懒,把以前整理的i2c相关的知识再梳理一下,做个了结,然后再去学习timer子系统。

    先看下i2c在内核中的代码分布:

obj-$(CONFIG_I2C_BOARDINFO)	+= i2c-boardinfo.o
obj-$(CONFIG_I2C)		+= i2c-core.o
obj-$(CONFIG_I2C_SMBUS)		+= i2c-smbus.o
obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
obj-$(CONFIG_I2C_MUX)		+= i2c-mux.o
obj-y				+= algos/ busses/ muxes/
    i2c的核心是i2c-core.c实现了i2c核心功能,i2c-dev.c实现了应用的交互接口。至于algos里面那主要实现的是总线适配,busses主要就是一些控制器相关的和gpio模拟的i2c,之后我们会详细介绍gpio模拟的i2c的代码。

    既然看了代码分布,那么还是先要了解下i2c的框架了:   

技术分享

    其中adaptor是i2c的总线驱动,dev和driver,client是i2c的设备驱动。一般如果要实现芯片的i2c驱动,那么就需要实现总线驱动,而设备驱动一般都是通用的。

    好了,既然已经知道了i2c的基本框架,那么就来看看他的数据结构了:

struct i2c_msg;  
struct i2c_algorithm;  
struct i2c_adapter;  
struct i2c_client;  
struct i2c_driver;  
union i2c_smbus_data;  
struct i2c_board_info;  
I2Cdriver

struct i2c_driver {  
       unsigned int class;//I2C设备类型      
       /* Notifies the driver that a new bus has appeared or is about to be   
        * removed. You should avoid using this, it will be removed in a  
        * near future.  
        */  
       int (*attach_adapter)(struct i2c_adapter *) __deprecated;  
       int (*detach_adapter)(struct i2c_adapter *) __deprecated;  
  
       /* Standard driver model interfaces */  
       int (*probe)(struct i2c_client *, const struct i2c_device_id *);  
       int (*remove)(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 *);     
  
       /* Alert callback, for example for the SMBus alert protocol.  
        * The format and meaning of the data value depends on the protocol.  
        * For the SMBus alert protocol, there is a single bit of data passed  
        * as the alert response's low bit ("event flag").  
        */  
  
       void (*alert)(struct i2c_client *, unsigned int data);     
      /* 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;  
       const struct i2c_device_id *id_table;   
  
       /* Device detection callback for automatic device creation */  
       int (*detect)(struct i2c_client *, struct i2c_board_info *);  
       const unsigned short *address_list; //要检测的I2C地址  
       struct list_head clients;   
};  


I2Cclient

识别单个设备连接到一个总线上。

struct i2c_client {   
       unsigned short flags;             /* div., see below          */  
       unsigned short addr;             /* chip address - NOTE: 7bit */  
                                   /* addresses are stored in the  */  
                                   /* _LOWER_ 7 bits              */  
       char name[I2C_NAME_SIZE];   //设备名  
       struct i2c_adapter *adapter;   /* the adapter we sit on  *///I2C主控制器  
       struct i2c_driver *driver;       /* and our access routines      *///I2C设备驱动   
       struct device dev;          /* the device structure           */从机的驱动类型设备节点  
       int irq;                  /* irq issued by device          */ //中断号  
       struct list_head detected;        
};  

I2Cboard_info

struct i2c_board_info {    
       char        type[I2C_NAME_SIZE]; //I2C设备名  
       unsigned short flags;      //i2c_client.flags的初始化  
       unsigned short addr;       //设备地址  
       void        *platform_data;  
       struct dev_archdata *archdata;  
       struct device_node *of_node;  
       int          irq;  //设备中断号  
};  


I2Calgorithm

所有的驱动时序都是在算法中实现的

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);   
  
       /* To determine what the adapter supports */    
       u32 (*functionality) (struct i2c_adapter *);   
};  


I2Cadapter

主控制器,用以鉴定i2c总线

struct i2c_adapter {   
       struct module *owner;  
       unsigned int class;           /* classes to allow probing for */  
       const struct i2c_algorithm *algo; /* the algorithm to access the bus */  
       void *algo_data;   
  
       /* data fields that are valid for all devices    */  
       struct rt_mutex bus_lock;  
   
       int timeout;                   /* in jiffies */  
       int retries;  
       struct device dev;          /* the adapter device */  
       int nr;  
       char name[48];   
       struct completion dev_released;   
       struct mutex userspace_clients_lock;  
       struct list_head userspace_clients;  
};.  


I2Cmsg

在调用i2c_transfer的时候发送或者接收数据

struct i2c_msg {  
       __u16 addr;    /* slave address*/  
       __u16 flags;   //读写等的标志  
#define I2C_M_TEN            0x0010    /* this is a ten bit chip address */  
#define I2C_M_RD              0x0001    /* read data, from slave to master */  
#define I2C_M_NOSTART           0x4000    /* if I2C_FUNC_PROTOCOL_MANGLING */  
#define I2C_M_REV_DIR_ADDR       0x2000    /* if I2C_FUNC_PROTOCOL_MANGLING */  
#define I2C_M_IGNORE_NAK   0x1000    /* if I2C_FUNC_PROTOCOL_MANGLING */  
#define I2C_M_NO_RD_ACK            0x0800    /* if I2C_FUNC_PROTOCOL_MANGLING */  
#define I2C_M_RECV_LEN        0x0400    /* length will be first received byte */  
       __u16 len;             /* msg length  *//发送和接收的buf的长度/  
       __u8 *buf;             /* pointer to msg data*///发送或者接收的buf  
};  

I2Cgpio模拟用的platform_data

struct i2c_gpio_platform_data {  
       unsigned int    sda_pin;  
       unsigned int    scl_pin;  
       int          udelay;  
       int          timeout;  
       unsigned int    sda_is_open_drain:1;  
       unsigned int    scl_is_open_drain:1;  
       unsigned int    scl_is_output_only:1;  
};  
    主要数据结构就是这些,接下去的话在下一篇文章中简单介绍下gpio模拟的i2c的流程。


 



















以上是关于初探linux子系统集之i2c子系统的主要内容,如果未能解决你的问题,请参考以下文章

linux驱动之i2c子系统mpu6050设备驱动

linux驱动之I2C子系统

Smart210学习记录-----Linux i2c驱动

Linux i2c子系统驱动probe

linux之i2c子系统架构

linux内核I2C子系统详解——看这一篇就够了