Linux内核i2c子系统驱动介绍 (linux内核i2c子系统驱动)
I2C(Inter-Integrated Circuit)总线是一种串行数据传输协议,被用于连接芯片之间的通信。在Linux内核中,i2c子系统驱动负责管理I2C总线,允许多个设备通过同一条总线进行通信。本文将介绍Linux内核i2c子系统驱动的相关知识。
一、i2c子系统驱动的结构
在Linux内核中,i2c子系统驱动通常包含以下几个结构:
1. i2c_adapter结构体
i2c_adapter结构体描述了一条I2C总线的特性,包括总线地址、时钟频率、数据传送方式等。该结构体的定义在i2c.h头文件中,如下所示:
struct i2c_adapter {
struct module *owner;
const char *name;
u32 class;
u32 nr;
struct bus_type *bus;
u32 algo_data;
struct i2c_algorithm *algo;
void *algo_priv;
struct device dev;
unsigned long algo_data_dma;
unsigned long owndata;
unsigned int timeout;
unsigned int retries;
bool (*unrecoverable)(struct i2c_adapter *, struct i2c_msg *);
int (*setup)(struct i2c_adapter *);
void (*shutdown)(struct i2c_adapter *);
int (*bus_recovery)(struct i2c_adapter *);
void *adapdata;
struct i2c_lock_operations *lock_ops;
const struct of_device_id *of_match_table;
};
2. i2c_algorithm结构体
i2c_algorithm结构体定义了I2C总线中的通信算法,包括数据传输格式、地址范围等。该结构体的定义在i2c.h头文件中,如下所示:
struct i2c_algorithm {
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
int (*bus_xfer)(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_bus_data *data);
int (*master_recv)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
int (*master_send)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
u32 (*functionality)(struct i2c_adapter *);
struct module *owner;
const char *name;
};
3. i2c_driver结构体
i2c_driver结构体描述了一个i2c设备的特性,包括设备类型、ID等信息。该结构体的定义在i2c.h头文件中,如下所示:
struct i2c_driver {
unsigned int class;
const struct i2c_device_id *id_table;
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t state);
int (*resume)(struct i2c_client *);
const struct i2c_device_id *of_match_table;
const struct of_device_id *of_match_table;
struct device_driver driver;
};
4. i2c_client结构体
i2c_client结构体描述了一个具体的i2c设备,包括设备地址、设备类型、驱动等信息。该结构体的定义在i2c.h头文件中,如下所示:
struct i2c_client {
int irq;
unsigned short flags;
unsigned short addr;
char name[I2C_NAME_SIZE];
struct device dev;
struct i2c_adapter *adapter;
struct i2c_driver *driver;
void *algo_data;
struct i2c_board_info const *board_info;
};
二、i2c子系统驱动的通信过程
i2c子系统驱动的通信过程需要经过以下步骤:
1. 注册i2c_adapter
初次使用I2C总线时,需要先注册i2c_adapter结构体,告诉内核I2C总线的特性。在Linux内核中,注册i2c_adapter结构体可以使用i2c_add_adapter函数来完成。
2. 注册i2c_driver
为了能够与具体的i2c设备通信,需要先注册i2c_driver结构体。在Linux内核中,注册i2c_driver结构体可以使用i2c_add_driver函数来完成。
3. 连接i2c_client设备
一旦I2C总线被注册成功,可以使用i2c_new_device函数连接一个i2c_client设备。在连接设备时,需要指定设备地址、设备类型等信息。
4. 与设备通信
当i2c_client设备连接成功后,就可以使用该设备进行I2C通信了。在Linux内核中,I2C数据的传输通常使用i2c_transfer函数进行。该函数需要传入一个指向i2c_msg结构体的指针,该结构体用于描述数据的传输信息。
5. 注销i2c_driver和i2c_adapter
当使用完i2c_driver和i2c_adapter之后,需要使用i2c_del_driver和i2c_del_adapter函数来注销。
三、i2c子系统驱动的应用场景
i2c子系统驱动在Linux内核中的应用广泛,包括但不限于以下场景:
1. 屏幕显示
在Linux内核中,i2c子系统驱动可用于控制显示器的点阵屏幕,比如树莓派的OLED屏幕等。
2. 触摸屏
i2c子系统驱动还可用于连接触摸屏设备,实现触摸控制。
3. 传感器
i2c子系统驱动也可以用于连接各种传感器设备,如温度传感器、气压传感器等。这些设备通常需要I2C总线进行数据传输。
i2c子系统驱动在Linux内核中的应用范围广泛,是连接各种设备的重要手段。通过对i2c子系统驱动的深入了解,可以更好地开发和使用相关设备。