Regulator模塊用於控制系統中某些設備的電壓/電流供應。在嵌入式系統(尤其是手機)中,控制耗電量很重要,直接影響到電池的續航時間。所以,如果系統中某一個模塊暫時不需要使用,就可以通過regulator關閉其電源供應;或者降低提供給該模塊的電壓、電流大小。
Regulator的文檔在KERNEL/Documentation/Power/Regulator中。
2、幾個重要結構:
regulator_dev
regulator_dev代表一個regulator設備。
struct regulator_dev {
struct regulator_desc *desc; // 描述符,包括regulator的名稱、ID、regulator_ops等
int use_count; // 使用計數
/* lists we belong to */
struct list_head list; // regulator通過此結構掛到regulator_list鏈表中
struct list_head slist; // 如果有父regulator,通過此域掛到父regulator的鏈表
/* lists we own */
struct list_head consumer_list; // 此regulator負責供電的設備列表
struct list_head supply_list; //此regulator負責供電的子regulator
struct blocking_notifier_head notifier; // notifier,具體的值在consumer.h中,比如REGULATOR_EVENT_FAIL
struct mutex mutex;
struct module *owner;
struct device dev; // device結構,屬於class regulator_class
struct regulation_constraints *constraints; // 限制,比如最大電壓/電流、最小電壓/電流
struct regulator_dev *supply; // 父regulator的指針
void *reg_data; /* regulator_dev data */
};
regulator_init_data
regulator_init_data在初始化時使用,用來建立父子regulator、受電模塊之間的樹狀結構,以及一些regulator的基本參數。
struct regulator_init_data {
struct device *supply_regulator_dev; // 父regulator的指針
struct regulation_constraints constraints;
int num_consumer_supplies;
struct regulator_consumer_supply *consumer_supplies; // 負責供電的設備數組
/* optional regulator machine specific init */
int (*regulator_init)(void *driver_data); // 初始化函數
void *driver_data; /* core does not touch this */
};
其它結構體自己可以看看~如
struct regulator -------> 設備驅動直接操作的結構體
struct regulation_constraints ----->regulator限制範圍,其它信息,在於
struct regulator_init_data,用於初始化
struct regulator_consumer_supply ----->consumer信息
struct regulator_desc ----->這個多關注些,內有正真操作設備函數結構體~
struct regulator_map ----->這個爲consumers與regulator對應表
通常情況下,我們要在板級文件中fill一些結構,如struct regulator_init_data,這個在regulator初始化時必調用的;還有一般情況下電源管理PMU都是I2C設備,所以struct regulator_init_data經常作爲I2C的私有數據來傳遞;另外由於一個PMU模塊控制不只一個模塊的電壓,通常都是多個,所以需要多個struct regulator_init_data結構,並且通常定義成struct regulator_init_data xxxx[]數組結構,並調用platform_device_add()來註冊設備(struct regulator_init_data結構作爲struct platform_device中的struct devices中的platformdata)。
regulator_desc
struct regulator_described{
const char* name;
int id;
unsigned n_voltages;
struct regulator_ops *ops;
int irq;
enum regulator_type type;
struct module *owner;
}
3、註冊regulator
板級信息和regulator_desc準備好之後就要註冊了。
通過regulator_register函數登記生成一個regulator_dev。
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct device *dev, struct regulator_init_data *init_data,void *driver_data)
{
struct regulator_dev *rdev;
....
//fill struct regulator_dev結構;
device_register(&rdev->dev); // 註冊設備
// 設置constraints,其中可能會包括供電狀態的初始化(設置初始電壓,enable/disable等等)
set_machine_constraints(rdev, &init_data->constraints);
add_regulator_attributes (rdev);
// 設置此regulator與其負責供電的設備之間的聯繫
for (i = 0; i < init_data->num_consumer_supplies; i++)
ret = set_consumer_device_supply(rdev, init_data->consumer_supplies[i].dev,
init_data->consumer_supplies[i].supply);
// 將regulator加入一個鏈表,該鏈表包含所有regulator
list_add(&rdev->list, ®ulator_list);
.......
}
set_consumer_device_supply函數用於登記regulator_dev與comsumer_dev(regulator負責供電的設備)之間的對應關係。對於每一個regulator_dev—comsumer_dev的配對,都會有一個regulator_map結構,這些結構會被加入到全局鏈表regulator_map_list中。
4、regulator應用
在設備驅動使用regulator對其驅動的設備供電時,需要首先保證設備與對應regulator之間的匹配關係已經被登記到regulator框架中。
設備驅動通過regulator_get函數得到regulator結構,此函數通過前文所述regulator_map_list找到對應regulator_dev,再生成regulator結構給用戶使用。
通過regulator_enable / regulator_disable打開、關閉regulator,這兩個函數最終都是調用struct regulator_ops裏的對應成員。
除此之外,還有regualtor_set_voltage / regulator_get_voltage等等。
具體代碼查看:/kernel/driver/regulator/core.c
以下文字來自:http://www.ednchina.com/ART_50292_28_0_AN_0573b455_2.HTM
1 校準器的基本概念
所謂校準器實際是在軟件控制下把輸入的電源調節精心輸出。例如電壓的控制,輸入時5V 輸出是1.8V;電流的限制,最大20mA;簡單的切換和電源的開關等,如圖1所示。
圖1 校準器
電源域是一組校準器,設備組成、輸入可能是校準器,開關也許是電源域,電源域可以級聯,電源約束可以和電源域配合以保護硬件。例如一個Internet Tablet/PMP,它由CPU、NOR Flash、音頻編解碼器、觸摸屏、LCD控制器、USB、WiFi 等其他外設組成,如圖2所示。
圖2 Internet Tablet/PMP系統結構
爲了實現上面的構想,需要在內核裏建立一個校準器構架,目的就是設計一個可以控制電壓和電流的標準內核接口以節省電能,從而儘可能的延長電池的供應。這個內核的架構分爲四個部分:針對設備驅動的消費接口(consumer)、校準器驅動的接口、系統配置的接口和麪嚮應用sysfs的userspace接口。
2 Consumer的API
regulator = regulator_get(dev, “Vcc”);
其中,dev 是設備“Vcc”一個字符串代表,校準器(regulator)然後返回一個指針,也是regulator_put(regulator)使用的。
打開和關閉校準器(regulator)API如下。
int regulator_enable(regulator);
int regulator_disable(regulator);
3 電壓的API
消費者可以申請提供給它們的電壓,如下所示。
int regulator_set_voltage(regulator, int min_uV, int max_uV);
在改變電壓前要檢查約束,如下所示。
regulator_set_voltage(regulator,100000,150000)
電壓值下面的設置改變如下所示。
int regulator_get_voltage)struct regulator *regulator);
4 電流的API
電流的API也是類似,需要指出的是,校準器的方法並不一定是最高的效率,效率和加載(如加載10mA電流)、操作模式都有關係,通過下面的API可以改變模式設置。
regulator_set_optimum_mode(requlator,10000);//10mA
5 校準器的驅動和系統配置
在實際使用校準器之前,需要按照下面的結構寫校準器的驅動程序,然後註冊後通知給消費者使用。
完成了校準器驅動程序之後,下一步就是系統設置(machine specific),即匹配如電壓、LDO1和NAND等關係。
regulator_set_supply(“LDO1”,dev, “Vcc”)
對於userspace,校準器的使用是通過sysfs,但是目前所有的包括電壓、電流、操作模式、限制等信息多隻是隻讀信息,應該是非常適合象powerTop這樣工具的使用。
6 應用
校準器的典型的應用包括如下:CPUfreq——CPU頻率的調節;CPU idle——CPU空閒模式控制;LCD背光調節——通過電流控制LED燈的亮度達到控制LCD背光的目的;音頻單元——如FM收音機在MP3使用的時候應該是關閉的,麥克風使用的時候,揚聲器的放大器應該是關閉的;NAND/NOR存儲器是耗電大戶,根據不同操作方式(讀/寫、擦除等)優化操作模式(控制電流)達到節省電量的要求。同其他電源管理的方法比較,校準器方法具有一定的硬件獨立和抽象性,簡單實用,原理上可以適合任何有電源管理芯片支持嵌入式系統電源管理,目前已經移植到Freescale MC13783、Wolfson WM8350/8400等幾個集成度很高的電源管理器件上了.
基於構件的面向CPU的電源管理技術
無論是PM_QoS、控制電壓和電流的校準器方法,還是許許多多半導體公司支持自己CPU和電源管理芯片的Linux BSP電源管理部分,都還沒有一個構建在更高層面的構件級嵌入式系統電源解決方案和商業產品。雖然包括CELF(消費和嵌入式Linux 論壇)和Intel主導的Mobile &Internet Linux項目都設立了專門的電源管理計劃(power manager project),但是顯然距離人們的要求和實際的應用還太遠了。
Montavista在過去和IBM合作開發DPM(動態電源管理)技術的基礎上,最近在專門針對手機、互聯網移動終端、PMP/PDN等便攜消費電子設備的mobilinux5.0上提出嵌入式電源管理技術的構件方法。Montavista的構件方式主要是針對以先進的多媒體應用處理器爲核心的新一代嵌入式系統,比如Freescale的MX31、TI OMAP2430/3430爲核心的系統級電源管理,它包含下面幾個主要的部分。