I3C 主控制器驱动 API

void i3c_bus_maintenance_lock(struct i3c_bus *bus)

锁定总线以进行维护操作

参数

struct i3c_bus *bus

要获取锁定的 I3C 总线

描述

此函数获取总线锁,以便不会在总线上发生其他操作。 这对于所有类型的总线维护操作都是必需的,例如 - 启用/禁用从机事件 - 重新触发 DAA - 更改设备的动态地址 - 放弃主控权 - ...

这种锁定的原因是,我们不希望驱动程序和核心逻辑依赖于可能在其背后更改的 I3C 设备信息。

void i3c_bus_maintenance_unlock(struct i3c_bus *bus)

在维护操作后释放总线锁

参数

struct i3c_bus *bus

要释放锁定的 I3C 总线

描述

应在总线维护操作完成后调用。 有关这些维护操作的更多详细信息,请参见i3c_bus_maintenance_lock()

void i3c_bus_normaluse_lock(struct i3c_bus *bus)

锁定总线以进行正常操作

参数

struct i3c_bus *bus

要获取锁定的 I3C 总线

描述

此函数获取总线锁,用于任何非维护操作的操作(有关非详尽的维护操作列表,请参见i3c_bus_maintenance_lock())。 基本上,与 I3C 设备的所有通信都是正常操作(HDR、SDR 传输或不更改总线状态或 I3C 动态地址的 CCC 命令)。

请注意,此锁不保证正常操作的序列化。 换句话说,传递给 I3C 主站的传输请求可以并行提交,并且 I3C 主驱动程序必须使用其自己的锁定来确保两个不同的通信不会混合在一起,或者在引擎繁忙时不会访问输出/输入队列。

void i3c_bus_normaluse_unlock(struct i3c_bus *bus)

在正常操作后释放总线锁

参数

struct i3c_bus *bus

要释放锁定的 I3C 总线

描述

应在正常操作完成后调用。 有关这些正常操作的更多详细信息,请参见i3c_bus_normaluse_lock()

int i3c_master_get_free_addr(struct i3c_master_controller *master, u8 start_addr)

在总线上获取空闲地址

参数

struct i3c_master_controller *master

I3C 主对象

u8 start_addr

从哪里开始搜索

描述

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

start_addr (包含) 开始的第一个空闲地址,如果没有更多可用地址,则返回 -ENOMEM。

int i3c_master_entdaa_locked(struct i3c_master_controller *master)

启动 DAA (动态地址分配) 过程

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

描述

发送 ENTDAA CCC 命令以启动 DAA 过程。

请注意,此函数仅发送 ENTDAA CCC 命令,动态地址分配背后的所有逻辑都必须在 I3C 主驱动程序中处理。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,如果错误是官方 Mx 错误代码之一,则返回正 I3C 错误代码,否则返回负错误代码。

int i3c_master_disec_locked(struct i3c_master_controller *master, u8 addr, u8 evts)

发送 DISEC CCC 命令

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

u8 addr

有效的 I3C 从机地址或 I3C_BROADCAST_ADDR

u8 evts

要禁用的事件

描述

发送 DISEC CCC 命令以禁用来自特定从机的一些或所有事件,如果 addrI3C_BROADCAST_ADDR,则禁用来自所有设备的事件。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,如果错误是官方 Mx 错误代码之一,则返回正 I3C 错误代码,否则返回负错误代码。

int i3c_master_enec_locked(struct i3c_master_controller *master, u8 addr, u8 evts)

发送 ENEC CCC 命令

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

u8 addr

有效的 I3C 从机地址或 I3C_BROADCAST_ADDR

u8 evts

要禁用的事件

描述

发送 ENEC CCC 命令以启用来自特定从机的一些或所有事件,如果 addrI3C_BROADCAST_ADDR,则启用来自所有设备的事件。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,如果错误是官方 Mx 错误代码之一,则返回正 I3C 错误代码,否则返回负错误代码。

int i3c_master_defslvs_locked(struct i3c_master_controller *master)

发送 DEFSLVS CCC 命令

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

描述

发送包含 master 已知的所有设备的 DEFSLVS CCC 命令。 当您在总线上有辅助主站来传播设备信息时,这非常有用。

