USB Type-C Alternate Mode 驱动程序的 API

简介

Alternate Mode 需要使用供应商定义消息 (VDM) 与伙伴通信,如 USB Type-C 和 USB Power Delivery 规范中所定义。该通信是 SVID(标准或供应商 ID)特定的,即对于每个 Alternate Mode 都是特定的,因此每个 Alternate Mode 都需要一个自定义驱动程序。

USB Type-C 总线允许通过使用 SVID 和模式编号将驱动程序绑定到已发现的伙伴 Alternate Mode。

USB Type-C 连接器类 为端口支持的每个 Alternate Mode 提供一个设备,并为伙伴支持的每个 Alternate Mode 提供单独的设备。Alternate Mode 的驱动程序绑定到伙伴 Alternate Mode 设备,并且端口 Alternate Mode 设备必须由端口驱动程序处理。

当注册新的伙伴 Alternate Mode 设备时,它会链接到伙伴所连接的端口的 Alternate Mode 设备,该设备具有匹配的 SVID 和模式。端口驱动程序和 Alternate Mode 驱动程序之间的通信将使用相同的 API 进行。

端口 Alternate Mode 设备用作伙伴和 Alternate Mode 驱动程序之间的代理,因此端口驱动程序仅需要将来自 Alternate Mode 驱动程序的 SVID 特定命令传递给伙伴,并将来自伙伴的 SVID 特定命令传递给 Alternate Mode 驱动程序。端口驱动程序不需要直接的 SVID 特定通信,但是端口驱动程序需要为端口 Alternate Mode 设备提供操作回调,就像 Alternate Mode 驱动程序需要为伙伴 Alternate Mode 设备提供操作回调一样。

用法:

常规

默认情况下,Alternate Mode 驱动程序负责进入模式。也可以将有关进入模式的决定留给用户空间(参见 ABI 文件测试/sysfs-class-typec)。端口驱动程序不应自行进入任何模式。

->vdm 是操作回调向量中最重要的回调。它将用于将来自伙伴的所有 SVID 特定命令传递给 Alternate Mode 驱动程序,反之亦然,对于端口驱动程序也是如此。驱动程序使用 typec_altmode_vdm() 相互发送 SVID 特定命令。

如果使用 SVID 特定命令与伙伴通信导致需要重新配置连接器上的引脚,则 Alternate Mode 驱动程序需要使用 typec_altmode_notify() 通知总线。驱动程序将协商的 SVID 特定引脚配置值作为参数传递给该函数。然后,总线驱动程序将使用该值作为 mux 的状态值来配置连接器后面的 mux。

注意:SVID 特定引脚配置值必须始终从 TYPEC_STATE_MODAL 开始。USB Type-C 规范为连接器定义了两个默认状态:TYPEC_STATE_USBTYPEC_STATE_SAFE。这些值由总线保留作为状态的第一个可能值。当进入 Alternate Mode 时,总线会将连接器置于 TYPEC_STATE_SAFE,然后在发送 Enter 或 Exit Mode 命令之前,如 USB Type-C 规范中所定义,并在退出模式后将连接器恢复到 TYPEC_STATE_USB

SVID 特定引脚配置的工作定义示例如下

enum {
    ALTMODEX_CONF_A = TYPEC_STATE_MODAL,
    ALTMODEX_CONF_B,
    ...
};

Helper 宏 TYPEC_MODAL_STATE() 也可以使用

#define ALTMODEX_CONF_A = TYPEC_MODAL_STATE(0);
#define ALTMODEX_CONF_B = TYPEC_MODAL_STATE(1);

电缆插头 Alternate Mode

Alternate Mode 驱动程序不绑定到电缆插头 Alternate Mode 设备,而仅绑定到伙伴 Alternate Mode 设备。如果 Alternate Mode 支持或需要响应 SOP Prime,以及可选的 SOP Double Prime 消息的电缆,则该 Alternate Mode 的驱动程序必须使用 typec_altmode_get_plug() 请求处理电缆插头 Alternate Mode,并接管它们的控制。

驱动程序 API

Alternate Mode 结构体

struct typec_altmode_ops

Alternate Mode 特定操作向量

定义:

struct typec_altmode_ops {
    int (*enter)(struct typec_altmode *altmode, u32 *vdo);
    int (*exit)(struct typec_altmode *altmode);
    void (*attention)(struct typec_altmode *altmode, u32 vdo);
    int (*vdm)(struct typec_altmode *altmode, const u32 hdr, const u32 *vdo, int cnt);
    int (*notify)(struct typec_altmode *altmode, unsigned long conf, void *data);
    int (*activate)(struct typec_altmode *altmode, int activate);
};

成员

enter

要使用 Enter Mode 命令执行的操作

exit

要使用 Exit Mode 命令执行的操作

attention

