穩壓器消費者驅動介面

本文件描述了消費者裝置驅動程式的穩壓器介面。 有關本文件中使用的術語的描述,請參閱Linux 電壓和電流穩壓器框架

1. 消費者穩壓器訪問(靜態和動態驅動)

消費者驅動程式可以透過呼叫以下方式訪問其電源穩壓器

regulator = regulator_get(dev, "Vcc");

消費者傳入其struct device指標和電源ID。 然後,核心透過查閱機器特定的查詢表來找到正確的穩壓器。 如果查詢成功,則此呼叫將返回指向為該消費者供電的struct regulator的指標。

要釋放穩壓器,消費者驅動程式應呼叫

regulator_put(regulator);

消費者可以由多個穩壓器供電,例如,具有模擬和數字電源的編解碼器消費者

digital = regulator_get(dev, "Vcc");  /* digital core */
analog = regulator_get(dev, "Avdd");  /* analog */

穩壓器訪問函式regulator_get()regulator_put()通常會在您的裝置驅動程式的probe()和remove()中分別呼叫。

2. 穩壓器輸出使能和停用(靜態和動態驅動)

消費者可以透過呼叫以下方式啟用其電源

int regulator_enable(regulator);
注意

在呼叫regulator_enable()之前,電源可能已經被啟用。 如果消費者共享穩壓器,或者穩壓器先前已由引導載入程式或核心板初始化程式碼啟用,則可能會發生這種情況。

消費者可以透過呼叫以下方式確定穩壓器是否已啟用

int regulator_is_enabled(regulator);

當穩壓器啟用時,這將返回>零。

當不再需要時,消費者可以透過呼叫以下方式停用其電源

int regulator_disable(regulator);
注意

如果它與其他消費者共享,則這可能不會停用電源。 只有在啟用引用計數為零時,穩壓器才會被停用。

最後,在緊急情況下,可以強制停用穩壓器

int regulator_force_disable(regulator);
注意

這將立即並強制關閉穩壓器輸出。 所有消費者都將被斷電。

3. 穩壓器電壓控制和狀態(動態驅動)

一些消費者驅動程式需要能夠動態更改其電源電壓以匹配系統執行點。 例如,CPUfreq驅動程式可以根據頻率縮放電壓以節省功率,SD驅動程式可能需要選擇正確的卡電壓等。

消費者可以透過呼叫以下方式控制其電源電壓

int regulator_set_voltage(regulator, min_uV, max_uV);

其中min_uV和max_uV是以微伏為單位的最小和最大可接受電壓。

注意:這可以在啟用或停用穩壓器時呼叫。 如果在啟用時呼叫,則電壓會立即改變,否則電壓配置會改變,並且電壓會在下次啟用穩壓器時物理設定。

可以透過呼叫以下方式找到穩壓器配置的電壓輸出

int regulator_get_voltage(regulator);
注意

get_voltage()將返回配置的輸出電壓,無論穩壓器是啟用還是停用,並且不應用於確定穩壓器輸出狀態。 但是,它可以與is_enabled()結合使用以確定穩壓器物理輸出電壓。

4. 穩壓器電流限制控制和狀態(動態驅動)

一些消費者驅動程式需要能夠動態更改其電源電流限制以匹配系統執行點。 例如,LCD背光碟機動程式可以更改電流限制以改變背光亮度,USB驅動程式可能希望在供電時將限制設定為500mA。

消費者可以透過呼叫以下方式控制其電源電流限制

int regulator_set_current_limit(regulator, min_uA, max_uA);

其中min_uA和max_uA是以微安為單位的最小和最大可接受電流限制。

注意

這可以在啟用或停用穩壓器時呼叫。 如果在啟用時呼叫,則電流限制會立即改變,否則電流限制配置會改變,並且電流限制會在下次啟用穩壓器時物理設定。

可以透過呼叫以下方式找到穩壓器電流限制

int regulator_get_current_limit(regulator);
注意

get_current_limit()將返回電流限制,無論穩壓器是啟用還是停用,並且不應用於確定穩壓器電流負載。

5. 穩壓器執行模式控制和狀態(動態驅動)

一些消費者可以透過更改其電源穩壓器的執行模式來進一步節省系統功耗,以便在消費者執行狀態改變時更有效。 例如,消費者驅動程式空閒並且隨後消耗更少的電流

穩壓器執行模式可以間接或直接更改。

間接執行模式控制。

消費者驅動程式可以透過呼叫以下方式請求更改其電源穩壓器執行模式

int regulator_set_load(struct regulator *regulator, int load_uA);

這將導致核心重新計算穩壓器上的總負載(基於其所有消費者),並更改執行模式(如果必要和允許)以最佳匹配當前執行負載。

load_uA值可以從消費者的資料表中確定。 例如,大多數資料表都有表格顯示在某些情況下消耗的最大電流。

大多數消費者將使用間接執行模式控制,因為他們不瞭解穩壓器或穩壓器是否與其他消費者共享。

直接執行模式控制。

定製或緊密耦合的驅動程式可能希望根據其執行點直接控制穩壓器執行模式。 這可以透過呼叫以下方式實現

int regulator_set_mode(struct regulator *regulator, unsigned int mode);
unsigned int regulator_get_mode(struct regulator *regulator);

只有 *知道* 穩壓器且不與其他消費者共享穩壓器的消費者才會使用直接模式。

6. 穩壓器事件

穩壓器可以通知消費者外部事件。 消費者可能會在穩壓器壓力或故障情況下收到事件。

消費者可以透過呼叫以下方式註冊對穩壓器事件的興趣

int regulator_register_notifier(struct regulator *regulator,
                                struct notifier_block *nb);

消費者可以透過呼叫以下方式取消註冊興趣

int regulator_unregister_notifier(struct regulator *regulator,
                                  struct notifier_block *nb);

穩壓器使用核心通知程式框架將事件傳送給他們感興趣的消費者。

7. 穩壓器直接暫存器訪問

某些型別的電源管理硬體或韌體的設計方式使得它們需要對穩壓器進行低階硬體訪問,而無需核心的參與。 此類裝置的示例有

  • 具有壓控振盪器的時鐘源和控制邏輯,可以透過I2C改變電源電壓以實現所需的輸出時鐘頻率

  • 可以在過溫條件下發出任意I2C事務以執行系統斷電的熱管理韌體

要設定此類裝置/韌體,需要為其配置各種引數,例如穩壓器的I2C地址、各種穩壓器暫存器的地址等。 穩壓器框架提供了以下輔助函式來查詢這些詳細資訊。

特定於匯流排的詳細資訊,例如I2C地址或傳輸速率由regmap框架處理。 要獲取穩壓器的regmap(如果支援),請使用

struct regmap *regulator_get_regmap(struct regulator *regulator);

要獲取穩壓器電壓選擇器暫存器的硬體暫存器偏移量和位掩碼,請使用

int regulator_get_hardware_vsel_register(struct regulator *regulator,
                                         unsigned *vsel_reg,
                                         unsigned *vsel_mask);

要將穩壓器框架電壓選擇器程式碼(由regulator_list_voltage使用)轉換為可以直接寫入電壓選擇器暫存器的特定於硬體的電壓選擇器,請使用

int regulator_list_hardware_vsel(struct regulator *regulator,
                                 unsigned selector);

要訪問用於啟用/停用穩壓器的硬體,消費者必須使用regulator_get_exclusive(),因為如果存在多個消費者則無法工作。 要啟用/停用穩壓器,請使用

int regulator_hardware_enable(struct regulator *regulator, bool enable);