应在发现所有 I3C 设备后(换句话说,在 DAA 过程完成后)并在 i3c_master_controller_ops->bus_init() 中实例化这些设备后调用此方法。 如果主站确认了热插拔请求并将动态地址分配给加入总线的设备,也应调用此方法。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,如果错误是官方 Mx 错误代码之一,则返回正 I3C 错误代码,否则返回负错误代码。

int i3c_master_do_daa(struct i3c_master_controller *master)

执行 DAA (动态地址分配)

参数

struct i3c_master_controller *master

执行 DAA 的主站

描述

此函数实例化 I3C 设备对象,并将其添加到 I3C 设备列表中。 所有设备信息都使用标准 CCC 命令自动检索。

如果主站想要使用 i3c_dev_set_master_data() 将私有数据附加到该对象,则返回 I3C 设备对象。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,否则返回负错误代码。

int i3c_master_set_info(struct i3c_master_controller *master, const struct i3c_device_info *info)

设置主设备信息

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

const struct i3c_device_info *info

I3C 设备信息

描述

设置主设备信息。 应从 i3c_master_controller_ops->bus_init() 调用此方法。

并非所有 i3c_device_info 字段对于主设备都有意义。 以下是应正确填充的字段列表

必须在维护模式下保持总线锁定的情况下调用此函数。

返回值

如果 info 包含有效信息(并非所有信息都可以检查,但我们至少可以确保 info->dyn_addrinfo->bcr 正确),则返回 0,否则返回 -EINVAL。

int i3c_master_bus_init(struct i3c_master_controller *master)

初始化 I3C 总线

参数

struct i3c_master_controller *master

初始化总线的主主站

描述

此函数遵循 I3C 规范中描述的所有初始化步骤

  1. 将 I2C 设备附加到主站,以便主站可以适当地填充其内部设备表

  2. 调用 i3c_master_controller_ops->bus_init() 方法以初始化主控制器。 通常在那里选择总线模式(纯总线或快速/慢速混合总线)

  3. 指示总线上的所有设备都放弃其动态地址。 当总线先前由其他人配置时(例如,引导加载程序),这一点尤其重要

  4. 禁用所有从机事件。

  5. 为具有 init_dyn_addr 的 I3C 设备保留地址槽。 并且,如果设备还具有 static_addr,则尝试预先分配 FW 请求的动态地址 (使用 SETDASA),并将相应的静态定义的 I3C 设备附加到主站。

  6. 执行 DAA (动态地址分配) 以将动态地址分配给所有剩余的 I3C 设备

完成后,所有 I3C 和 I2C 设备都应该可用。

返回值

成功时返回 0,否则返回负错误代码。

int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master, u8 addr)

将 I3C 从机添加到总线

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

u8 addr

分配给设备的 I3C 从机动态地址

描述

此函数实例化 I3C 设备对象,并将其添加到 I3C 设备列表中。 所有设备信息都使用标准 CCC 命令自动检索。

如果主站想要使用 i3c_dev_set_master_data() 将私有数据附加到该对象,则返回 I3C 设备对象。

必须在以写入模式保持总线锁定的情况下调用此函数。

返回值

成功时返回 0,否则返回负错误代码。

void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)

将 IBI 排队

参数

struct i3c_dev_desc *dev

此 IBI 来自的设备

struct i3c_ibi_slot *slot

用于存储有效负载的 IBI 槽

描述

将 IBI 排队到控制器工作队列。 连接到 dev 的 IBI 处理程序将从工作队列上下文中调用。

void i3c_generic_ibi_free_pool(struct i3c_generic_ibi_pool *pool)

释放通用 IBI 池

参数

struct i3c_generic_ibi_pool *pool

要释放的 IBI 池

描述

释放通用 IBI 池分配的所有 IBI 槽。

struct i3c_generic_ibi_pool *i3c_generic_ibi_alloc_pool(struct i3c_dev_desc *dev, const struct i3c_ibi_setup *req)

创建通用 IBI 池

参数

struct i3c_dev_desc *dev

此池将用于的设备

const struct i3c_ibi_setup *req

IBI 设置请求,描述设备驱动程序的期望

