I2C 和 SMBus 子系统¶
I2C (或者没有花哨的排版,"I2C") 是 "Inter-IC" 总线的缩写,这是一种简单的总线协议,广泛用于低数据速率通信足以的场合。由于它也是一个许可商标,一些供应商对同一总线使用另一个名称(例如 “Two-Wire Interface”, TWI)。I2C 只需要两个信号(SCL 用于时钟,SDA 用于数据),节省了电路板空间并最大限度地减少了信号质量问题。大多数 I2C 设备使用 7 位地址,总线速度高达 400 kHz;有一个高速扩展 (3.4 MHz) 尚未得到广泛使用。I2C 是一种多主总线;使用开漏信号在主设备之间进行仲裁,以及进行握手和同步来自较慢客户端的时钟。
Linux I2C 编程接口支持总线交互的主设备端和从设备端。编程接口围绕两种驱动程序和两种设备构建。I2C “适配器驱动程序” 抽象化了控制器硬件;它绑定到物理设备(可能是 PCI 设备或 platform_device),并公开一个 struct i2c_adapter
,表示它管理的每个 I2C 总线段。每个 I2C 总线段上将有由 struct i2c_client
表示的 I2C 设备。这些设备将绑定到 struct i2c_driver
,该驱动程序应遵循标准的 Linux 驱动程序模型。有一些函数可以执行各种 I2C 协议操作;在撰写本文时,所有这些函数只能从任务上下文中调用。
系统管理总线 (SMBus) 是一种同级协议。大多数 SMBus 系统也符合 I2C 标准。SMBus 的电气约束更严格,它标准化了特定的协议消息和惯例。支持 I2C 的控制器也可以支持大多数 SMBus 操作,但 SMBus 控制器不支持 I2C 控制器支持的所有协议选项。有一些函数可以执行各种 SMBus 协议操作,可以使用 I2C 原语或向不支持这些 I2C 操作的 i2c_adapter 设备发出 SMBus 命令。
-
int i2c_master_recv(const struct i2c_client *client, char *buf, int count)¶
在主接收模式下发出单个 I2C 消息
参数
const struct i2c_client *client
从设备句柄
char *buf
存储从设备读取的数据的位置
int count
要读取的字节数,必须小于 64k,因为 msg.len 是 u16
描述
返回负 errno,否则返回读取的字节数。
-
int i2c_master_recv_dmasafe(const struct i2c_client *client, char *buf, int count)¶
使用 DMA 安全缓冲区在主接收模式下发出单个 I2C 消息
参数
const struct i2c_client *client
从设备句柄
char *buf
存储从设备读取的数据的位置,必须安全地用于 DMA
int count
要读取的字节数,必须小于 64k,因为 msg.len 是 u16
描述
返回负 errno,否则返回读取的字节数。
-
int i2c_master_send(const struct i2c_client *client, const char *buf, int count)¶
在主发送模式下发出单个 I2C 消息
参数
const struct i2c_client *client
从设备句柄
const char *buf
将写入从设备的数据
int count
要写入的字节数,必须小于 64k,因为 msg.len 是 u16
描述
返回负 errno,否则返回写入的字节数。
-
int i2c_master_send_dmasafe(const struct i2c_client *client, const char *buf, int count)¶
使用 DMA 安全缓冲区在主发送模式下发出单个 I2C 消息
参数
const struct i2c_client *client
从设备句柄
const char *buf
将写入从设备的数据,必须安全地用于 DMA
int count
要写入的字节数,必须小于 64k,因为 msg.len 是 u16
描述
返回负 errno,否则返回写入的字节数。
-
struct i2c_device_identity¶
i2c 客户端设备标识
定义:
struct i2c_device_identity {
u16 manufacturer_id;
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS 0;
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_1 1;
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_2 2;
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_3 3;
#define I2C_DEVICE_ID_RAMTRON_INTERNATIONAL 4;
#define I2C_DEVICE_ID_ANALOG_DEVICES 5;
#define I2C_DEVICE_ID_STMICROELECTRONICS 6;
#define I2C_DEVICE_ID_ON_SEMICONDUCTOR 7;
#define I2C_DEVICE_ID_SPRINTEK_CORPORATION 8;
#define I2C_DEVICE_ID_ESPROS_PHOTONICS_AG 9;
#define I2C_DEVICE_ID_FUJITSU_SEMICONDUCTOR 10;
#define I2C_DEVICE_ID_FLIR 11;
#define I2C_DEVICE_ID_O2MICRO 12;
#define I2C_DEVICE_ID_ATMEL 13;
#define I2C_DEVICE_ID_NONE 0xffff;
u16 part_id;
u8 die_revision;
};
成员
manufacturer_id
0 - 4095,由 NXP 维护的数据库
part_id
0 - 511,根据制造商
die_revision
0 - 7,根据制造商
-
enum i2c_driver_flags¶
I2C 设备驱动程序的标志
常量
I2C_DRV_ACPI_WAIVE_D0_PROBE
不要在探测时将设备置于 D0 状态
-
struct i2c_driver¶
表示 I2C 设备驱动程序
定义:
struct i2c_driver {
unsigned int class;
int (*probe)(struct i2c_client *client);
void (*remove)(struct i2c_client *client);
void (*shutdown)(struct i2c_client *client);
void (*alert)(struct i2c_client *client, enum i2c_alert_protocol protocol, unsigned int data);
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
struct device_driver driver;
const struct i2c_device_id *id_table;
int (*detect)(struct i2c_client *client, struct i2c_board_info *info);
const unsigned short *address_list;
struct list_head clients;
u32 flags;
};
成员
class
我们实例化什么类型的 i2c 设备(用于检测)
probe
设备绑定的回调
remove
设备解除绑定的回调
shutdown
设备关机的回调
alert
警报回调,例如用于 SMBus 警报协议
command
总线范围信号的回调(可选)
driver
设备驱动程序模型驱动程序
id_table
此驱动程序支持的 I2C 设备列表
detect
设备检测的回调
address_list
要探测的 I2C 地址(用于检测)
clients
我们创建的检测到的客户端列表(仅供 i2c-core 使用)
flags
enum i2c_driver_flags
中定义的标志的位掩码
描述
driver.owner 字段应设置为此驱动程序的模块所有者。driver.name 字段应设置为此驱动程序的名称。
为了实现自动设备检测,必须定义 detect 和 address_list。还应该设置 class,否则只会创建使用模块参数强制指定的设备。detect 函数必须在成功检测到设备时至少填充它所接收的 i2c_board_info 结构的 name 字段,并且可能还需要填充 flags 字段。
如果缺少 detect,驱动程序对于枚举设备仍然可以正常工作。只是不支持检测到的设备。对于许多无法可靠检测的 I2C/SMBus 设备以及实际上总是可以枚举的设备来说,这是预期的。
传递给 detect 回调的 i2c_client 结构不是真正的 i2c_client。它的初始化仅足够让你在其上调用 i2c_smbus_read_byte_data 及相关函数。不要对其进行其他任何操作。特别是,不允许在其上调用 dev_dbg 及相关函数。
-
struct i2c_client¶
表示一个 I2C 从设备
定义:
struct i2c_client {
unsigned short flags;
#define I2C_CLIENT_PEC 0x04 ;
#define I2C_CLIENT_TEN 0x10 ;
#define I2C_CLIENT_SLAVE 0x20 ;
#define I2C_CLIENT_HOST_NOTIFY 0x40 ;
#define I2C_CLIENT_WAKE 0x80 ;
#define I2C_CLIENT_SCCB 0x9000 ;
unsigned short addr;
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter;
struct device dev;
int init_irq;
int irq;
struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE);
i2c_slave_cb_t slave_cb;
#endif;
void *devres_group_id;
};
成员
flags
可能的标志请参考 I2C_CLIENT_*
addr
连接到父适配器的 I2C 总线上使用的地址。
name
指示设备的类型,通常是芯片名称,该名称足够通用,可以隐藏第二来源和兼容版本。
adapter
管理承载此 I2C 设备的总线段
dev
从设备的驱动程序模型设备节点。
init_irq
初始化时设置的 IRQ
irq
指示此设备生成的 IRQ(如果有)
detected
i2c_driver.clients 列表或 i2c-core 的 userspace_devices 列表的成员
slave_cb
当使用适配器的 I2C 从模式时,此回调函数被调用。适配器会调用它,将从事件传递给从驱动程序。
devres_group_id
为探测此设备时获取的资源创建的 devres 组的 ID。
描述
i2c_client 标识连接到 i2c 总线的单个设备(即芯片)。暴露给 Linux 的行为由管理该设备的驱动程序定义。
-
struct i2c_board_info¶
设备创建的模板
定义:
struct i2c_board_info {
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
const char *dev_name;
void *platform_data;
struct device_node *of_node;
struct fwnode_handle *fwnode;
const struct software_node *swnode;
const struct resource *resources;
unsigned int num_resources;
int irq;
};
成员
type
芯片类型,用于初始化 i2c_client.name
flags
用于初始化 i2c_client.flags
addr
存储在 i2c_client.addr 中
dev_name
如果设置,则覆盖默认的 <busnr>-<addr> dev_name
platform_data
存储在 i2c_client.dev.platform_data 中
of_node
指向 OpenFirmware 设备节点的指针
fwnode
平台固件提供的设备节点
swnode
设备的软件节点
resources
与设备关联的资源
num_resources
resources 数组中的资源数量
irq
存储在 i2c_client.irq 中
描述
I2C 实际上不支持硬件探测,尽管控制器和设备可能能够使用 I2C_SMBUS_QUICK 来判断给定地址上是否存在设备。驱动程序通常需要更多信息,例如芯片类型、配置、关联的 IRQ 等。
i2c_board_info 用于构建列出存在的 I2C 设备的信息表。此信息用于扩展驱动程序模型树。对于主板,这是使用 i2c_register_board_info()
静态完成的;总线号标识尚未可用的适配器。对于附加板,i2c_new_client_device()
会在适配器已知的情况下动态执行此操作。
-
I2C_BOARD_INFO¶
I2C_BOARD_INFO (dev_type, dev_addr)
用于列出 i2c 设备及其地址的宏
参数
dev_type
标识设备类型
dev_addr
设备在总线上的地址。
描述
此宏初始化 struct i2c_board_info
的基本字段,声明在特定板上提供了什么。可选字段(例如关联的 irq 或设备特定的 platform_data)使用常规语法提供。
-
struct i2c_algorithm¶
表示 I2C 传输方法
定义:
struct i2c_algorithm {
union {
int (*xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
};
union {
int (*xfer_atomic)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
int (*master_xfer_atomic)(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);
int (*smbus_xfer_atomic)(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 *adap);
#if IS_ENABLED(CONFIG_I2C_SLAVE);
union {
int (*reg_target)(struct i2c_client *client);
int (*reg_slave)(struct i2c_client *client);
};
union {
int (*unreg_target)(struct i2c_client *client);
int (*unreg_slave)(struct i2c_client *client);
};
#endif;
};
成员
{unnamed_union}
匿名
xfer
通过指定的适配器传输由 msgs 数组定义的给定数量的消息。
master_xfer
已弃用,请使用 xfer
{unnamed_union}
匿名
xfer_atomic
与 xfer 相同。但是,仅使用原子上下文,以便可以在关机前很晚的时候访问 PMIC 等。可选。
master_xfer_atomic
已弃用,请使用 xfer_atomic
smbus_xfer
向给定的 I2C 适配器发出 SMBus 事务。如果不存在此项,则总线层将尝试将 SMBus 调用转换为 I2C 传输。
smbus_xfer_atomic
与 smbus_xfer 相同。但是,仅使用原子上下文,以便可以在关机前很晚的时候访问 PMIC 等。可选。
functionality
从
I2C_FUNC_*
标志返回此算法/适配器对支持的标志。{unnamed_union}
匿名
reg_target
将给定的客户端注册到此适配器的本地目标模式
reg_slave
已弃用,请使用 reg_target
{unnamed_union}
匿名
unreg_target
从此适配器的本地目标模式注销给定的客户端
unreg_slave
已弃用,请使用 unreg_target
描述
i2c_algorithm 是一个接口,用于连接可以使用相同总线算法寻址的硬件解决方案类 - 即位操作或 PCF8584,这两个是最常见的。
来自 xfer{_atomic}
字段的返回代码应指示传输期间发生的错误代码类型,如内核文档文件 I2C/SMBUS 故障代码 中所述。否则,应返回已执行的消息数量。
-
struct i2c_lock_operations¶
表示 I2C 锁定操作
定义:
struct i2c_lock_operations {
void (*lock_bus)(struct i2c_adapter *adapter, unsigned int flags);
int (*trylock_bus)(struct i2c_adapter *adapter, unsigned int flags);
void (*unlock_bus)(struct i2c_adapter *adapter, unsigned int flags);
};
成员
lock_bus
获取对 I2C 总线段的独占访问权
trylock_bus
尝试获取对 I2C 总线段的独占访问权
unlock_bus
释放对 I2C 总线段的独占访问权
描述
主要操作由 i2c_lock_bus 和 i2c_unlock_bus 包裹。
-
struct i2c_timings¶
I2C 时序信息
定义:
struct i2c_timings {
u32 bus_freq_hz;
u32 scl_rise_ns;
u32 scl_fall_ns;
u32 scl_int_delay_ns;
u32 sda_fall_ns;
u32 sda_hold_ns;
u32 digital_filter_width_ns;
u32 analog_filter_cutoff_freq_hz;
};
成员
bus_freq_hz
总线频率,单位为 Hz
scl_rise_ns
SCL 信号上升所需的时间,单位为纳秒;在 I2C 规范中为 t(r)
scl_fall_ns
SCL 信号下降所需的时间,单位为纳秒;在 I2C 规范中为 t(f)
scl_int_delay_ns
IP 核额外需要设置 SCL 的时间,单位为纳秒
sda_fall_ns
SDA 信号下降所需的时间,单位为纳秒;在 I2C 规范中为 t(f)
sda_hold_ns
IP 核额外需要保持 SDA 的时间,单位为纳秒
digital_filter_width_ns
IP 核数字滤波器可以滤除的 i2c 线上的尖峰宽度,单位为纳秒
analog_filter_cutoff_freq_hz
低通 IP 核模拟滤波器的阈值频率
-
struct i2c_bus_recovery_info¶
I2C 总线恢复信息
定义:
struct i2c_bus_recovery_info {
int (*recover_bus)(struct i2c_adapter *adap);
int (*get_scl)(struct i2c_adapter *adap);
void (*set_scl)(struct i2c_adapter *adap, int val);
int (*get_sda)(struct i2c_adapter *adap);
void (*set_sda)(struct i2c_adapter *adap, int val);
int (*get_bus_free)(struct i2c_adapter *adap);
void (*prepare_recovery)(struct i2c_adapter *adap);
void (*unprepare_recovery)(struct i2c_adapter *adap);
struct gpio_desc *scl_gpiod;
struct gpio_desc *sda_gpiod;
struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_gpio;
};
成员
recover_bus
恢复例程。传递驱动程序的 recover_bus() 例程或 i2c_generic_scl_recovery()。
get_scl
获取 SCL 线的当前值。对于通用 SCL 恢复是必需的。对于通用 GPIO 恢复,内部会填充此项。
set_scl
设置/清除 SCL 线。对于通用 SCL 恢复是必需的。对于通用 GPIO 恢复,内部会填充此项。
get_sda
获取 SDA 线的当前值。对于通用 SCL 恢复,此项或 set_sda() 是必需的。如果 sda_gpio 是有效的 GPIO,则对于通用 GPIO 恢复,内部会填充此项。
set_sda
设置/清除 SDA 线。对于通用 SCL 恢复,此项或 get_sda() 是必需的。如果 sda_gpio 是有效的 GPIO,则对于通用 GPIO 恢复,内部会填充此项。
get_bus_free
如果 IP 核具有比仅读取 SDA 更复杂的内部逻辑,则返回从 IP 核看到的总线空闲状态。可选。
prepare_recovery
在开始恢复之前将调用此项。平台可以在此处为 SDA/SCL 线配置 padmux 或其他任何他们想要的操作。
unprepare_recovery
完成恢复后将调用此项。平台可以在此处为 SDA/SCL 线配置 padmux 或其他任何他们想要的操作。
scl_gpiod
SCL 线的 gpiod。仅 GPIO 恢复需要此项。
sda_gpiod
SDA 线的 gpiod。仅 GPIO 恢复需要此项。
pinctrl
GPIO 恢复用来更改 I2C 引脚状态的 pinctrl。可选。
pins_default
SCL/SDA 线的默认 pinctrl 状态,当它们被分配给 I2C 总线时。可选。如果找到名称为 PINCTRL_STATE_DEFAULT 的状态并且 pinctrl 有效,则为 GPIO 恢复内部填充此项。
pins_gpio
SCL/SDA 线的恢复 pinctrl 状态,当它们用作 GPIO 时。可选。如果此状态被称为 “gpio” 或 “recovery” 并且 pinctrl 有效,则为 GPIO 恢复内部填充此项。
-
struct i2c_adapter_quirks¶
描述 i2c 适配器的缺陷
定义:
struct i2c_adapter_quirks {
u64 flags;
int max_num_msgs;
u16 max_write_len;
u16 max_read_len;
u16 max_comb_1st_msg_len;
u16 max_comb_2nd_msg_len;
};
成员
flags
可能的标志请参考 I2C_AQ_* 并阅读下文
max_num_msgs
每次传输的最大消息数
max_write_len
写消息的最大长度
max_read_len
读消息的最大长度
max_comb_1st_msg_len
组合消息中第一个消息的最大长度
max_comb_2nd_msg_len
组合消息中第二个消息的最大长度
描述
关于组合消息的注意事项:一些I2C控制器每次传输只能发送一条消息,外加一种称为组合消息或先写后读的消息。这通常是一个小的写消息,后跟一个读消息,刚好足够访问诸如EEPROM之类的基于寄存器的设备。有一个标志来支持此模式。它表示 max_num_msg = 2,并使用 max_comb_*_len 进行长度检查,因为组合消息模式通常有其自身的限制。由于硬件实现的原因,某些控制器实际上可以执行先写后任何操作或其他变体。为了支持这一点,先写后读已被分解为更小的部分,例如先写和后读,可以根据需要组合使用。
-
void i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags)¶
获取对 I2C 总线段的独占访问权
参数
struct i2c_adapter *adapter
目标 I2C 总线段
unsigned int flags
I2C_LOCK_ROOT_ADAPTER 锁定根 i2c 适配器,I2C_LOCK_SEGMENT 仅锁定适配器树中的此分支
-
int i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags)¶
尝试获取对 I2C 总线段的独占访问权
参数
struct i2c_adapter *adapter
目标 I2C 总线段
unsigned int flags
I2C_LOCK_ROOT_ADAPTER 尝试锁定根 i2c 适配器,I2C_LOCK_SEGMENT 尝试仅锁定适配器树中的此分支
返回
如果 I2C 总线段被锁定,则返回 true,否则返回 false
-
void i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)¶
释放对 I2C 总线段的独占访问权
参数
struct i2c_adapter *adapter
目标 I2C 总线段
unsigned int flags
I2C_LOCK_ROOT_ADAPTER 解锁根 i2c 适配器,I2C_LOCK_SEGMENT 仅解锁适配器树中的此分支
-
void i2c_mark_adapter_suspended(struct i2c_adapter *adap)¶
向核心报告适配器的挂起状态
参数
struct i2c_adapter *adap
要标记为挂起的适配器
描述
当使用此助手将适配器标记为挂起时,核心将拒绝进一步传输到此适配器。此助手的使用是可选的,但建议用于具有用于系统挂起和运行时挂起的不同处理程序的设备。更复杂的设备可以自由实施自定义解决方案,以在挂起时拒绝传输。
-
void i2c_mark_adapter_resumed(struct i2c_adapter *adap)¶
向核心报告适配器的恢复状态
参数
struct i2c_adapter *adap
要标记为恢复的适配器
描述
当使用此助手将适配器标记为恢复时,核心将允许进一步传输到此适配器。另请参阅有关 i2c_mark_adapter_suspended()
的更多说明。
-
bool i2c_check_quirks(struct i2c_adapter *adap, u64 quirks)¶
用于检查 i2c 适配器中的怪癖标志的函数
参数
struct i2c_adapter *adap
i2c 适配器
u64 quirks
怪癖标志
返回
如果适配器具有所有指定的怪癖标志,则返回 true,否则返回 false
-
module_i2c_driver¶
module_i2c_driver (__i2c_driver)
用于注册模块化 I2C 驱动程序的助手宏
参数
__i2c_driver
i2c_driver 结构体
描述
用于在模块初始化/退出时不执行任何特殊操作的 I2C 驱动程序的助手宏。这消除了大量样板代码。每个模块只能使用此宏一次,并且调用它会替换 module_init()
和 module_exit()
-
builtin_i2c_driver¶
builtin_i2c_driver (__i2c_driver)
用于注册内置 I2C 驱动程序的助手宏
参数
__i2c_driver
i2c_driver 结构体
描述
用于在其初始化时不执行任何特殊操作的 I2C 驱动程序的助手宏。这消除了大量样板代码。每个驱动程序只能使用此宏一次,并且调用它会替换 device_initcall()。
-
int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)¶
静态声明 I2C 设备
参数
int busnum
标识这些设备所属的总线
struct i2c_board_info const *info
i2c 设备描述符的向量
unsigned len
向量中有多少个描述符;可以为零以保留指定的总线号。
描述
使用 Linux I2C 驱动程序堆栈的系统可以在初始化时声明板信息表。这应该在板特定的初始化代码中,在 arch_initcall() 时间附近或等效的时间进行,在注册任何 I2C 适配器驱动程序之前。例如,主板初始化代码可以定义多个设备,就像板堆栈中每个子卡的初始化代码一样。
I2C 设备将在以后创建,在相关总线的适配器注册之后。在那之后,使用标准的驱动程序模型工具将“新样式”I2C 驱动程序绑定到设备。使用此例程声明的任何设备的总线号都不可用于动态分配。
传递的板信息可以安全地是 __initdata,但要注意嵌入式指针(对于 platform_data、函数等),因为它不会被复制。
-
struct i2c_client *i2c_verify_client(struct device *dev)¶
将参数作为 i2c_client 返回,或 NULL
参数
struct device *dev
设备,可能来自某些驱动程序模型迭代器
描述
当遍历驱动程序模型树时,可能使用诸如 device_for_each_child()
之类的驱动程序模型迭代器,你不能对找到的节点做太多假设。使用此函数可避免由于将某些非 I2C 设备错误地视为 i2c_client 而导致的错误。
-
struct i2c_client *i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info)¶
实例化 i2c 设备
参数
struct i2c_adapter *adap
管理设备的适配器
struct i2c_board_info const *info
描述一个 I2C 设备;bus_num 被忽略
上下文
可以休眠
描述
创建一个 i2c 设备。绑定通过驱动程序模型 probe()/remove() 方法处理。驱动程序可能会在从该函数返回时或稍后(例如,热插拔可能会加载驱动程序模块)绑定到此设备。此调用不适合由主板初始化逻辑使用,主板初始化逻辑通常在任何 i2c_adapter 可能存在之前的 arch_initcall() 期间运行。
这会返回新的 i2c 客户端,该客户端可以保存以供稍后与 i2c_unregister_device()
一起使用;或者返回一个 ERR_PTR 来描述错误。
-
void i2c_unregister_device(struct i2c_client *client)¶
i2c_new_*_device() 的反向效果
参数
struct i2c_client *client
从 i2c_new_*_device() 返回的值
上下文
可以休眠
-
struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode)¶
为 fwnode 查找 i2c_client
参数
struct fwnode_handle *fwnode
对应于
struct i2c_client
的struct fwnode_handle
描述
查找并返回与 fwnode 对应的 struct i2c_client
。如果找不到客户端,或者 fwnode 为 NULL,则返回 NULL。
用户在使用完 i2c 客户端后必须调用 put_device(client->dev
)。
-
struct i2c_client *i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address)¶
返回一个绑定到虚拟驱动程序的新 i2c 设备
参数
struct i2c_adapter *adapter
管理设备的适配器
u16 address
要使用的七位地址
上下文
可以休眠
描述
这将返回一个绑定到 “dummy” 驱动程序的 I2C 客户端,旨在用于消耗多个地址的设备。此类芯片的示例包括各种 EEPROM(如 24c04 和 24c08 型号)。
这些虚拟设备有两个主要用途。首先,除了 i2c_transfer()
之外的大多数 I2C 和 SMBus 调用都需要客户端句柄;虚拟设备将是该句柄。其次,这可以防止指定的地址绑定到不同的驱动程序。
这将返回新的 i2c 客户端,该客户端应保存以便稍后与 i2c_unregister_device()
一起使用;或者返回一个 ERR_PTR 来描述错误。
-
struct i2c_client *devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adapter, u16 address)¶
返回一个绑定到虚拟驱动程序的新 i2c 设备
参数
struct device *dev
托管资源绑定到的设备
struct i2c_adapter *adapter
管理设备的适配器
u16 address
要使用的七位地址
上下文
可以休眠
描述
这是 i2c_new_dummy_device 的设备管理版本。它返回新的 i2c 客户端,如果发生错误,则返回 ERR_PTR。
-
struct i2c_client *i2c_new_ancillary_device(struct i2c_client *client, const char *name, u16 default_addr)¶
获取实例化的辅助地址并创建关联设备的帮助程序
参数
struct i2c_client *client
主客户端的句柄
const char *name
指定要获取哪个辅助地址的句柄
u16 default_addr
如果未指定辅助地址,则用作回退
上下文
可以休眠
描述
I2C 客户端可以由绑定在单个组件中的多个 I2C 从设备组成。然后,I2C 客户端驱动程序绑定到主 I2C 从设备,并且需要创建 I2C 虚拟客户端以与所有其他从设备通信。
此函数创建并返回一个 I2C 虚拟客户端,该客户端的 I2C 地址是从基于给定从设备名称的平台固件检索的。如果固件未指定地址,则使用 default_addr。
在基于 DT 的平台上,地址是从 “reg” 属性条目单元格检索的,该单元格的 “reg-names” 值与从设备名称匹配。
这将返回新的 i2c 客户端,该客户端应保存以便稍后与 i2c_unregister_device()
一起使用;或者返回一个 ERR_PTR 来描述错误。
参数
struct device *dev
设备,可能来自某些驱动程序模型迭代器
描述
当遍历驱动程序模型树时,可能使用诸如 device_for_each_child()
之类的驱动程序模型迭代器时,您不能对找到的节点进行太多假设。使用此函数可避免因将某些非 I2C 设备错误地视为 i2c_adapter 而导致的错误。
-
int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr)¶
将主机通知事件转发到正确的 I2C 客户端。
参数
struct i2c_adapter *adap
适配器
unsigned short addr
通知设备的 I2C 地址
上下文
不能休眠
描述
要从 I2C 总线驱动程序的 中断处理程序调用的辅助函数。它将调度主机通知 IRQ。
-
int i2c_add_adapter(struct i2c_adapter *adapter)¶
声明 i2c 适配器,使用动态总线号
参数
struct i2c_adapter *adapter
要添加的适配器
上下文
可以休眠
描述
此例程用于在总线号无关紧要时或当其总线号由 dt 别名指定时声明 I2C 适配器。总线号无关紧要的基本示例:通过 USB 链路或 PCI 插件卡动态添加的 I2C 适配器。
当此值返回零时,分配了一个新的总线号并存储在 adap->nr 中,并且指定的适配器可用于客户端。否则,将返回负 errno 值。
-
int i2c_add_numbered_adapter(struct i2c_adapter *adap)¶
声明 i2c 适配器,使用静态总线号
参数
struct i2c_adapter *adap
要注册的适配器(已初始化 adap->nr)
上下文
可以休眠
描述
当其总线号很重要时,此例程用于声明 I2C 适配器。例如,将其用于片上系统 CPU 的 I2C 适配器,或以其他方式构建到系统主板中的 I2C 适配器,以及在其中使用 i2c_board_info 正确配置 I2C 设备。
如果请求的总线号设置为 -1,则此函数将与 i2c_add_adapter 的行为相同,并将动态分配一个总线号。
如果尚未为此总线预先声明任何设备,请确保在任何动态分配的设备之前注册适配器。否则,可能无法使用所需的总线 ID。
当此值返回零时,指定的适配器可以使用 adap->nr 中提供的总线号供客户端使用。此外,扫描使用 i2c_register_board_info()
预先声明的 I2C 设备表,并创建相应的驱动程序模型设备节点。否则,将返回负 errno 值。
-
void i2c_del_adapter(struct i2c_adapter *adap)¶
取消注册 I2C 适配器
参数
struct i2c_adapter *adap
要取消注册的适配器
上下文
可以休眠
描述
这将取消注册先前由 i2c_add_adapter 或 i2c_add_numbered_adapter 注册的 I2C 适配器。
-
int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter)¶
i2c_add_adapter()
的设备管理变体。
参数
struct device *dev
管理设备以添加此 I2C 适配器。
struct i2c_adapter *adapter
要添加的适配器
上下文
可以休眠
描述
添加具有动态总线号的适配器,与 i2c_add_adapter()
相同,但该适配器将在驱动程序分离时自动删除。
-
struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode)¶
查找 fwnode 的 i2c_adapter。
参数
struct fwnode_handle *fwnode
对应于
struct i2c_adapter
的struct fwnode_handle
。
描述
查找并返回与 fwnode 对应的 struct i2c_adapter
。如果找不到适配器,或 fwnode 为 NULL,则返回 NULL。
用户必须在使用完 I2C 适配器后调用 put_device(adapter->dev
)。
-
struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode)¶
查找 fwnode 的 i2c_adapter。
参数
struct fwnode_handle *fwnode
对应于
struct i2c_adapter
的struct fwnode_handle
。
描述
查找并返回与 fwnode 对应的 struct i2c_adapter
,并增加适配器模块的使用计数。如果找不到适配器,或 fwnode 为 NULL,则返回 NULL。
用户必须在使用完 I2C 适配器后调用 i2c_put_adapter(adapter)。请注意,这与 i2c_find_adapter_by_node() 不同。
-
void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults)¶
从固件获取 I2C 相关时序参数。
参数
struct device *dev
要扫描 I2C 时序属性的设备。
struct i2c_timings *t
要填充值的 i2c_timings 结构。
bool use_defaults
一个布尔值,用于在找不到属性时使用从 I2C 规范导出的合理默认值,否则不更新。
描述
扫描设备以获取描述信号时序参数的通用 I2C 属性,并使用结果填充给定的结构。如果找不到属性且 use_defaults 为 true,则会假设最大时序,这些时序是从 I2C 规范导出的。如果未使用 use_defaults,则结果将与以前相同,因此驱动程序可以在调用此助手之前应用自己的默认值。后者主要用于避免想要切换到此函数的现有驱动程序的回归。新驱动程序几乎总是应该使用默认值。
-
void i2c_del_driver(struct i2c_driver *driver)¶
注销 I2C 驱动程序。
参数
struct i2c_driver *driver
正在注销的驱动程序。
上下文
可以休眠
-
int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)¶
i2c_transfer 的非锁定版本。
参数
struct i2c_adapter *adap
I2C 总线的句柄。
struct i2c_msg *msgs
在发出 STOP 以终止操作之前要执行的一个或多个消息;每个消息都以 START 开始。
int num
要执行的消息数。
描述
返回负的 errno,否则返回已执行的消息数。
调用此函数时必须持有适配器锁。不会进行调试日志记录。
-
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)¶
执行单个或组合的 I2C 消息。
参数
struct i2c_adapter *adap
I2C 总线的句柄。
struct i2c_msg *msgs
在发出 STOP 以终止操作之前要执行的一个或多个消息;每个消息都以 START 开始。
int num
要执行的消息数。
描述
返回负的 errno,否则返回已执行的消息数。
请注意,没有要求每个消息都发送到相同的从设备地址,尽管这是最常见的模型。
-
int i2c_transfer_buffer_flags(const struct i2c_client *client, char *buf, int count, u16 flags)¶
发出一个 I2C 消息,用于在缓冲区之间传输数据。
参数
const struct i2c_client *client
从设备句柄
char *buf
数据存储的位置。
int count
要传输的字节数,必须小于 64k,因为 msg.len 为 u16。
u16 flags
要用于消息的标志,例如,对于读取操作为 I2C_M_RD。
描述
返回负的 errno,否则返回传输的字节数。
-
int i2c_get_device_id(const struct i2c_client *client, struct i2c_device_identity *id)¶
获取设备的制造商、部件 ID 和芯片修订版。
参数
const struct i2c_client *client
要查询的设备。
struct i2c_device_identity *id
查询的信息。
描述
错误时返回负的 errno,成功时返回零。
-
const struct i2c_device_id *i2c_client_get_device_id(const struct i2c_client *client)¶
获取设备的驱动程序匹配表条目。
参数
const struct i2c_client *client
要查询的设备。该设备必须绑定到驱动程序。
描述
如果找到匹配的条目,则返回指向该条目的指针,否则返回 NULL。
-
u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold)¶
为给定的 i2c_msg 获取一个 DMA 安全的缓冲区
参数
struct i2c_msg *msg
要检查的消息
unsigned int threshold
使用 DMA 有意义的最小字节数。应至少为 1。
返回
- 如果未获得 DMA 安全缓冲区,则为 NULL。使用带有 PIO 的 msg->buf。
或要与 DMA 一起使用的有效指针。使用后,通过调用
i2c_put_dma_safe_msg_buf()
释放它。
描述
此函数必须仅从进程上下文中调用!
-
void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred)¶
释放 DMA 安全缓冲区并与 i2c_msg 同步
参数
u8 *buf
从
i2c_get_dma_safe_msg_buf()
获取的缓冲区。可能为 NULL。struct i2c_msg *msg
缓冲区对应的消息
bool xferred
表示消息是否已传输的布尔值
-
u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)¶
给定输入数据数组上的增量 CRC8
参数
u8 crc
先前的返回 crc8 值
u8 *p
指向数据缓冲区的指针。
size_t count
数据缓冲区中的字节数。
描述
在 p 指向的数组中,对 count 个字节进行增量 CRC8 计算
-
s32 i2c_smbus_read_byte(const struct i2c_client *client)¶
SMBus “接收字节”协议
参数
const struct i2c_client *client
从设备句柄
描述
这会执行 SMBus “接收字节”协议,如果发生错误则返回负 errno 值,否则返回从设备接收到的字节。
-
s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value)¶
SMBus “发送字节”协议
参数
const struct i2c_client *client
从设备句柄
u8 value
要发送的字节
描述
这会执行 SMBus “发送字节”协议,如果发生错误则返回负 errno 值,否则成功时返回零。
-
s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)¶
SMBus “读取字节”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
描述
这会执行 SMBus “读取字节”协议,如果发生错误则返回负 errno 值,否则返回从设备接收到的数据字节。
-
s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value)¶
SMBus “写入字节”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
u8 value
要写入的字节
描述
这会执行 SMBus “写入字节”协议,如果发生错误则返回负 errno 值,否则成功时返回零。
-
s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)¶
SMBus “读取字”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
描述
这会执行 SMBus “读取字”协议,如果发生错误则返回负 errno 值,否则返回从设备接收到的 16 位无符号“字”。
-
s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value)¶
SMBus “写入字”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
u16 value
要写入的 16 位“字”
描述
这会执行 SMBus “写入字”协议,如果发生错误则返回负 errno 值,否则成功时返回零。
-
s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values)¶
SMBus “块读取”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
u8 *values
将数据读入的字节数组;足够大以容纳从设备返回的数据。SMBus 最多允许 32 个字节。
描述
这会执行 SMBus “块读取”协议,如果发生错误则返回负 errno 值,否则返回从设备的响应中获取的数据字节数。
请注意,使用此函数需要客户端的适配器支持 I2C_FUNC_SMBUS_READ_BLOCK_DATA 功能。并非所有适配器驱动程序都支持此功能;通过 I2C 消息传递的模拟依赖于特定的机制 (I2C_M_RECV_LEN),该机制可能未实现。
-
s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values)¶
SMBus “块写入”协议
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
u8 length
数据块的大小;SMBus 最多允许 32 个字节
const u8 *values
将写入的字节数组。
描述
这会执行 SMBus “块写入”协议,如果发生错误则返回负 errno 值,否则成功时返回零。
-
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int protocol, union i2c_smbus_data *data)¶
执行 SMBus 协议操作
参数
struct i2c_adapter *adapter
I2C 总线的句柄。
u16 addr
该总线上 SMBus 从机的地址
unsigned short flags
I2C_CLIENT_* 标志(通常为零或 I2C_CLIENT_PEC)
char read_write
I2C_SMBUS_READ 或 I2C_SMBUS_WRITE
u8 command
从设备解释的字节,用于使用此类字节的协议
int protocol
要执行的 SMBus 协议操作,例如 I2C_SMBUS_PROC_CALL
union i2c_smbus_data *data
要读取或写入的数据
描述
这会执行 SMBus 协议操作,如果发生错误则返回负 errno 代码,否则成功时返回零。
-
s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, u8 command, u8 length, u8 *values)¶
读取数据块或模拟读取
参数
const struct i2c_client *client
从设备句柄
u8 command
从设备解释的字节
u8 length
数据块的大小;SMBus 允许的最大字节数为 I2C_SMBUS_BLOCK_MAX
u8 *values
将读取数据的字节数组;大小应足以容纳从从设备返回的数据。SMBus 允许的最大字节数为 I2C_SMBUS_BLOCK_MAX。
描述
如果适配器支持,则执行 SMBus “块读取” 协议。如果不支持块读取,则根据可用性使用字读取或字节读取协议进行模拟。
使用此函数访问的 I2C 从设备的地址必须映射到线性区域,以便块读取与字节读取具有相同的效果。在使用此函数之前,必须仔细检查 I2C 从设备是否支持与字节传输交换块传输。
-
struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup)¶
获取用于 SMBus 警报支持的 ara 客户端
参数
struct i2c_adapter *adapter
目标适配器
struct i2c_smbus_alert_setup *setup
SMBus 警报处理程序的设置数据
上下文
可以休眠
描述
在给定的 I2C 总线段上设置 SMBus 警报协议的处理。
处理可以通过我们的 IRQ 处理程序完成,也可以通过适配器(从其处理程序、定期轮询或任何其他方式)完成。
这会返回 ara 客户端,应保存该客户端以供后续与 i2c_handle_smbus_alert() 和最终的 i2c_unregister_device()
一起使用;或者返回 ERRPTR 以指示错误。