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 字段应设置为此驱动程序的名称。

为了实现自动设备检测,必须定义 detectaddress_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_clientstruct 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 i2c_adapter *i2c_verify_adapter(struct device *dev)

将参数作为 i2c_adapter 返回或返回 NULL

参数

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_adapteri2c_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_adapterstruct 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_adapterstruct 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 以指示错误。