描述

基于 req 中提供的信息创建通用 IBI 池。

返回值

成功时返回有效的 IBI 池,否则返回 ERR_PTR()

struct i3c_ibi_slot *i3c_generic_ibi_get_free_slot(struct i3c_generic_ibi_pool *pool)

从通用 IBI 池中获取空闲槽

参数

struct i3c_generic_ibi_pool *pool

要在其上查询 IBI 槽的池

描述

在通用 IBI 池中搜索空闲槽。 在不再需要该槽时,应使用 i3c_generic_ibi_recycle_slot() 将该槽返回到池中。

返回值

指向空闲槽的指针,如果没有空闲槽可用,则返回 NULL。

void i3c_generic_ibi_recycle_slot(struct i3c_generic_ibi_pool *pool, struct i3c_ibi_slot *s)

将槽返回到通用 IBI 池

参数

struct i3c_generic_ibi_pool *pool

要将 IBI 槽返回到的池

struct i3c_ibi_slot *s

要回收的 IBI 槽

描述

将 IBI 槽添加回其通用 IBI 池。 应从主驱动程序 struct_master_controller_ops->recycle_ibi() 方法调用。

int i3c_master_register(struct i3c_master_controller *master, struct device *parent, const struct i3c_master_controller_ops *ops, bool secondary)

注册 I3C 主站

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

struct device *parent

父设备(提供此 I3C 主控制器的设备)

const struct i3c_master_controller_ops *ops

主控制器操作

bool secondary

如果要注册辅助主站,则为 true。 如果设置为 true,将返回 -ENOTSUPP,因为尚不支持辅助主站

描述

此函数会为您处理所有事情

  • 创建并初始化 I3C 总线

  • 如果 parent->of_node 不为 NULL,则使用静态 I2C 设备填充总线

  • 注册控制器在总线初始化期间添加的所有 I3C 设备

  • 注册 I2C 适配器和所有 I2C 设备

返回值

成功时返回 0,否则返回负错误代码。

void i3c_master_unregister(struct i3c_master_controller *master)

注销 I3C 主站

参数

struct i3c_master_controller *master

用于在总线上发送帧的主站

描述

基本上撤消 i3c_master_register() 中所做的一切。

struct i3c_i2c_dev_desc

I3C/I2C 设备描述符的公共部分

定义:

struct i3c_i2c_dev_desc {
    struct list_head node;
    struct i3c_master_controller *master;
    void *master_priv;
};

成员

node

用于将槽插入 I2C 或 I3C 设备列表的节点元素

master

实例化此设备的 I3C 主站。 将用于执行 I2C/I3C 传输

master_priv

分配给设备的主站私有数据。 可用于添加主站特定信息

描述

此结构描述了公共 I3C/I2C 设备信息。

struct i2c_dev_boardinfo

I2C 设备板信息

定义:

struct i2c_dev_boardinfo {
    struct list_head node;
    struct i2c_board_info base;
    u8 lvr;
};

成员

node

用于将 boardinfo 对象插入 I2C boardinfo 列表

base

常规 I2C 板信息

lvr

I3C 核心需要 LVR (旧版虚拟寄存器) 来了解 I2C 设备的限制

描述

此结构用于将板级信息附加到 I2C 设备。 连接在 I3C 总线上的每个 I2C 设备都应具有一个。

struct i2c_dev_desc

I2C 设备描述符

定义:

struct i2c_dev_desc {
    struct i3c_i2c_dev_desc common;
    struct i2c_client *dev;
    u16 addr;
    u8 lvr;
};

成员

common

I2C 设备描述符的公共部分

dev

注册到 I2C 框架的 I2C 设备对象

addr

I2C 设备地址

lvr

I3C 核心需要 LVR (旧版虚拟寄存器) 来了解 I2C 设备的限制

描述

连接在总线上的每个 I2C 设备都将具有 i2c_dev_desc。 此对象由核心创建,稍后使用 struct_i3c_master_controller->ops->attach_i2c_dev() 连接到控制器。

struct_i2c_dev_desc 是连接在 I3C 总线上的 I2C 设备的内部表示。 此对象也会传递到所有 struct_i3c_master_controller_ops 挂钩。