Attention 命令的回调

vdm

SVID 特定命令的回调

notify

平台和 Alternate Mode 的通信通道

activate

Enter/Exit Mode 的用户回调

struct typec_altmode_driver

USB Type-C Alternate Mode 设备驱动程序

定义:

struct typec_altmode_driver {
    const struct typec_device_id *id_table;
    int (*probe)(struct typec_altmode *altmode);
    void (*remove)(struct typec_altmode *altmode);
    struct device_driver driver;
};

成员

id_table

以 NULL 结尾的 SVID 数组

probe

设备绑定的回调

remove

设备解除绑定的回调

driver

设备驱动程序模型驱动程序

描述

这些驱动程序将绑定到伙伴 Alternate Mode 设备。它们将处理所有 SVID 特定通信。

Alternate Mode 驱动程序注册/注销

typec_altmode_register_driver

typec_altmode_register_driver (drv)

注册 USB Type-C Alternate Mode 设备驱动程序

参数

drv

指向 struct typec_altmode_driver 的指针

描述

这些驱动程序将绑定到伙伴 Alternate Mode 设备。它们将处理所有 SVID 特定通信。

void typec_altmode_unregister_driver(struct typec_altmode_driver *drv)

注销 USB Type-C Alternate Mode 设备驱动程序

参数

struct typec_altmode_driver *drv

指向 struct typec_altmode_driver 的指针

描述

这些驱动程序将绑定到伙伴 Alternate Mode 设备。它们将处理所有 SVID 特定通信。

Alternate Mode 驱动程序操作

int typec_altmode_notify(struct typec_altmode *adev, unsigned long conf, void *data)

操作系统和 Alternate Mode 驱动程序之间的通信

参数

struct typec_altmode *adev

Alternate Mode 的句柄

unsigned long conf

Alternate Mode 特定配置值

void *data

Alternate Mode 特定数据

描述

此函数的主要目的是允许 Alternate Mode 驱动程序告知与伙伴协商了哪个引脚配置。然后,该信息将用于例如配置 mux。也可以向另一个方向通信,并且底层设备驱动程序也可以向 Alternate Mode 驱动程序发送通知。实际通信对于每个 SVID 都是特定的。

int typec_altmode_enter(struct typec_altmode *adev, u32 *vdo)

进入模式

参数

struct typec_altmode *adev

Alternate Mode

u32 *vdo

Enter Mode 命令的 VDO

描述

Alternate Mode 驱动程序使用此函数进入模式。端口驱动程序使用它来通知 Alternate Mode 驱动程序伙伴已启动 Enter Mode 命令。如果 Alternate Mode 不需要 VDO,则 vdo 必须为 NULL。

int typec_altmode_exit(struct typec_altmode *adev)

退出模式

参数

struct typec_altmode *adev

Alternate Mode

描述

adev 的伙伴已启动 Exit Mode 命令。

int typec_altmode_attention(struct typec_altmode *adev, u32 vdo)

Attention 命令

参数

struct typec_altmode *adev

Alternate Mode

u32 vdo

Attention 命令的 VDO

描述

通知 adev 的伙伴有关 Attention 命令。

int typec_altmode_vdm(struct typec_altmode *adev, const u32 header, const u32 *vdo, int count)

将供应商定义消息 (VDM) 发送到伙伴

参数

struct typec_altmode *adev

Alternate Mode 句柄

const u32 header

VDM 标头

const u32 *vdo

供应商定义数据对象数组

int count

数据对象数

描述

Alternate Mode 驱动程序使用此函数与伙伴进行 SVID 特定通信。端口驱动程序使用它将从伙伴收到的结构化 VDM 传递给 Alternate Mode 驱动程序。

端口驱动程序的 API

struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, size_t n, u16 svid, u8 mode)

将 SVID 和模式匹配到 Alternate Mode 数组

参数

struct typec_altmode **altmodes

Alternate Mode 数组

size_t n

数组中的元素数,对于以 NULL 结尾的数组为 -1

u16 svid

要匹配的标准或供应商 ID

u8 mode

要匹配的模式

描述

返回指向 SVID 与 svid 匹配的 Alternate Mode 的指针,或者在未找到匹配项时返回 NULL。

电缆插头操作

struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *adev, enum typec_plug_index index)

查找电缆插头 Alternate Mode

参数

struct typec_altmode *adev

伙伴 Alternate Mode 的句柄

enum typec_plug_index index

电缆插头索引

描述

增加电缆插头 Alternate Mode 设备的引用计数。返回电缆插头 Alternate Mode 的句柄,如果未找到,则返回 NULL。

void typec_altmode_put_plug(struct typec_altmode *plug)

减少电缆插头 Alternate Mode 引用计数

参数

struct typec_altmode *plug

电缆插头 Alternate Mode 的句柄