一、Documentation\power\regulator\overview.txt
1.命名規則
(1) Regulator - 為其他設備供電的電子設備。大多數調節器可以啟用和禁用其輸出,而某些調節器可以控制其輸出電壓和/或電流。
Input Voltage -> Regulator -> Output Voltage
(2) PMIC - 電源管理IC。一個pmic里面包含大量regulator且通常包含其他子系統的IC。
(3) Consumer -由調節器供電的電子設備,Consumers可分為兩類:
靜態:消費者不更改其電源電壓或電流限制。它只需要啟用或禁用電源即可。它的電源電壓由硬件,啟動程序,固件或內核板初始化代碼設置。
動態:消費者需要更改其電源電壓或電流限制,以滿足操作需求。
(4) Power Domain - 由調節器、開關或其他電源域的輸出功率提供其輸入功率的電子電路。電源調節器可能在開關后面。即:
Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A] | | | +-> [Consumer B], [Consumer C] | +-> [Consumer D], [Consumer E]
這是一個調節器和三個電源域:
域1:Switch-1,消費者D和E。
域2:Switch-2,消費者B和C。
域3:消費者A。
這表示一種“供應”關系:
Domain-1 --> Domain-2 --> Domain-3.
電源域可能具有由其他調節器供電的調節器。即:
Regulator-1 -+-> Regulator-2 -+-> [Consumer A] | +-> [Consumer B]
這為我們提供了兩個調節器和兩個電源域:
Domain 1: Regulator-2, Consumer B.
Domain 2: Consumer A.
和“供應”關系:
Domain-1 --> Domain-2
(5) Constraints - 約束用於定義功耗性能和硬件保護的功率級別。 約束存在三個層次:
a. 調節器級別:這由調節器硬件操作參數定義,並在調節器數據表中指定。 即:
-電壓輸出范圍為800mV-> 3500mV。
-電流輸出限制為20mA@5V,但為10mA@10V。
b. 電源域級別:這是在軟件中由內核級板初始化代碼定義的。 它用於將電源域限制為特定的范圍內。即:
-域1電壓為3300mV
-域2電壓為1400mV->1600mV
-域3的電流限制為0mA->20mA。
c. 消費者級別:由Consumer的驅動程序動態設置電壓或電流的限制水平的定義。
例如,消費者背光驅動器要求電流從5mA增加到10mA以增加LCD照明,通過以下級別:
消費者:需要增加LCD的亮度。在亮度表中查找並請求下一個電流mA值(基於相同的參考設備,用戶驅動程序可以用於幾種不同的方式)。
電源域:是對此域和系統狀態(例如電池電源,USB電源)進行限制的一種新的電流限制方式。
調節器域:是在調節器工作參數中調節輸入/輸出電壓的一種新的電流限制方式。
如果對調節器的請求通過了所有約束測試,則將應用新的調節器值。
2. 設計
該框架旨在針對基於SoC的設備而設計的,但也可能與非SoC設備相關,並且分為以下四個接口:
(1) 消費者驅動接口(Consumer driver interface)。
這使用了與內核時鍾接口類似的API,因為消費者驅動程序可以獲取和釋放一個調節器(就像使用atm時鍾一樣)並獲取/設置電壓電流限制,模式,啟用和禁用。 這應該使消費者驅動能夠完全控制其電源電壓和電流限制。 如果不使用,這也可以不編譯進去,因此驅動程序可以在不基於調節器的電源控制的系統中重用。
請看 Documentation/power/regulator/consumer.txt
(2) 調節器驅動程序接口(Regulator driver interface)。
這使調節器驅動程序可以注冊其調節器並向內核提供操作。 它還具有一個通知鏈,用於將調節事件傳播給客戶(clients)。
請看 Documentation/power/regulator/regulator.txt
(3) 機器接口(Machine interface)
該接口特定用於機器的代碼,並允許為每個調節器創建電壓/電流域(帶有約束)。它可以提供調節器約束,以防止由於錯誤的客戶端驅動器引起的過電壓或過電流而損壞設備。它還允許創建一個調節器樹,其中一些調節器由其他調節器供電(類似於時鍾樹)。
請看 /power/regulator/machine.txt
(4) 用戶空間ABI。
該框架還通過sysfs將大量有用的電壓/電流/opmode數據導出到用戶空間。 這可用於幫助監視設備的功耗和狀態。
請看 Documentation/ABI/testing/sysfs-class-regulator
二、Documentation\power\regulator\consumer.txt
穩壓器消費者驅動程序接口
==================================
本文介紹了消費類設備驅動程序的調節器接口。請參閱overview.txt以獲取本文中所用術語的描述。
1.消費者驅動獲取調節器(靜態和動態驅動程序)
=======================================================
(1) 消費者驅動程序可以通過以下方式訪問為其供電的調節器:
regulator = regulator_get(dev, "Vcc"); //Vcc-supply = <&XXX>
使用者傳遞其dev結構設備指針和supplyID。 然后,內核通過查詢機器特定的查找表來找到正確的調節器。如果查找成功,則此調用將返回一個指針,該指針指向此使用者的調節器結構。
(2) 要釋放調節器,消費者驅動程序可以調用:
regulator_put(regulator);
消費者可能存在同時由多個調節器供電的情況,例如,具有需要進行模擬供電和數字供電的編解碼器:
digital = regulator_get(dev, "Vcc"); /* digital core */ analog = regulator_get(dev, "Avdd"); /* analog */
通常在消費者驅動的probe()中調用regulator_get(),在消費者驅動的remove()中調用regulator_put()。
2.調節器輸出的使能和禁止(靜態和動態驅動)
=======================================================
(1) 消費者可以通過以下方式啟用電源:
int regulator_enable(regulator);
注意:在調用regulator_enabled()之前,電源可能已經啟用。如果使用者共享調節器,或者先前已通過引導加載程序或內核板初始化代碼啟用了調節器,則可能會發生這種情況。
(2) 消費者驅動可以通過以下方式確定是否已經使能了調節器:
int regulator_is_enabled(regulator); //若調節器是使能的,返回0
(3) 消費者驅動可以通過以下方式禁用不再需要的電源:
int regulator_disable(regulator);
注意:如果與其他使用者共享電源,則可能不會禁用電源。僅當啟用的引用計數為零時,才會真正禁用此調節器。
(4) 在緊急情況下,可以強制禁用調節器:
int regulator_force_disable(regulator);
注意:這將立即強制關閉調節器輸出。所有使用此調節器的消費者都會下電。
3.調節器的電壓控制和狀態(動態驅動)
======================================================
一些消費者驅動程序需要能夠動態更改其電源電壓以匹配系統工作狀態。例如CPUfreq驅動程序可以隨頻率縮放電壓以節省功耗,SD驅動程序可能需要選擇正確的卡電壓等。
(1) 消費者驅動可以通過以下方式控制其電源電壓:
int regulator_set_voltage(regulator, min_uV, max_uV); //其中min_uV和max_uV是可接受的最小和最大電壓,以微伏為單位。
注意:可以在啟用或禁用調節器時調用此函數。如果在啟用時調用,則電壓會立即改變,否則電壓配置會改變,並且在下次使能調節器時會實際設置電壓。
(2) 調節器配置的電壓輸出值可通過以下方法查到:
int regulator_get_voltage(regulator);
注意:無論是啟用還是禁用調節器的狀態,get_voltage()都將返回配置的輸出電壓,因此不應將其用於確定調節器的輸出狀態。但是,可以將其與is_enabled()結合使用以確定調節器的物理輸出電壓。
4.調節器電流限制控制和狀態(動態驅動)
======================================================
一些消費者驅動程序需要能夠動態更改其電源電流限制以匹配系統工作狀態。例如LCD背光驅動器可以更改電流限制以改變背光亮度,USB驅動器可能需要在供電時將限制設置為500mA。
(1) 消費者可以通過以下方式控制其電源電流限制:
int regulator_set_current_limit(regulator, min_uA, max_uA); //其中min_uA和max_uA是微安的最小和最大可接受電流限制。
注意:在啟用或禁用調節器的狀態下都可以調用此函數。如果在啟用時調用,則電流限制會立即生效,否則電流限制配置會更改,並且在下次啟用調節器時會實際設置電流限制。
(3) 可以通過以下方法查詢調節器的電流限制:
int regulator_get_current_limit(regulator);
注意:無論是啟用還是禁用調節器的狀態,get_current_limit()都將返回電流限制,因此不應將其用於確定調節器實際電流值。
5. 調節器操作模式控制和狀態(動態驅動器)
======================================================
一些使用者可以通過更改其電源調節器的工作模式來進一步節省系統功率,從而在使用者工作狀態發生變化時更加高效。 例如 消費者驅動程序處於空閑狀態,因此消耗的電流更少
調節器的運行模式可以間接或直接更改。
(1) 間接操作模式控制。
--------------------------------
消費者驅動可以通過調用這個函數更改其供應調節器的運行模式
int regulator_set_load(struct regulator *regulator, int load_uA);
這將導致內核重新計算調節器上的總負載(基於其所有consumers),並更改運行模式(如果需要並允許)以最佳地匹配當前的運行負載。
可以從consumer的數據表中確定load_uA值。 例如 大多數數據手冊都有表格顯示某些情況下的最大消耗電流。
大多數消費者將使用間接操作模式控制,因為他們不了解調節器或調節器是否與其他消費者共享。
(2) 直接操作模式控制。
------------------------------
定制或緊密耦合的驅動器可能希望根據其工作點直接控制調節器的工作模式。 這可以通過調用這個函數實現:
int regulator_set_mode(struct regulator *regulator, unsigned int mode); unsigned int regulator_get_mode(struct regulator *regulator);
直接模式將僅由“了解”調節器並且不與其他使用者共享調節器的使用者使用。
6.調節器事件
===================
Regulators可以將外部事件通知消費者。 消費者可以在調節器壓力或故障條件下接收事件。
消費者可以通過以下方式注冊對調節器事件的監聽:
int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb);
消費者可以通過以下方式取消對調節器事件的監聽:
int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb);
調機器使用內核通知鏈框架將事件發送給感興趣的使用者(Consumers)。
7. Regulator直接寄存器訪問
==================================
某些電源管理硬件或固件經過設計,因此它們需要對調節器進行低級硬件訪問,而無需內核參與。 此類設備的示例是:
-具有壓控振盪器和控制邏輯的時鍾源,用於改變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);
三、Documentation\power\regulator\regulator.txt
調節器驅動程序接口
=========================
調節器驅動程序界面相對簡單,旨在允許調節器驅動程序在核心框架中注冊其服務。
1.注冊
============
驅動可以通過以下方式注冊一個regulator:
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, const struct regulator_config *config);
這會將調節器的功能和操作注冊到調節器核心。
2. 可以通過以下方式取消調節器的注冊:
void regulator_unregister(struct regulator_dev *rdev);
3. 調節器事件
================
調節器可以通過以下方式將事件(例如,過熱,欠壓等)發送給消費者驅動器:
int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data);
四、Documentation\power\regulator\machine.txt
1. 調節器Machine端驅動程序接口
==================================
調節器Machine驅動程序接口旨在用於主板/機器專用的初始化代碼,以配置調節器子系統。
考慮以下機器:
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] | +-> [Consumer B @ 3.3V]
消費者A和B的驅動必須映射到正確的調節器,以控制其電源。 通過為每個調節器創建一個struct regulator_consumer_supply結構,可以在機器初始化代碼中實現此映射。
struct regulator_consumer_supply { const char *dev_name; /* consumer dev_name() */ const char *supply; /* consumer supply - e.g. "vcc" */ };
例如 對於上面的機器
static struct regulator_consumer_supply regulator1_consumers[] = { REGULATOR_SUPPLY("Vcc", "consumer B"), }; static struct regulator_consumer_supply regulator2_consumers[] = { REGULATOR_SUPPLY("Vcc", "consumer A"), };
這將調節器1映射到消費者B的“Vcc”電源,並將調節器2映射到消費者A的“Vcc”電源。
現在可以通過為每個調節器電源域定義一個struct regulator_init_data 來注冊約束。 這種結構還將消費者映射到他們的供應調節器中:
static struct regulator_init_data regulator1_data = { .constraints = { .name = "Regulator-1", .min_uV = 3300000, .max_uV = 3300000, .valid_modes_mask = REGULATOR_MODE_NORMAL, }, .num_consumer_supplies = ARRAY_SIZE(regulator1_consumers), .consumer_supplies = regulator1_consumers, };
名稱字段應設置為對板有用的描述,用於配置其他調節器的電源以及用於日志記錄和其他診斷輸出。 通常,示意圖中用於供電軌的名稱是一個不錯的選擇。 如果未提供名稱,則子系統將選擇一個。
調節器1為調節器2供電。 此關系必須在內核中注冊,以便在消費者A啟用其電源(Regulator-2)時也啟用Regulator-1。 電源調節器由下面的supply_regulator字段和co設置:
static struct regulator_init_data regulator2_data = { .supply_regulator = "Regulator-1", .constraints = { .min_uV = 1800000, .max_uV = 2000000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, .valid_modes_mask = REGULATOR_MODE_NORMAL, }, .num_consumer_supplies = ARRAY_SIZE(regulator2_consumers), .consumer_supplies = regulator2_consumers, };
最后,必須以常規方式注冊調節器設備。
static struct platform_device regulator_devices[] = { { .name = "regulator", .id = DCDC_1, .dev = { .platform_data = ®ulator1_data, }, }, { .name = "regulator", .id = DCDC_2, .dev = { .platform_data = ®ulator2_data, }, }, }; /* register regulator 1 device */ platform_device_register(®ulator_devices[0]); /* register regulator 2 device */ platform_device_register(®ulator_devices[1]);
五、Documentation\ABI\testing\sysfs-class-regulator
(1) /sys/class/regulator/.../state
一些調節器目錄將包含一個稱為state的字段。 這報告了調節器啟用控制,用於可以報告該輸入值的調節器。
這將是以下字符串之一:
'enabled'
'disabled'
'unknown'
“enabled”表示調節器輸出為ON,並且正在為系統供電(假設沒有錯誤可防止調節器輸出)。
“disabled”表示調節器輸出為OFF,並且不為系統供電(除非某些非Linux控件已啟用它)。
“unknown”表示軟件無法確定狀態,或報告的狀態無效。
注意:此字段可與微伏或微安一起使用,以確定已配置的調節器輸出電平。
(2) /sys/class/regulator/.../status
某些調節器目錄將包含一個稱為“status”的字段。 對於可以報告該輸出值的調節器,此報告當前的調節器狀態。
這將是以下字符串之一:
off
on
error
fast
normal
idle
standby
“off”表示調節器沒有為系統供電。
“on”表示調節器正在為系統供電,並且調節器無法報告詳細的操作模式。
“error”表示失調狀態,例如由於熱關機而被禁用,或者由於輸入電源的問題而導致電壓不穩定。
“fast”,“normal”,“idle”和“standby”都是詳細的調節器操作模式(在其他地方介紹)。 它們暗示“on”,但提供更多細節。
請注意,調節器狀態是許多輸入的函數,而不僅限於Linux的控制輸入。 例如,顯示的實際負載可能會觸發“error”狀態。 或其他用戶可能啟用了調節器,即使Linux沒有啟用它也是如此。
(3) /sys/class/regulator/.../type
每個調節器目錄將包含一個稱為type的字段。 這保存調節器類型。
這將是以下字符串之一:
'voltage'
'current'
'unknown'
“voltage”表示調節器的輸出電壓可以通過軟件控制。
“current”表示調節器輸出電流極限可以通過軟件控制
“unknown”表示軟件無法控制電壓或電流限制。
(4) /sys/class/regulator/.../microvolts
一些調節器目錄將包含一個稱為microvolts(微伏)的字段。 對於可報告電壓控制輸入的調節器,它保持以微伏(即E-6伏)為單位的調節器輸出電壓設置。
注意:該值不應用於確定調節器輸出電壓電平,因為無論調節器是啟用還是禁用,該值都相同。
(5) /sys/class/regulator/.../microamps
一些調節器目錄將包含一個稱為microamps(微安)的字段。 對於可報告電流限制的控制輸入的調節器,這將保持以微安(即E-6安培)為單位的調節器輸出電流限制設置。
注意:此值不應用於確定egulator的輸出電流水平,因為無論調節器是啟用還是禁用,此值都相同。
(6) /sys/class/regulator/.../opmode
一些調節器目錄將包含一個名為opmode的字段。 對於可以報告該控制輸入值的調節器,它保持當前的調節器操作模式。
opmode值可以是以下字符串之一:
'fast'
'normal'
'idle'
'standby'
'unknown'
模式在include/linux/regulator/consumer.h中描述
注意:此值不應用於確定調節器輸出操作模式,因為無論調節器是啟用還是禁用,此值都相同。 “status”屬性可能可用於確定實際模式。
(7) /sys/class/regulator/.../min_microvolts
一些調節器目錄將包含一個名為min_microvolts的字段。 對於支持電壓約束的調節器,此保存該域的最小安全工作調節器輸出電壓設置(以微伏為單位)。
注意:如果電源域沒有平台代碼定義的最小微伏特約束,則它將返回字符串“constraint not defined”。
(8) /sys/class/regulator/.../max_microvolts
一些調節器目錄將包含一個名為max_microvolts的字段。 對於支持電壓限制的調節器,此保持該域的最大安全工作調節器輸出電壓設置(以微伏為單位)。
注意:如果電源域沒有平台代碼定義的最大微伏約束,則將返回字符串“ constraint not defined”。
(9) /sys/class/regulator/.../min_microamps
一些調節器目錄將包含一個名為min_microamps的字段。 對於支持電流限制的調節器,這保持了該域的最小安全工作調節器輸出電流限制設置(以微安為單位)。
注意:如果電源域沒有平台代碼定義的最小微安約束,則它將返回字符串“ constraint not defined”。
(9) /sys/class/regulator/.../max_microamps
一些調節器目錄將包含一個名為max_microamps的字段。 對於支持電流限制的調節器,此保持該域的最大安全工作調節器輸出電流限制設置(以微安為單位)。
注意:如果電源域沒有平台代碼定義的最大微安約束,則它將返回字符串“ constraint not defined”。
(10) /sys/class/regulator/.../name
每個調節器目錄將包含一個名為name的字段。 它包含一個字符串,用於標識用於顯示的調節器。
注意:如果平台或調節器驅動程序未提供合適的名稱,則此字段為空。
(11) /sys/class/regulator/.../num_users
每個調節器目錄將包含一個名為num_users的字段。 這保留了在此調節器上調用了regulator_enable()的消費類設備的數量。
(12) /sys/class/regulator/.../requested_microamps
一些調節器目錄將包含一個名為requested_microamps的字段。 這將保持其所有消費類設備為該穩壓器提供的總要求負載電流(以微安為單位)。
(13) /sys/class/regulator/.../parent
一些調節器目錄將包含一個稱為parent的鏈接。 如果存在,則指向上級或供應regulator。
(14) /sys/class/regulator/.../suspend_mem_microvolts
一些調節器目錄將包含一個名為suspend_mem_microvolts的字段。 當系統掛起至存儲器時,這將保持該域的調節器輸出電壓設置(以微伏為單位),用於實現掛起電壓配置約束的電壓調節器。
(15) /sys/class/regulator/.../suspend_disk_microvolts
一些調節器目錄將包含一個名為suspend_disk_microvolts的字段。 當系統懸掛到磁盤上時,這將保持該域的調節器輸出電壓設置(以微伏為單位),以實現實現suspend電壓配置約束的電壓調節器。
(16) /sys/class/regulator/.../suspend_standby_microvolts
一些調節器目錄將包含一個稱為suspend_standby_microvolts的字段。 當系統掛起到待機狀態時,這將保持該域的調節器輸出電壓設置(以微伏為單位),
用於實現了suspend電壓配置約束的電壓調節器。
(17) /sys/class/regulator/.../suspend_mem_mode
一些調節器目錄將包含一個稱為suspend_mem_mode的字段。 當系統掛起到內存時,這將保留該域的調節器操作模式設置,以用於實現掛起模式配置約束的調節器。
(18) /sys/class/regulator/.../suspend_disk_mode
一些調節器目錄將包含一個稱為suspend_disk_mode的字段。 當系統掛起到磁盤時,這將保留該域的調節器操作模式設置,以用於實現掛起模式配置約束的調節器。
(19) /sys/class/regulator/.../suspend_standby_mode
一些調節器目錄將包含一個稱為suspend_standby_mode的字段。 當系統掛起到standby狀態時,這將保留該域的調節器操作模式設置,以用於實現掛起模式配置約束的調節器。
(20) /sys/class/regulator/.../suspend_mem_state
一些調節器目錄將包含一個稱為suspend_mem_state的字段。 當調節器實施到掛起配置約束時,這將保持調節器在suspend到內存中時的工作狀態。
這將是“ state”屬性報告的相同字符串之一。
(21) /sys/class/regulator/.../suspend_disk_state
一些調節器目錄將包含一個名為suspend_disk_state的字段。 當調節器實施到掛起配置約束時,它會在掛起到磁盤時保持調節器的工作狀態。這將是“ state”屬性報告的相同字符串之一。
(22) /sys/class/regulator/.../suspend_standby_state
一些調節器目錄將包含一個稱為suspend_standby_state的字段。 當調節器實現暫停配置約束時,它會在暫停到待機狀態時保持調節器的工作狀態。這將是“ state”屬性報告的相同字符串之一。
(22) /sys/class/regulator/.../bypass
一些調節器目錄將包含一個稱為bypass(旁路)的字段。 這表明設備是否處於旁路模式。
這將是以下字符串之一:
'enabled'
'disabled'
'unknown'
“enabled”表示調節器處於旁路模式。
“disabled”表示調節器正在監管。
“unknown”表示軟件無法確定狀態,或報告的狀態無效。
五、補充
1.dump /d/regulator下的內容可以看到設備樹中供電配置的差異。