struct i3c_ibi_slot

I3C IBI (带内中断) 槽

定义:

struct i3c_ibi_slot {
    struct work_struct work;
    struct i3c_dev_desc *dev;
    unsigned int len;
    void *data;
};

成员

work

与此槽关联的工作。 IBI 处理程序将从那里调用

dev

生成此 IBI 的 I3C 设备

len

与此 IBI 关联的有效负载的长度

data

有效负载缓冲区

描述

IBI 槽是由控制器预分配的对象,并在 IBI 进入时使用。 每次 IBI 进入时,I3C 主驱动程序应在其 IBI 槽池中找到一个空闲 IBI 槽,检索 IBI 有效负载,并使用 i3c_master_queue_ibi() 将 IBI 排队。

IBI 槽的分配方式留给 I3C 主驱动程序处理,但是,对于简单的基于 kmalloc 的分配,可以使用通用 IBI 槽池。

struct i3c_device_ibi_info

附加到特定设备的 IBI 信息

定义:

struct i3c_device_ibi_info {
    struct completion all_ibis_handled;
    atomic_t pending_ibis;
    unsigned int max_payload_len;
    unsigned int num_slots;
    unsigned int enabled;
    struct workqueue_struct *wq;
    void (*handler)(struct i3c_device *dev, const struct i3c_ibi_payload *payload);
};

成员

all_ibis_handled

用于在没有更多 IBI 等待处理时通知。 i3c_device_disable_ibi() 使用此功能来等待所有 IBI 出队

pending_ibis

计算挂起的 IBI 的数量。 每个挂起的 IBI 都将其工作元素排队到控制器工作队列

max_payload_len

来自此 IBI 的 IBI 的最大有效负载长度。 在调用 i3c_device_request_ibi() 时指定此值,并且不应在运行时更改。 主站应拒绝所有超过此限制的消息 IBI

num_slots

为此设备保留的 IBI 槽的数量

enabled

反映 IBI 状态

wq

用于执行 IBI 处理程序的工作队列。

handler

i3c_device_request_ibi() 调用时指定的 IBI 处理程序。 此处理程序将从控制器工作队列调用,因此允许休眠(尽管建议尽可能快地处理 IBI,以避免阻止在同一工作队列上排队的其他 IBI 的处理)。 可以从 IBI 处理程序发送新的 I3C 消息

描述

在调用 i3c_device_request_ibi() 并附加到特定设备时,会分配 struct_i3c_device_ibi_info 对象。 此对象用于管理来自特定 I3C 设备的 IBI。

请注意,此结构是 IBI 管理基础结构的通用视图。 I3C 主驱动程序可能具有自己的内部表示,可以使用控制器私有数据将其与设备关联。

struct i3c_dev_boardinfo

I3C 设备板信息

定义:

struct i3c_dev_boardinfo {
    struct list_head node;
    u8 init_dyn_addr;
    u8 static_addr;
    u64 pid;
    struct device_node *of_node;
};

成员

node

用于将 boardinfo 对象插入 I3C boardinfo 列表

init_dyn_addr

FW 请求的初始动态地址。 我们不保证设备最终将使用此地址,但会尽力将此特定地址分配给设备

static_addr

I3C 设备在主站为其分配动态地址之前侦听的静态地址。 将在总线初始化期间使用此地址为其分配特定动态地址,然后再启动 DAA (动态地址分配)

pid

设备暴露的 I3C Provisioned ID。当设备没有静态地址时,这可以用作将 boardinfo 附加到 i3c_dev_desc 的唯一标识符。

of_node

可选的 DT 节点,以防设备已在 DT 中描述。

描述

此结构用于将板级信息附加到 I3C 设备。并非总线上连接的所有 I3C 设备都有 boardinfo。只有当您想将额外的资源附加到设备或为其分配特定的动态地址时才需要。

struct i3c_dev_desc

I3C 设备描述符

定义:

struct i3c_dev_desc {
    struct i3c_i2c_dev_desc common;
    struct i3c_device_info info;
    struct mutex ibi_lock;
    struct i3c_device_ibi_info *ibi;
    struct i3c_device *dev;
    const struct i3c_dev_boardinfo *boardinfo;
};

