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 的控制代碼