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 命令以禁用来自特定从属设备的部分或全部事件,如果 **addr** 为 I3C_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 命令以启用来自特定从属设备的部分或全部事件,如果 **addr** 为 I3C_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()中实例化后调用。 如果主控器 ACK 了热加入请求并为加入总线的设备分配了动态地址,也应该调用它。

必须在持有总线锁的写入模式下调用此函数。

返回

成功时为 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,则尝试使用 SETDASA 预分配 FW 请求的动态地址,并将相应的静态定义的 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 排队到控制器工作队列。附加到设备的 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

用于将板级信息对象插入 I2C 板级信息列表

base

常规 I2C 板级信息

lvr

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

描述

此结构用于将板级信息附加到 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 内核需要了解 I2C 设备限制的 LVR(旧版虚拟寄存器)

描述

连接到总线的每个 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 的最大有效负载长度。此值在调用 i3c_device_request_ibi() 时指定,并且不应在运行时更改。所有超出此限制的消息 IBI 都应由主设备拒绝

num_slots

为此设备保留的 IBI 槽数

enabled

反映 IBI 状态

wq

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

handler

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

描述

当调用 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

用于将板级信息对象插入 I3C 板级信息列表

init_dyn_addr

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

static_addr

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

pid

设备公开的 I3C 预配置 ID。这是一个唯一的标识符,当设备没有静态地址时,可以使用该标识符将板级信息附加到 i3c_dev_desc

of_node

如果设备已在 DT 中描述,则为可选的 DT 节点

描述

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

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 设备的板级信息的指针

描述

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 总线上的所有设备可见。在切换到 I3C 模式时,以 I2C 模式工作的 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

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

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, const 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。仅当在 ->enable_ibi() 之前调用了 ->request_ibi() 时才有效。控制器应首先在控制器端启用 IBI(例如,取消屏蔽硬件 IRQ),然后向 I3C 设备发送 ENEC CCC 命令(设置了 IBI 标志)。此方法仅当 ->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.i2c

I2C 板级信息对象列表

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 总线