成员

common

I3C 设备描述符的公共部分

info

I3C 设备信息。当您使用 i3c_master_add_i3c_dev_locked() 创建设备时,将自动填充。

ibi_lock

用于保护 struct_i3c_device->ibi 的锁

ibi

附加到设备的 IBI 信息。在调用 i3c_device_request_ibi() 之前应为 NULL

dev

指向暴露给 I3C 设备驱动程序的 I3C 设备对象的指针。永远不应从 I3C 主控制器驱动程序访问此对象。只有核心代码应在更新 dev <-> desc 链接或将 IBI 事件传播到驱动程序时操作它。

boardinfo

指向附加到此 I3C 设备的 boardinfo 的指针

描述

I3C 设备的内部表示。此对象仅由核心使用,并在请求对设备执行某些操作时传递给 I3C 主控制器驱动程序。核心维护内部 I3C 设备描述符和暴露给 I3C 设备驱动程序的对象 (struct_i3c_device) 之间的链接。

struct i3c_device

I3C 设备对象

定义:

struct i3c_device {
    struct device dev;
    struct i3c_dev_desc *desc;
    struct i3c_bus *bus;
};

成员

dev

用于将 I3C 设备注册到设备模型的设备对象

desc

指向 i3c 设备描述符对象的指针。每次使用分配的不同动态地址重新发现 I3C 设备时,都会更新此链接。

bus

此设备连接到的 I3C 总线

描述

暴露给 I3C 设备驱动程序的 I3C 设备对象。负责将此对象链接到相关的 struct_i3c_dev_desc 对象。I3C 总线上的所有 I3C 设备都已表示,包括 I3C 主设备。对于每个设备,我们都有一个 struct i3c_device 的实例。

enum i3c_bus_mode

I3C 总线模式

常量

I3C_BUS_MODE_PURE

只有 I3C 设备连接到总线。没有预期限制。

I3C_BUS_MODE_MIXED_FAST

总线上存在带有 50ns 尖峰滤波器的 I2C 设备。此模式下的唯一影响是高 SCL 脉冲必须保持在 50ns 以下,才能在传输 I3C 帧时欺骗 I2C 设备。

I3C_BUS_MODE_MIXED_LIMITED

总线上存在没有 50ns 尖峰滤波器的 I2C 设备。但是,它们允许符合高达最大 SDR SCL 时钟频率的要求。

I3C_BUS_MODE_MIXED_SLOW

总线上存在没有 50ns 尖峰滤波器的 I2C 设备。

enum i3c_open_drain_speed

I3C 开漏速度

常量

I3C_OPEN_DRAIN_SLOW_SPEED

用于发送第一个广播地址的慢速开漏速度。此速度下的第一个广播地址对 I3C 总线上的所有设备可见。以 I2C 模式工作的 I3C 设备将在切换到 I3C 模式时关闭其尖峰滤波器。

I3C_OPEN_DRAIN_NORMAL_SPEED

I3C 总线模式下的正常开漏速度。

enum i3c_addr_slot_status

I3C 地址槽状态

常量

I3C_ADDR_SLOT_FREE

地址空闲

I3C_ADDR_SLOT_RSVD

地址已保留

I3C_ADDR_SLOT_I2C_DEV

地址已分配给 I2C 设备

I3C_ADDR_SLOT_I3C_DEV

地址已分配给 I3C 设备

I3C_ADDR_SLOT_STATUS_MASK

地址槽掩码

I3C_ADDR_SLOT_EXT_STATUS_MASK

带有扩展信息的地址槽掩码

I3C_ADDR_SLOT_EXT_DESIRED

该位掩码表示某些设备首选的地址,例如设备树源中的“assigned-address”属性。在 I3C 总线上,地址是动态分配的,我们需要知道哪些地址可以自由使用,哪些地址已经被分配。

描述

标记为保留的地址是 I3C 协议保留的地址(广播地址等)。

struct i3c_bus

I3C 总线对象

定义:

