I2C 地址轉換器¶
作者:Luca Ceresoli <luca@lucaceresoli.net> 作者:Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
描述¶
I2C 地址轉換器 (ATR) 是一種具有 I2C 從裝置父埠(“上游”)和 N 個 I2C 主裝置子埠(“下游”)的裝置,並將來自上游的事務以修改後的從裝置地址轉發到適當的下游埠。父總線上使用的地址稱為“別名”,並且與子匯流排的物理從裝置地址(可能)不同。 地址轉換由硬體完成。
- ATR 看起來類似於 i2c-mux,除了
父匯流排和子總線上的地址可能不同
通常不需要選擇子埠;父總線上使用的別名暗示了這一點
ATR 功能可以由具有許多其他功能的晶片提供。核心 i2c-atr 提供了一個幫助程式,用於在驅動程式中實現 ATR。
ATR 在每個子總線上建立一個新的 I2C“子”介面卡。 在子總線上新增裝置最終會呼叫驅動程式程式碼來選擇可用的別名。維護適當的可用別名池併為每個新裝置選擇一個別名由驅動程式實現者負責。 ATR 維護一個當前分配的別名表,並使用它來修改所有定向到子總線上裝置的 I2C 事務。
以下是一個典型的例子。
拓撲
Slave X @ 0x10
.-----. |
.-----. | |---+---- B
| CPU |--A--| ATR |
`-----' | |---+---- C
`-----' |
Slave Y @ 0x10
別名表
A、B 和 C 是三個物理 I2C 匯流排,在電氣上彼此獨立。 ATR 接收在匯流排 A 上啟動的事務,並根據事務中的裝置地址和別名表,將它們傳播到匯流排 B 或匯流排 C,或者不傳播到任何匯流排。
別名表
客戶端 |
別名 |
|---|---|
X(匯流排 B,0x10) |
0x20 |
Y(匯流排 C,0x10) |
0x30 |
交易
從裝置 X 驅動程式請求一個事務(在介面卡 B 上),從裝置地址 0x10
ATR 驅動程式發現從裝置 X 在匯流排 B 上,並且別名為 0x20,使用地址 0x20 重寫訊息,轉發到介面卡 A
匯流排 A 上的物理 I2C 事務,從裝置地址 0x20
ATR 晶片檢測到地址 0x20 上的事務,在表中找到它,將事務傳播到匯流排 B,地址轉換為 0x10,保持匯流排 A 上的時鐘拉伸,等待回覆
從裝置 X 晶片(在匯流排 B 上)檢測到其自己的物理地址 0x10 上的事務,並正常回復
ATR 晶片停止時鐘拉伸,並在匯流排 A 上轉發回覆,地址轉換回 0x20
ATR 驅動程式接收回復,使用地址 0x10 重寫訊息,因為它們最初是
從裝置 X 驅動程式取回 msgs[],其中包含回覆和地址 0x10
用法
在驅動程式中(通常在 probe 函式中),透過呼叫
i2c_atr_new()並傳遞 attach/detach 回撥來新增 ATR當呼叫 attach 回撥時,選擇適當的別名,在晶片中配置它,並在 alias_id 引數中返回所選別名
當呼叫 detach 回撥時,從晶片中取消配置別名,並將別名放回池中以供以後使用
I2C ATR 函式和資料結構¶
-
enum i2c_atr_flags¶
I2C ATR 驅動程式的標誌
常量
I2C_ATR_F_STATICATR 不支援動態對映,使用靜態對映。對映只會因裝置從子匯流排新增或刪除而新增或刪除。 ATR 池必須足夠大,以容納預計新增到子匯流排的所有裝置。
I2C_ATR_F_PASSTHROUGH允許未對映的傳入地址透過
-
struct i2c_atr_ops¶
從 ATR 到裝置驅動程式的回撥。
定義:
struct i2c_atr_ops {
int (*attach_addr)(struct i2c_atr *atr, u32 chan_id, u16 addr, u16 alias);
void (*detach_addr)(struct i2c_atr *atr, u32 chan_id, u16 addr);
};
成員
attach_addr通知驅動程式有新裝置連線到子匯流排,併為其分配了別名。 驅動程式必須配置硬體以使用該別名。
detach_addr通知驅動程式裝置已斷開連線。 驅動程式必須配置硬體以停止使用該別名。
描述
所有這些函式在成功時返回 0,否則返回一個負錯誤程式碼。
-
struct i2c_atr_adap_desc¶
ATR 下游匯流排描述符
定義:
struct i2c_atr_adap_desc {
u32 chan_id;
struct device *parent;
struct fwnode_handle *bus_handle;
size_t num_aliases;
u16 *aliases;
};
成員
chan_id新介面卡的索引(0 .. max_adapters-1)。此值將傳遞給
struct i2c_atr_ops中的回撥。parent用作新 i2c 介面卡父裝置的裝置,或者為 NULL 以使用 i2c-atr 裝置作為父裝置。
bus_handle指向介面卡的 i2c 外設的 fwnode 控制代碼,或 NULL。
num_aliases此介面卡的私有別名池中的別名數量。如果此介面卡使用 ATR 的全域性別名池,則設定為零。
aliases介面卡使用的私有別名的可選陣列,而不是 ATR 的全域性別名池。如果 num_aliases > 0,則必須包含確切的 num_aliases 條目,否則將被忽略。
-
struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev, const struct i2c_atr_ops *ops, int max_adapters, u32 flags)¶
分配和初始化 I2C ATR 助手。
引數
struct i2c_adapter *parent父(上游)介面卡
struct device *dev充當 ATR 的裝置
const struct i2c_atr_ops *ops特定於驅動程式的回撥
int max_adapters子介面卡的最大數量
u32 flagsATR 的標誌
描述
新的 ATR 助手連線到父介面卡,但沒有子介面卡。 呼叫 i2c_atr_add_adapter() 新增一些。
呼叫 i2c_atr_delete() 刪除。
返回
指向新 ATR 助手物件的指標,或 ERR_PTR
-
void i2c_atr_delete(struct i2c_atr *atr)¶
刪除 I2C ATR 助手。
引數
struct i2c_atr *atr要刪除的 I2C ATR 助手。
描述
前提條件:所有使用 i2c_atr_add_adapter() 新增的介面卡必須透過呼叫 i2c_atr_del_adapter() 來刪除。
-
int i2c_atr_add_adapter(struct i2c_atr *atr, struct i2c_atr_adap_desc *desc)¶
建立子(“下游”)I2C 匯流排。
引數
struct i2c_atr *atrI2C ATR
struct i2c_atr_adap_desc *descATR 介面卡描述符
描述
呼叫此函式後,將出現一條新的 i2c 匯流排。 在下游總線上新增和刪除裝置將導致呼叫 i2c_atr_ops->attach_client 和 i2c_atr_ops->detach_client 回撥,供驅動程式為裝置分配別名。
介面卡的 fwnode 設定為 bus_handle,或者如果 bus_handle 為 NULL,則該函式會在 i2c-atr 裝置的“i2c-atr”節點下查詢其 ‘reg’ 屬性與 chan_id 匹配的子節點。
呼叫 i2c_atr_del_adapter() 刪除介面卡。
返回
成功時為 0,否則為負錯誤程式碼。
-
void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id)¶
刪除
i2c_atr_add_adapter()新增的子(“下游”)I2C 匯流排。 如果沒有新增 I2C 匯流排,則此函式不執行任何操作。
引數
struct i2c_atr *atrI2C ATR
u32 chan_id要刪除的介面卡的索引(0 .. max_adapters-1)
-
void i2c_atr_set_driver_data(struct i2c_atr *atr, void *data)¶
將私有驅動程式資料設定為 i2c-atr 例項。
引數
struct i2c_atr *atrI2C ATR
void *data指向要儲存的資料的指標
-
void *i2c_atr_get_driver_data(struct i2c_atr *atr)¶
獲取儲存的驅動程式資料。
引數
struct i2c_atr *atrI2C ATR
返回
指向儲存資料的指標