linux regulator之浅见
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
还没有评论,来说两句吧...