http://blog.sina.com.cn/s/blog_694348b00100n3ip.html
regulator是驱动中电源管理的基础设施。要先注册到内核中,然后使用这些电压输出的模块get其regulator,在驱动中的init里,在适当时间中进行电压电流的设置.
Linux内核的动态电压和电流控制接口
"LDO是low dropout regulator,意为低压差线性稳压器",是相对于传统的线性稳压器来说的。传统的线性稳压器,如78xx系列的芯片都要求输入电压要比输出电压高出 2v~3V以上,否则就不能正常工作。但是在一些情况下,这样的条件显然是太苛刻了,如5v转3.3v,输入与输出的压差只有1.7v,显然是不满足条件的。针对这种情况,才有了LDO类的电源转换芯片。生产LDO芯片的公司很多,常见的有ALPHA, Linear(LT), Micrel, National semiconductor,TI等。
in:twl4030-poweroff.c
一种称为校准器(regulator)的动态电压和电流控制的方法,很有参考意义和实际使用价值。
1:校准器的基本概念
所谓校准器实际是在软件控制下把输入的电源调节精心输出。
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:校准器的驱动和系统配置
在实际使用校准器之前,需要按照下面的结构写校准器的驱动程序,然后注册后通知给消费者使用。
//
static LIST_HEAD(regulator_list); //整个regulator模型的所有regulator.
static LIST_HEAD(regulator_map_list); //整个regulator模型的map
struct regulator_consumer_supply : 用户支持的接口映射。 supply -> device
struct regulator_state: 用于表示 在整个系统的低功耗状态下的设备状态。
struct regulation_constraints : 操作约束。
struct regulator_init_da ta 校准器平台初始化数据。
struct regulator_dev 向内核注册后得到regulator设备结构
注册:
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,struct device *dev, void *driver_data)
反注册:
要使用注册得到 regulator_dev:
void regulator_unregister(struct regulator_dev *rdev)
#define REGULATOR_MODE_FAST 0x1 //电压可以快速调
#define REGULATOR_MODE_NORMAL 0x2 //一般模式
#define REGULATOR_MODE_IDLE 0x4 //低load
#define REGULATOR_MODE_STANDBY 0x8 //sleep/ standby 状态下 低功耗
例子:
static struct regulator_init_da ta zoom2_vsim = { //这个da ta被置于 对应的 platform_device 的da ta字段中。
};
// regulator 的初始化数据要放到 device 's platform_da ta
struct regulator_init_da ta *init_da ta = dev->platform_da ta;
"重点"
//
struct twlreg_info :关联到驱动与设备的数据。驱动的私有数据,driver_da ta.
struct twlreg_info {
};
//一个驱动(platform_driver)对应所有的regulator, 每个regulator在内核中表示为一个platform_device. 所以调用了许多次的probe
//在probe中,从全局数组中取出自定义的数据结构: twlreg_info, 然后从platform_device中取出初始化数据(device's platform_data),然后就可以向内核注册一个 regulator(会返回一个regulator_dev:类)。
1:每个regulator 的 "twlreg_info" 被 存于 regulator_dev 的 device 's driver_data, twlreg_info中的 table 存支持的电压值。
2:两种操作结构"regulator_ops":twl4030fixed_ops(电压固定), twl4030ldo_ops(电压可调)
3:传入每个 ops中的操作函数 的参数是: regulator_dev.
4: 在 twl4030-core.c中,在添加 twl4030的 i2c_client时,添加了所有的 regulator 的 platform_device.
5: 在驱动初始化注册中,内核会自动去匹配 bus上的所有符合的 platform_device(代表regulator,init_data放于device's platform_data), 所以一个驱动就可以匹配到 bus上所有对应的 regulator.
6: 每匹配一个 regulator的 platform_device时,就会从中,platform_device的 device 中的 platform_data 中得到 regulator的初始化数据: regulator_init_data
7: 取出初始化数据后, 设置一下. "设置,即是当设备支持一定的功能后,由驱动来控制时,要匹配驱动能做到的功能。that is 两者 与(&) 一下"
然后,从regulator模块的全局数组"twl4030_regs[]" 中取出 twlreg_info
8: // regulator_ops 存入了 regulator_desc, 然后注册时,desc 关联到了 regulator_dev-> desc = desc.
生成regualator_dev, 设置数据,注册sysfs,然后: constraints, attribute, supply ,comsumer device.
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct device *dev, void *driver_data)
9:另:
大部分的regulator的platform_device生成如下:
每个regulator设备注册到内核的时机是在 twl4030-core.c 中。
把regulator的初始化数据,放到新生成的platform_device 's device 's platform_da ta...
然后注册 platform_device 到内核中。
usb部分的regulator生成如下:(这里明显是由于OMAP不一定是有USB??,然后在其Board-zoom2.c中,"没有设置每个初始化数据"(包括:supply,constraints(min,max,mask)))
而对于usb模块的 regulator, 先生成对应的platform_device, 返回了platform_device->device, 然后利用这个device去形成多个: regulator_consumer_supply.dev = device.
然后用这些 regulator_consumer_supply, 来做comsumer并生成 platform_device.注册
//
regulator已经向内核模型注册了,但如何使用呢,怎样调节电压??
//注册后,内核中就已经有对应的regulator对应的 supply consumer. 然后在驱动中任何地方调用接口即可:
//regulator_get, regulator_enable, regulator_disable, regulator_set_voltage, regulator_get_voltage......
1:在twl4030-usb模块中,会用到 usb对应的 reuglator,, fixed_ops
2:
regulator = regulator_get(dev, “Vcc”);
其中,dev 是设备“Vcc”一个字符串代表,校准器(regulator)然后返回一个指针,也是regulator_put(regulator)使用的。
打开和关闭校准器(regulator)API如下。
int regulator_enable(regulator);
int regulator_disable(regulator);
消费者可以申请提供给它们的电压,如下所示。
int regulator_set_voltage(regulator, int min_uV, int max_uV);
在改变电压前要检查约束,如下所示。
regulator_set_voltage(regulator,100000,150000)
//
struct regulator_desc {
};
enum regulator_status {
};
struct regulator_dev {
};
struct regulator {
};
struct regulator_map {
};
struct regulator_state {
};
struct regulation_constraints {
};
struct regulator_consumer_supply {
};
struct regulator_desc {
};
struct regulator_init_da ta {
};
#define REGULATOR_CHANGE_VOLTAGE 0x1
#define REGULATOR_CHANGE_CURRENT 0x2
#define REGULATOR_CHANGE_MODE 0x4
#define REGULATOR_CHANGE_STATUS 0x8
#define REGULATOR_CHANGE_DRMS 0x10
#define REGULATOR_MODE_FAST 0x1
#define REGULATOR_MODE_NORMAL 0x2
#define REGULATOR_MODE_IDLE 0x4
#define REGULATOR_MODE_STANDBY 0x8