struct i3c_bus {
    struct i3c_dev_desc *cur_master;
    int id;
    unsigned long addrslots[((I2C_MAX_ADDR + 1) * I3C_ADDR_SLOT_STATUS_BITS) / BITS_PER_LONG];
    enum i3c_bus_mode mode;
    struct {
        unsigned long i3c;
        unsigned long i2c;
    } scl_rate;
    struct {
        struct list_head i3c;
        struct list_head i2c;
    } devs;
    struct rw_semaphore lock;
};

成员

cur_master

当前驱动总线的 I3C 主设备。由于 I3C 是多主设备,因此这可能会随时间变化。将用于让主设备知道是否需要在发送帧之前请求总线所有权。

id

总线 ID。由框架在注册总线时分配。

addrslots

一个位图,每个插槽 2 位,用于编码地址状态并简化 DAA(动态地址分配)过程(参见 enum i3c_addr_slot_status)。

mode

总线模式(参见 enum i3c_bus_mode)。

scl_rate

I3C 和 I2C 模式下的 SCL 信号速率

scl_rate.i3c

执行 I3C SDR/私有传输时时钟信号的最大速率

scl_rate.i2c

执行 I2C 传输时时钟信号的最大速率

devs

2 个列表,其中包含连接到总线的所有 I3C/I2C 设备

devs.i3c

包含 I3C 设备描述符列表,这些描述符表示连接到总线并成功附加到 I3C 主设备的 I3C 设备

devs.i2c

包含 I2C 设备描述符列表,这些描述符表示连接到总线并成功附加到 I3C 主设备的 I2C 设备

lock

总线上的读/写锁。这是为了防止对整个总线及其连接的设备产生影响的操作。例如,当要求从设备放弃其动态地址 (RSTDAA CCC) 时,我们需要确保没有人尝试向这些设备发送 I3C 帧。请注意,此锁不能防止设备之间的并发:多个驱动程序可以并行通过同一个主设备发送不同的 I3C/I2C 帧。主设备有责任保证帧实际上是按顺序发送而不是交错发送的。

描述

I3C 总线用其自身的对象表示,而不是由 I3C 主设备隐式描述,以处理多主设备功能,其中一个总线可以在多个主设备之间共享,每个主设备在需要时请求总线所有权。

struct i3c_master_controller_ops

I3C 主设备方法

定义:

struct i3c_master_controller_ops {
    int (*bus_init)(struct i3c_master_controller *master);
    void (*bus_cleanup)(struct i3c_master_controller *master);
    int (*attach_i3c_dev)(struct i3c_dev_desc *dev);
    int (*reattach_i3c_dev)(struct i3c_dev_desc *dev, u8 old_dyn_addr);
    void (*detach_i3c_dev)(struct i3c_dev_desc *dev);
    int (*do_daa)(struct i3c_master_controller *master);
    bool (*supports_ccc_cmd)(struct i3c_master_controller *master, const struct i3c_ccc_cmd *cmd);
    int (*send_ccc_cmd)(struct i3c_master_controller *master, struct i3c_ccc_cmd *cmd);
    int (*priv_xfers)(struct i3c_dev_desc *dev,struct i3c_priv_xfer *xfers, int nxfers);
    int (*attach_i2c_dev)(struct i2c_dev_desc *dev);
    void (*detach_i2c_dev)(struct i2c_dev_desc *dev);
    int (*i2c_xfers)(struct i2c_dev_desc *dev, struct i2c_msg *xfers, int nxfers);
    int (*request_ibi)(struct i3c_dev_desc *dev, const struct i3c_ibi_setup *req);
    void (*free_ibi)(struct i3c_dev_desc *dev);
    int (*enable_ibi)(struct i3c_dev_desc *dev);
    int (*disable_ibi)(struct i3c_dev_desc *dev);
    void (*recycle_ibi_slot)(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot);
    int (*enable_hotjoin)(struct i3c_master_controller *master);
    int (*disable_hotjoin)(struct i3c_master_controller *master);
    int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed);
};

成员

bus_init

负责 I3C 总线初始化的钩子。您至少应该从那里调用 master_set_info() 并设置总线模式。您也可以将控制器特定的初始化放在那里。此方法是必需的。

bus_cleanup

清理在 i3c_master_controller_ops->bus_init() 中完成的所有操作。此方法是可选的。

