沉淀、分享、成长,让自己和他人都能有所收获!😄
📢 要简单介绍下系统的Regulator Framework
。
Regulator
翻译为”调节器”,分为电压调节器(voltage regulator
)和电流调节器(current regulator
),是电源管理的底层基础设施之一,在内核中regulator
实际是个抽象出来的概念。
在linux
中regulator Framework
框架设计,控制系统中某些设备的电压/电流供应,并且在系统运行的过程中,动态改变regulators
的输出,以达到省电的目的。 该Regulator
框架为各种使用电源的设备(consumer
)提供统一接口,允许获取电压,限制电压,使能和关闭电源等操作,也提供了Regulator
驱动接口, 允许注册电源提供者(provider
)并向内核提供操作函数等。
Linux Regulator Framework
整体分为四个部分,分别是machine
(regulator
硬件制约,映射关系等),regulator
(理解为regulator driver
), consumer
(regulator
的使用者,服务对象),sys-class-regulator
(用户空间接口)。
Regulator驱动主要是电源提供者(provider)注册和通过相关操作函数,电源提供者(provider)是PMIC等。下面介绍下注册接口函数和数据结构:
struct regulator_desc结构体用来描述一个独立的PMIC提供的每个调节器,一个静态描述。
struct regulator_desc {
const char *name;
const char *supply_name;
const char *of_match;
const char *regulators_node;
/*..................*/
int id;
unsigned n_voltages;
const struct regulator_ops *ops;
int irq;
enum regulator_type type;
struct module *owner;
unsigned int min_uV;
unsigned int uV_step;
unsigned int ramp_delay;
/*..................*/
};
上面结构体有省略,详细请看内核源码/include/linux/regulator/driver.h,有详细的注释。
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
const struct regulator_config *config);
void regulator_unregister(struct regulator_dev *rdev);
regulator_register函数是注册regulator的接口,传入regulator_desc和regulator_config两个结构体参数,regulator_desc描述regulator以及相关操作函数, regulator_config主要包含一些调节器描述的可变元素和一些约束,一种安全限制等。返回一个regulator_dev结构体,该结构体是一个抽象的描述对regulator,如下(有省略):
struct regulator_dev {
const struct regulator_desc *desc;
int exclusive;
u32 use_count;
u32 open_count;
u32 bypass_count;
/* lists we belong to */
struct list_head list; /* list of all regulators */
/* lists we own */
struct list_head consumer_list; /* consumers we supply */
struct coupling_desc coupling_desc;
struct blocking_notifier_head notifier;
struct mutex mutex; /* consumer lock */
struct task_struct *mutex_owner;
int ref_cnt;
struct module *owner;
struct device dev;
struct regulation_constraints *constraints;
struct regulator *supply; /* for tree */
const char *supply_name;
struct regmap *regmap;
struct delayed_work disable_work;
int deferred_disables;
void *reg_data; /* regulator_dev data */
/*..................*/
};
struct regulation_constraints {
const char *name;
/*电压输出范围 */
int min_uV;
int max_uV;
int uV_offset;
/* 电流输出范围 */
int min_uA;
int max_uA;
int ilim_uA;
int system_load;
/* used for coupled regulators */
int max_spread;
/* 标志对这个regulator有效的操作模式*/
unsigned int valid_modes_mask;
/* regulator有效的操作 */
unsigned int valid_ops_mask;
/* regulator input voltage - only if supply is another regulator */
int input_uV;
/*.......................*/
/* 约束标志位 */
unsigned always_on:1; /* 当系统开启时,regulator不会关闭 */
unsigned boot_on:1; /* bootloader/firmware enabled regulator */
unsigned apply_uV:1; /* 当电压最大值等于最小值,使能约束,是固定的电压*/
unsigned ramp_disable:1; /* disable ramp delay */
unsigned soft_start:1; /* ramp voltage slowly */
unsigned pull_down:1; /* pull down resistor when regulator off */
unsigned over_current_protection:1; /* auto disable on over current */
}
该结构体是一个安全限制,比如是电压调节器,限制了电压的输出范围等,这些一般在设备树描述,比如min_uA对应设备树的“regulator-min-microvolt”属性。
consumer是regulator提供服务的对象,使用者。每个consumer都有个结构体:
struct regulator {
struct device *dev;
struct list_head list;
unsigned int always_on:1;
unsigned int bypass:1;
int uA_load;
struct regulator_voltage voltage[REGULATOR_STATES_NUM];
const char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev; //关联的regulator
struct dentry *debugfs;
};
常见的consumer接口函数:
/*获取和释放*/
struct regulator *regulator_get(struct device*dev, const char *id);
void regulator_put(struct regulator *regulator);
/*使能和关闭*/
int regulator_enable(regulator);
int regulator_disable(regulator);
/*设置regulator的电压,获得regulator的电压状态*/
int regulator_set_voltage(regulator, min_uVmax_uV)
int regulator_get_voltage(regulator);
int regulator_set_current_limit(regulator, min_uA, max_uA);
/*操作模式控制和状态*/
int regulator_set_optimum_mode(struct regulator*regulator,int load_uA);
int regulator_set_mode(struct regulator*regulator, unsigned int mode);
unsigned int regulator_get_mode(struct regulator*regulator);
切换到/sys/class/regulator目录下。
可以看到该目录有我们注册的regulator,并且都是链接文件,指向平台设备下的具体文件。 我们切换到一个regulator.14(tcs4525)目录下,可以看到一系列文件: