I2C 和 SMBus 子系统¶
I2C(或者没有花哨的排版,“I2C”)是“Inter-IC”总线的首字母缩写,这是一种简单的总线协议,广泛用于低数据速率通信足够的情况。 由于它也是一个获得许可的商标,因此一些供应商对同一总线使用另一个名称(例如“双线接口”,TWI)。 I2C 只需要两个信号(SCL 用于时钟,SDA 用于数据),从而节省了电路板空间并最大限度地减少了信号质量问题。 大多数 I2C 设备使用七位地址,总线速度高达 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;
};
成员
类
我们实例化哪种 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;
struct dentry *debugfs;
};
成员
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。
debugfs
指向 I2C 核心为此客户端创建的 debugfs 子目录的指针。
描述
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 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 中
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 信号上升所需的时间,单位为 ns;I2C 规范中的 t(r)
scl_fall_ns
SCL 信号下降所需的时间,单位为 ns;I2C 规范中的 t(f)
scl_int_delay_ns
IP 核额外需要的 SCL 建立时间,单位为 ns
sda_fall_ns
SDA 信号下降所需的时间,单位为 ns;I2C 规范中的 t(f)
sda_hold_ns
IP 核额外需要的 SDA 保持时间,单位为 ns
digital_filter_width_ns
IP 核数字滤波器可以滤除的 I2C 线上尖峰的宽度,单位为 ns
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 适配器中 quirk 标志的函数
参数
struct i2c_adapter *adap
I2C 适配器
u64 quirks
quirk 标志
返回
如果适配器具有所有指定的 quirk 标志,则为 true,否则为 false
-
module_i2c_driver¶
module_i2c_driver (__i2c_driver)
用于注册模块化 I2C 驱动程序的帮助程序宏
参数
__i2c_driver
i2c_driver 结构
描述
用于在模块 init/exit 中不执行任何特殊操作的 I2C 驱动程序的帮助程序宏。这消除了大量的样板代码。每个模块只能使用此宏一次,并且调用它会替换 module_init()
和 module_exit()
-
builtin_i2c_driver¶
builtin_i2c_driver (__i2c_driver)
用于注册内置 I2C 驱动程序的帮助程序宏
参数
__i2c_driver
i2c_driver 结构
描述
用于在其 init 中不执行任何特殊操作的 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() 方法处理。当我们从该函数返回时,或在任何后续时刻(例如,可能热插拔将加载驱动程序模块),驱动程序可能会绑定到此设备。此调用不适合由主板初始化逻辑使用,该逻辑通常在 arch_initcall() 期间运行,远早于任何 i2c_adapter 都可能存在的时间。
这将返回新的 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
要使用的七位地址
上下文
可以休眠
描述
这将返回绑定到“虚拟”驱动程序的 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 总线驱动程序的 Interrupt 处理程序调用的辅助函数。它将安排主机通知 IRQ。
-
int i2c_add_adapter(struct i2c_adapter *adapter)¶
声明 i2c 适配器,使用动态总线编号
参数
struct i2c_adapter *adapter
要添加的适配器
上下文
可以休眠
描述
当 I2C 适配器的总线编号无关紧要或总线编号由 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 适配器的总线编号很重要时,使用此例程来声明 I2C 适配器。 例如,将其用于来自片上系统 CPU 的 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 属性,并将结果填充到给定的结构中。如果未找到属性且 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。 使用 msg->buf 和 PIO。
或者,用于 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 以指示错误。