標籤:
轉自:http://blog.csdn.net/batoom/article/details/17081651
1: 校準器的基本概念所謂校準器實際是在軟體控制下把輸入的電源調節精心輸出。
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
linux regulator之淺見【轉】