I2C设备驱动分析-基于imx6下总线驱动
1. 主要数据结构说明
1. struct i2c_adapter(include/linux/i2c.h)
struct i2c_adapter描述了MPU的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;
struct i2c_bus_recovery_info *bus_recovery_info;
const struct i2c_adapter_quirks *quirks;
};
2. struct i2c_algorithm(include/linux/i2c.h)
struct i2c_algorithm提供了一套通信方法,作为I2C适配器和设备之间的通讯方法。
struct i2c_algorithm {
/* 通讯函数 */
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);
/* 返回支持的功能 */
u32 (*functionality) (struct i2c_adapter *);
#if IS_ENABLED(CONFIG_I2C_SLAVE)
int (*reg_slave)(struct i2c_client *client);
int (*unreg_slave)(struct i2c_client *client);
#endif
}
3. struct imx_i2c_struct(i2c-imx.c)
总线驱动私有结构体。
struct imx_i2c_struct {
/* 适配器 */
struct i2c_adapter adapter;
/* 时钟 */
struct clk *clk;
/* IO地址 */
void __iomem *base;
/* 等待队列头 */
wait_queue_head_t queue;
unsigned long i2csr;
unsigned int disable_delay;
int stopped;
unsigned int ifdr; /* IMX_I2C_IFDR */
unsigned int cur_clk;
/* bit速率 */
unsigned int bitrate;
const struct imx_i2c_hwdata *hwdata;
struct imx_i2c_dma *dma;
};
4. struct imx_i2c_dma(i2c-imx.c)
描述了DMA属性。
struct imx_i2c_dma {
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
struct dma_chan *chan_using;
struct completion cmd_complete;
dma_addr_t dma_buf;
unsigned int dma_len;
enum dma_transfer_direction dma_transfer_dir;
enum dma_data_direction dma_data_dir;
};
5. struct i2c_msg(include/uapi/linux/i2c.h)
I2C消息结构体,描述了一条I2C消息,包括数据和长度。
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_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
#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 */
__u8 *buf; /* pointer to msg data */
};
2. 主要函数说明
1. 驱动加载和卸载函数
在驱动加载和卸载的时候执行。
static int __init i2c_adap_imx_init(void)
{
retur