attach_i3c_dev

每次将 I3C 设备连接到总线时调用。它可以在 DAA 之后,也可以在设备由固件静态声明时调用,在这种情况下,它将只有静态地址,动态地址将为 0。调用此函数时,尚未检索设备信息。这是将主控制器特定数据附加到 I3C 设备的好地方。此方法是可选的。

reattach_i3c_dev

每次 I3C 设备的地址更改时调用。可能是因为设备已断电并丢失了其地址,或者当设备具有静态地址并且已使用 SETDASA 分配了动态地址时发生。此方法是可选的。

detach_i3c_dev

当 I3C 设备从总线分离时调用。通常在注销主设备时发生。此方法是可选的。

do_daa

执行 DAA(动态地址分配)过程。此过程应发送 ENTDAA CCC 命令,然后使用 i3c_master_add_i3c_dev_locked() 添加 DAA 发现的所有设备。使用 i3c_master_add_i3c_dev_locked() 添加的设备随后将连接或重新连接到控制器。此方法是必需的。

supports_ccc_cmd

如果支持 CCC 命令,则应返回 true,否则返回 false。此方法是可选的,如果未提供,则核心假定支持所有 CCC 命令。

send_ccc_cmd

发送 CCC 命令。此方法是必需的。

priv_xfers

执行一个或多个私有 I3C SDR 传输。此方法是必需的。

attach_i2c_dev

每次将 I2C 设备连接到总线时调用。这是将主控制器特定数据附加到 I2C 设备的好地方。此方法是可选的。

detach_i2c_dev

当 I2C 设备从总线分离时调用。通常在注销主设备时发生。此方法是可选的。

i2c_xfers

执行一个或多个 I2C 传输。请注意,与 i3c 传输不同,核心不保证附加到传输的缓冲区是 DMA 安全的。如果驱动程序想要具有 DMA 安全缓冲区,则应使用 I2C 框架提供的 i2c_get_dma_safe_msg_buf()i2c_put_dma_safe_msg_buf() 辅助函数。此方法是必需的。

request_ibi

将 IBI 处理程序附加到 I3C 设备。这意味着定义 IBI 处理程序和 IBI 的约束(最大有效负载长度和预分配槽的数量)。某些控制器支持的具有 IBI 功能的设备少于常规设备,因此如果没有更多空间用于额外的 IBI 注册,则此方法可能会返回 -EBUSY。此方法是可选的。

free_ibi

释放先前使用 ->request_ibi() 请求的 IBI。IBI 应该在使用 ->disable_irq() 禁用的情况下进行。仅当 ->request_ibi 不为 NULL 时,此方法才是必需的。

enable_ibi

启用 IBI。仅当先前已调用 ->request_ibi() 时,->enable_ibi() 才有效。控制器应首先在控制器端启用 IBI(例如,取消屏蔽硬件 IRQ),然后将 ENEC CCC 命令(设置了 IBI 标志)发送到 I3C 设备。仅当 ->request_ibi 不为 NULL 时,此方法才是必需的。

disable_ibi

禁用 IBI。首先发送带有 IBI 标志的 DISEC CCC 命令,然后在控制器端停用硬件 IRQ。仅当 ->request_ibi 不为 NULL 时,此方法才是必需的。

recycle_ibi_slot

回收 IBI 插槽。每次 IBI 由其处理程序处理时调用。IBI 插槽应放回 IBI 插槽池中,以便控制器可以将其重新用于将来的 IBI。仅当 ->request_ibi 不为 NULL 时,此方法才是必需的。

enable_hotjoin

启用热插拔事件检测。

disable_hotjoin

禁用热插拔事件检测。

set_speed

调整 I3C 开漏模式时序。

struct i3c_master_controller

I3C 主控制器对象

定义:

struct i3c_master_controller {
    struct device dev;
    struct i3c_dev_desc *this;
    struct i2c_adapter i2c;
    const struct i3c_master_controller_ops *ops;
    unsigned int secondary : 1;
    unsigned int init_done : 1;
    unsigned int hotjoin: 1;
    struct {
        struct list_head i3c;
        struct list_head i2c;
    } boardinfo;
    struct i3c_bus bus;
    struct workqueue_struct *wq;
};

成员

dev

要注册到设备模型的设备

this

表示此主设备的 I3C 设备对象。此设备将添加到总线上可用的 I3C 设备列表中。

i2c

用于向后兼容的 I2C 适配器。此适配器已注册到 I2C 子系统,以便尽可能透明地处理现有的 I2C 驱动程序。

ops

主设备操作。参见 struct i3c_master_controller_ops

secondary

如果主设备是辅助主设备,则为 true。

init_done

总线初始化完成时为 true。

hotjoin

如果主设备支持热插拔,则为 true。

boardinfo

附加到总线上连接的设备的板级信息

boardinfo.i3c

I3C boardinfo 对象列表

boardinfo.i2c

I2C boardinfo 对象列表

bus

此主设备暴露的 I3C 总线

wq

工作队列,如果主驱动程序需要推迟需要在线程上下文中发生的操作,则可以使用该队列。典型的例子是热插拔处理,它需要在维护中获取总线锁,而这只能从可睡眠的上下文中完成。

描述

必须通过 i3c_master_register()struct i3c_master_controller 注册到 I3C 子系统。不应手动设置 struct i3c_master_controller 的任何字段,只需将适当的值传递给 i3c_master_register()

i3c_bus_for_each_i2cdev

i3c_bus_for_each_i2cdev (bus, dev)

迭代总线上存在的所有 I2C 设备

参数

bus

I3C 总线

dev

一个 I2C 设备描述符指针,更新为指向循环的每次迭代中的当前插槽

描述

迭代总线上存在的所有 I2C 设备。

i3c_bus_for_each_i3cdev

i3c_bus_for_each_i3cdev (bus, dev)

迭代总线上存在的所有 I3C 设备

参数

bus

I3C 总线

dev

一个 I3C 设备描述符指针,更新为指向循环的每次迭代中的当前插槽

描述

迭代总线上存在的所有 I3C 设备。

void *i3c_dev_get_master_data(const struct i3c_dev_desc *dev)

获取附加到 I3C 设备描述符的主设备私有数据

参数

const struct i3c_dev_desc *dev

从中获取私有数据的 I3C 设备描述符

返回值

先前使用 i3c_dev_set_master_data() 附加的私有数据

如果没有任何数据附加到设备,则为 NULL。

void i3c_dev_set_master_data(struct i3c_dev_desc *dev, void *data)

将主设备私有数据附加到 I3C 设备描述符

参数

struct i3c_dev_desc *dev

要将私有数据附加到的 I3C 设备描述符

void *data

私有数据

描述

此函数允许主控制器附加每个设备的私有数据,然后可以使用 i3c_dev_get_master_data() 检索该数据。

void *i2c_dev_get_master_data(const struct i2c_dev_desc *dev)

获取附加到 I2C 设备描述符的主设备私有数据

参数

const struct i2c_dev_desc *dev

从中获取私有数据的 I2C 设备描述符

返回值

先前使用 i2c_dev_set_master_data() 附加的私有数据

如果没有任何数据附加到设备,则为 NULL。

void i2c_dev_set_master_data(struct i2c_dev_desc *dev, void *data)

将主设备私有数据附加到 I2C 设备描述符

参数

struct i2c_dev_desc *dev

要将私有数据附加到的 I2C 设备描述符

void *data

私有数据

描述

此函数允许主控制器附加每个设备的私有数据,然后可以使用 i2c_device_get_master_data() 检索该数据。

struct i3c_master_controller *i3c_dev_get_master(struct i3c_dev_desc *dev)

获取用于与设备通信的主设备

参数

struct i3c_dev_desc *dev

I3C 设备

返回值

驱动 dev 的主控制器

struct i3c_master_controller *i2c_dev_get_master(struct i2c_dev_desc *dev)

获取用于与设备通信的主设备

参数

struct i2c_dev_desc *dev

I2C 设备

返回值

驱动 dev 的主控制器

struct i3c_bus *i3c_master_get_bus(struct i3c_master_controller *master)

获取附加到主设备的总线

参数

struct i3c_master_controller *master

主设备对象

返回值

master 连接到的 I3C 总线