Linux Regulator Framework(1)_概述

1. 前言

Regulator,中文名翻译为“稳定器”,在电子工程中,是voltage regulator(稳压器)或者current regulator(稳流器)的简称,指可以自动维持恒定电压(或电流)的装置。

voltage regulator最早应用于功放电路中,主要用于滤除电源纹波(100或者120Hz)和噪声,以及避免“输出电压随负载的变化而变化”的情况。后来,随着IC级别的regulator的出现(便宜了),voltage regulator几乎存在于任何的电子设备中。例如我们常见的嵌入式设备中,基本上每一种电压,都是经过regulator输出的。

相比较voltage regulator的广泛使用,很少见到current regulator的应用场景(相信大多数的嵌入式工程师都没有接触过)。它一般存在于电流源中,除此之外,它广泛存在于近年来新兴的LED照明设备中。current regulator在LED设备中的作用主要有两个:避免驱动电流超出最大额定值,影响其可靠性;获得预期的亮度要求,并保证各个LED亮度、色度的一致性。

注1:有关regulator的描述,参考自“http://sound.westhost.com/articles/vi-regulators.html”。

注2:kernel中有关regulator framework的介绍写的相当好(Documentation\power\regulator*),因此本文大部分内容会参考这些文件。

2. 背后的思考

Linux regulator framework的目的很直接:提供标准的内核接口,控制系统的voltage/current regulators,并提供相应的机制,在系统运行的过程中,动态改变regulators的输出,以达到省电的目的。

看似简单的背后,有些因素不得不考虑。

1)最重要的,就是安全性:

在一个系统中,错误的regulator配置是非常危险的,严重时可以损毁硬件。而无论是regulator的使用者(consumer),还是regulator提供者(provider,即regulator driver),都不一定有足够的知识和能力,避免危险发生。因此必须从machine的角度,小心的设计regulator的输出限值(这一般由产品设计、硬件设计决定的)。

同时,一旦设计确定下来之后,这些限制必须保存在一些相对固定的地方,不能轻易地被软件修改。

最后,所有的regulator操作,必须是小心的、在可允许范围内的。

2)系统中大部分的设备,都没有动态更改regulator配置的需求,甚至连enable/disable都懒得关心的,framework需要考虑这种情况,尽量简化接口。

3)会存在同一个regulator向多个设备提供power的情况,如果这些设备的需求不同怎么办?

4)regulator之间是否可以级联?如果可以,怎么处理?

这些思考最终都会反映到软件设计上,具体可参考如下的软件架构。

3. 软件架构

基于上面的思考,regulator framework的软件架构如下:
在这里插入图片描述
除了machine之外,基本上和common clock framework的consumer/provider框架类似。

3.1 machine

machine的主要功能,是使用软件语言(struct regulator_init_data),静态的描述regulator在板级的物理现状,包括:

/**
 * struct regulator_init_data - 调节器平台初始化数据。
 *
 * 初始化约束条件、我们的供应电源和消费者供应电源。
 *
 * @supply_regulator: 父调节器。通过在sysfs中的名称字段中显示的调节器名称指定,
 *                    可以使用constraints字段的'name'来明确设置。
 *
 * @constraints: 约束条件。必须为了使调节器可用而指定。
 * @num_consumer_supplies: 消费者设备供应电源的数量。
 * @consumer_supplies: 消费者设备供电配置。
 *
 * @regulator_init: 调节器注册后调用的回调函数。
 * @driver_data: 传递给regulator_init的数据。
 */
struct regulator_init_data {
    const char *supply_regulator;        /* 父调节器的名称,如果没有父调节器,则为 NULL */

    struct regulation_constraints constraints; /* 调节器的初始化约束条件 */

    int num_consumer_supplies; /* 与调节器关联的消费者设备供应的数量 */

    struct regulator_consumer_supply *consumer_supplies; /* 指向消费者设备供电配置的指针 */

    /* 可选的调节器机器特定初始化回调函数 */
    int (*regulator_init)(void *driver_data);

    void *driver_data;    /* 机器特定数据指针,内核核心不会直接操作 */
};

struct regulator_init_data 结构体用于提供调节器的初始化数据,包括供应电源信息、约束条件、消费者设备供电配置以及初始化回调函数。这些数据有助于内核初始化和配置调节器以满足系统的电源管理需求。通过填充这个结构体,开发人员可以定制调节器的行为和特性,以满足不同的硬件和应用需求。

1)前级regulator(即该regulator的输出是另一个regulator的输入,简称supply regulator)和后级regulator(即该regulator的输入是其它regulator的输出,简称consumer regulator)。

这主要用于描述regulator在板级的级联关系,需要留意的是,它和clock不同,这种级联关系是非常确定的,以至于需要使用静态的方式描述,而不是像clock那样,在注册的时候动态指定并形成。

2)该regulator的物理限制(struct regulation_constraints),包括:

输出电压的最大值和最小值(voltage regulator);
输出电流的最大值和最小值(current regulator);
允许的操作(修改电压值、修改电流限制、enable、disable等等);
输入电压是多少(当输入是另一个regulator时);
是否不允许关闭(always_on);
是否启动时就要打开(always_on);
等等。

这些限制关系到系统安全,因此必须小心配置。配置完成后,在系统运行的整个过程中,它们都不会再改变了。

3)与调节器关联的消费者设备供应的数量
4)指向消费者设备供电配置的指针
5)调节器注册后调用的回调函数
6)传递给regulator_init的数据

3.2 driver

driver模块的功能,是从regulator driver的角度,抽象regulator设备。

1)使用struct regulator_desc描述regulator的静态信息,包括:名字、supply regulator的名字、中断号、操作函数集(struct regulator_ops)、使用regmap时相应的寄存器即bitmap等等。

2)使用struct regulator_config,描述regulator的动态信息(所谓的动态信息,体现在struct regulator_config变量都是局部变量,因此不会永久保存),包括struct regulator_init_data指针、设备指针、enable gpio等等。

3)提供regulator的注册接口(regulator_register/devm_regulator_register),该接口接受描述该regulator的两个变量的指针:struct regulator_desc和struct regulator_config,并分配一个新的数据结构(struct regulator_dev,从设备的角度描述regulator),并把静态指针(struct regulator_desc)和动态指针(struct regulator_config)提供的信息保存在其中。

4)最后,regulator driver将以为struct regulator_dev指针为对象,对regulator进行后续的操作。

3.3 consumer

consumer的功能,是从regulator consumer的角度,抽象regulator设备(struct regulator),并提供regulator操作相关的接口。包括:

3.4 core

core负责上述逻辑的具体实现,并以sysfs的形式,向用户空间提供接口。

4. 接口汇整

本节对regulator framework向各个层次提供的API做一个汇整,具体细节会在后续的文章中详细描述。

4.1 consumer模块向内核空间consumer提供的接口

regulator framework向内核空间consumer提供的接口位于“include/linux/regulator/consumer.h”中,包括regulator的获取、使能、修改等接口,如下。

1)struct regulator

struct regulator结构用于从consumer的角度抽象一个regulator,consumer不需要关心该结构的细节,当作一个句柄使用即可(类似struct clk)。

2)regulator的get/put接口

/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
					     const char *id);
struct regulator *__must_check devm_regulator_get(struct device *dev,
					     const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
						       const char *id);
struct regulator *__must_check devm_regulator_get_exclusive(struct device *dev,
							const char *id);
struct regulator *__must_check regulator_get_optional(struct device *dev,
						      const char *id);
struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
							   const char *id);
int devm_regulator_get_enable(struct device *dev, const char *id);
int devm_regulator_get_enable_optional(struct device *dev, const char *id);
void regulator_put(struct regulator *regulator);
void devm_regulator_put(struct regulator *regulator);
这些函数是Linux内核中用于与电压和电流调节器(regulator)子系统交互的一组函数,用于获取和释放(put)电压和电流调节器的引用。电压和电流调节器通常用于管理嵌入式系统中的电源电压和电流,以确保稳定的电源供应。以下是这些函数的详细说明:

    struct regulator *regulator_get(struct device *dev, const char *id);
        作用:此函数用于从指定的设备 dev 获取一个电压或电流调节器,该调节器由参数 id 指定。如果找到匹配的调节器,它将返回一个指向该调节器的结构体指针。
        返回值:如果找到匹配的调节器,则返回指向该调节器的指针,否则返回NULL。

    struct regulator *devm_regulator_get(struct device *dev, const char *id);
        作用:与 regulator_get 类似,但是这个函数是设备管理器(devres)版本的 regulator_get。它会自动在设备被释放时释放资源,不需要手动调用 regulator_put。

    struct regulator *regulator_get_exclusive(struct device *dev, const char *id);
        作用:类似于 regulator_get,但是它尝试以独占模式获取电压或电流调节器,这意味着其他使用者无法在此期间获取相同的调节器。
        返回值:如果成功获取独占的调节器,返回指向该调节器的指针;否则返回NULL。

    struct regulator *devm_regulator_get_exclusive(struct device *dev, const char *id);
        作用:与 regulator_get_exclusive 类似,但是这是设备管理器版本的函数,会在设备释放时自动释放资源。

    struct regulator *regulator_get_optional(struct device *dev, const char *id);
        作用:类似于 regulator_get,但是它不会报错如果找不到匹配的调节器,而是返回NULL。这对于一些电源管理不是必需的情况很有用。
        返回值:如果找到匹配的调节器,则返回指向该调节器的指针,否则返回NULL。

    struct regulator *devm_regulator_get_optional(struct device *dev, const char *id);
        作用:与 regulator_get_optional 类似,是设备管理器版本的函数,会在设备释放时自动释放资源。

    int devm_regulator_get_enable(struct device *dev, const char *id);
        作用:用于获取指定调节器的状态。如果调节器处于启用状态,返回1;如果处于禁用状态,返回0;如果找不到调节器,返回负数错误代码。

    int devm_regulator_get_enable_optional(struct device *dev, const char *id);
        作用:与 devm_regulator_get_enable 类似,但是它不会报错如果找不到匹配的调节器,而是返回负数错误代码。

    void regulator_put(struct regulator *regulator);
        作用:用于释放通过 regulator_get 或 regulator_get_exclusive 获取的调节器的引用。一旦不再需要调节器,应该调用此函数以确保正确释放资源。

    void devm_regulator_put(struct regulator *regulator);
        作用:与 regulator_put 类似,但是这是设备管理器版本的函数,会在设备释放时自动释放资源,不需要手动调用。

这些函数使开发者能够方便地与Linux内核的电压和电流调节器子系统进行交互,以管理系统的电源供应。根据具体的需求和错误处理策略,可以选择使用不同的函数。

3)supply alias相关的接口

int regulator_register_supply_alias(struct device *dev, const char *id,
				    struct device *alias_dev,
				    const char *alias_id);
void regulator_unregister_supply_alias(struct device *dev, const char *id);

int regulator_bulk_register_supply_alias(struct device *dev,
					 const char *const *id,
					 struct device *alias_dev,
					 const char *const *alias_id,
					 int num_id);
void regulator_bulk_unregister_supply_alias(struct device *dev,
					    const char * const *id, int num_id);

int devm_regulator_register_supply_alias(struct device *dev, const char *id,
					 struct device *alias_dev,
					 const char *alias_id);

int devm_regulator_bulk_register_supply_alias(struct device *dev,
					      const char *const *id,
					      struct device *alias_dev,
					      const char *const *alias_id,
					      int num_id);
这些函数是Linux内核中用于注册和取消注册电压和电流调节器供应别名的函数。这些别名可以帮助管理和标识不同设备之间的电源供应关系。以下是这些函数的详细说明:

    int regulator_register_supply_alias(struct device *dev, const char *id, struct device *alias_dev, const char *alias_id);
        作用:用于在给定的设备 dev 上注册一个电源供应别名,将其命名为 id,并将其关联到另一个设备 alias_dev 的别名 alias_id。这意味着在设备 dev 上使用 id 来请求电源供应时,实际上会请求到 alias_dev 上的 alias_id。
        返回值:成功注册返回0,否则返回负数错误代码。

    void regulator_unregister_supply_alias(struct device *dev, const char *id);
        作用:用于取消在设备 dev 上注册的电源供应别名 id。

    int regulator_bulk_register_supply_alias(struct device *dev, const char *const *id, struct device *alias_dev, const char *const *alias_id, int num_id);
        作用:与 regulator_register_supply_alias 类似,但可以一次注册多个电源供应别名。参数 id 和 alias_id 是字符串数组,num_id 是数组中的元素数量。
        返回值:成功注册所有别名返回0,否则返回负数错误代码。

    void regulator_bulk_unregister_supply_alias(struct device *dev, const char * const *id, int num_id);
        作用:与 regulator_unregister_supply_alias 类似,但可以一次取消注册多个电源供应别名。参数 id 是要取消注册的别名的字符串数组,num_id 是数组中的元素数量。

    int devm_regulator_register_supply_alias(struct device *dev, const char *id, struct device *alias_dev, const char *alias_id);
        作用:与 regulator_register_supply_alias 类似,但这是设备管理器(devres)版本的函数,会在设备释放时自动取消注册别名。
        返回值:成功注册返回0,否则返回负数错误代码。

    int devm_regulator_bulk_register_supply_alias(struct device *dev, const char *const *id, struct device *alias_dev, const char *const *alias_id, int num_id);
        作用:与 regulator_bulk_register_supply_alias 类似,但这是设备管理器版本的函数,会在设备释放时自动取消注册别名。
        返回值:成功注册所有别名返回0,否则返回负数错误代码。

这些函数使开发者能够在Linux内核中管理电源供应别名,以便更好地管理设备之间的电源依赖关系和互连。通过使用这些函数,可以简化电源管理的任务,确保设备在请求电源供应时能够获得正确的供应。

4)regulator的控制、状态获取接口

/* regulator output control and status */
int __must_check regulator_enable(struct regulator *regulator);
int regulator_disable(struct regulator *regulator);
int regulator_force_disable(struct regulator *regulator);
int regulator_is_enabled(struct regulator *regulator);
int regulator_disable_deferred(struct regulator *regulator, int ms);

int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
				    struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
					 struct regulator_bulk_data *consumers);
void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
int __must_check devm_regulator_bulk_get_const(
	struct device *dev, int num_consumers,
	const struct regulator_bulk_data *in_consumers,
	struct regulator_bulk_data **out_consumers);
int __must_check regulator_bulk_enable(int num_consumers,
				       struct regulator_bulk_data *consumers);
int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers,
				   const char * const *id);
int regulator_bulk_disable(int num_consumers,
			   struct regulator_bulk_data *consumers);
int regulator_bulk_force_disable(int num_consumers,
			   struct regulator_bulk_data *consumers);
void regulator_bulk_free(int num_consumers,
			 struct regulator_bulk_data *consumers);

int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_is_supported_voltage(struct regulator *regulator,
				   int min_uV, int max_uV);
unsigned int regulator_get_linear_step(struct regulator *regulator);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_set_voltage_time(struct regulator *regulator,
			       int old_uV, int new_uV);
int regulator_get_voltage(struct regulator *regulator);
int regulator_sync_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
			       int min_uA, int max_uA);
int regulator_get_current_limit(struct regulator *regulator);

int regulator_set_mode(struct regulator *regulator, unsigned int mode);
unsigned int regulator_get_mode(struct regulator *regulator);
int regulator_get_error_flags(struct regulator *regulator,
				unsigned int *flags);
int regulator_set_load(struct regulator *regulator, int load_uA);

int regulator_allow_bypass(struct regulator *regulator, bool allow);

struct regmap *regulator_get_regmap(struct regulator *regulator);
int regulator_get_hardware_vsel_register(struct regulator *regulator,
					 unsigned *vsel_reg,
					 unsigned *vsel_mask);
int regulator_list_hardware_vsel(struct regulator *regulator,
				 unsigned selector);
这些函数是Linux内核中用于控制和管理电压和电流调节器(regulator)的函数。电压和电流调节器用于管理嵌入式系统中的电源供应。以下是这些函数的详细说明和总结:

    int regulator_enable(struct regulator *regulator);
        作用:启用指定的电压或电流调节器。
        返回值:成功启用返回0,否则返回负数错误代码。

    int regulator_disable(struct regulator *regulator);
        作用:禁用指定的电压或电流调节器。
        返回值:成功禁用返回0,否则返回负数错误代码。

    int regulator_force_disable(struct regulator *regulator);
        作用:强制禁用指定的电压或电流调节器,忽略可能存在的使用计数。
        返回值:成功禁用返回0,否则返回负数错误代码。

    int regulator_is_enabled(struct regulator *regulator);
        作用:检查指定的电压或电流调节器是否已启用。
        返回值:如果已启用返回1,否则返回0。

    int regulator_disable_deferred(struct regulator *regulator, int ms);
        作用:延迟一段时间后禁用指定的电压或电流调节器。
        返回值:成功启用延迟返回0,否则返回负数错误代码。

    int regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers);
        作用:批量获取多个电压或电流调节器的引用。
        返回值:成功获取返回0,否则返回负数错误代码。

    int devm_regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers);
        作用:与 regulator_bulk_get 类似,但这是设备管理器版本的函数,会在设备释放时自动释放资源。
        返回值:成功获取返回0,否则返回负数错误代码。

    void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
        作用:释放通过 devm_regulator_bulk_get 获取的电压或电流调节器的引用。

    int devm_regulator_bulk_get_const(struct device *dev, int num_consumers, const struct regulator_bulk_data *in_consumers, struct regulator_bulk_data **out_consumers);
        作用:与 devm_regulator_bulk_get 类似,但可以在输入参数 in_consumers 上工作,并返回输出参数 out_consumers。
        返回值:成功获取返回0,否则返回负数错误代码。

    int regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers);
        作用:批量启用多个电压或电流调节器。
        返回值:成功启用返回0,否则返回负数错误代码。

    int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers, const char * const *id);
        作用:与 devm_regulator_bulk_get 类似,但用于批量启用电压或电流调节器,并根据 id 列表指定哪些调节器应该启用。
        返回值:成功启用返回0,否则返回负数错误代码。

    int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers);
        作用:批量禁用多个电压或电流调节器。
        返回值:成功禁用返回0,否则返回负数错误代码。

    int regulator_bulk_force_disable(int num_consumers, struct regulator_bulk_data *consumers);
        作用:批量强制禁用多个电压或电流调节器,忽略可能存在的使用计数。
        返回值:成功禁用返回0,否则返回负数错误代码。

    void regulator_bulk_free(int num_consumers, struct regulator_bulk_data *consumers);
        作用:释放通过 regulator_bulk_get 或 devm_regulator_bulk_get 获取的电压或电流调节器的引用。

    int regulator_count_voltages(struct regulator *regulator);
        作用:获取指定调节器支持的电压级别数量。
        返回值:支持的电压级别数量。

    int regulator_list_voltage(struct regulator *regulator, unsigned selector);
        作用:获取指定调节器的电压级别。
        返回值:电压级别(单位为微伏)。

    int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV);
        作用:检查指定的调节器是否支持给定的电压范围。
        返回值:如果支持返回1,否则返回0。

    unsigned int regulator_get_linear_step(struct regulator *regulator);
        作用:获取指定调节器的线性电压级别步进值。
        返回值:线性电压级别步进值(单位为微伏)。

    int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
        作用:设置指定调节器的电压范围。
        返回值:成功设置返回0,否则返回负数错误代码。

    int regulator_set_voltage_time(struct regulator *regulator, int old_uV, int new_uV);
        作用:设置指定调节器从旧电压到新电压的转换时间。
        返回值:成功设置返回0,否则返回负数错误代码。

    int regulator_get_voltage(struct regulator *regulator);
        作用:获取指定调节器的当前电压。
        返回值:当前电压(单位为微伏)。

    int regulator_sync_voltage(struct regulator *regulator);
        作用:同步指定调节器的电压状态。
        返回值:成功同步返回0,否则返回负数错误代码。

    int regulator_set_current_limit(struct regulator *regulator, int min_uA, int max_uA);
        作用:设置指定调节器的电流限制范围。
        返回值:成功设置返回0,否则返回负数错误代码。

    int regulator_get_current_limit(struct regulator *regulator);
        作用:获取指定调节器的当前电流限制。
        返回值:当前电流限制(单位为微安)。

    int regulator_set_mode(struct regulator *regulator, unsigned int mode);
        作用:设置指定调节器的工作模式。
        返回值:成功设置返回0,否则返回负数错误代码。

    unsigned int regulator_get_mode(struct regulator *regulator);
        作用:获取指定调节器的当前工作模式。

    int regulator_get_error_flags(struct regulator *regulator, unsigned int *flags);
        作用:获取指定调节器的错误标志。
        返回值:成功获取返回0,否则返回负数错误代码。

    int regulator_set_load(struct regulator *regulator, int load_uA);
        作用:设置指定调节器的负载。
        返回值:成功设置返回0,否则返回负数错误代码。

    int regulator_allow_bypass(struct regulator *regulator, bool allow);
        作用:允许或禁止绕过指定调节器。
        返回值:成功设置返回0,否则返回负数错误代码。

    struct regmap *regulator_get_regmap(struct regulator *regulator);
        作用:获取与指定调节器关联的寄存器映射对象。
        返回值:指向寄存器映射对象的指针。

    int regulator_get_hardware_vsel_register(struct regulator *regulator, unsigned *vsel_reg, unsigned *vsel_mask);
        作用:获取调节器的硬件电压选择寄存器及其位掩码。
        返回值:成功获取返回0,否则返回负数错误代码。

    int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector);
        作用:列出指定调节器支持的硬件电压选择级别。
        返回值:硬件电压选择级别。

5)bulk型的操作(一次操作多个regulator)

/* regulator notifier block */
int regulator_register_notifier(struct regulator *regulator,
			      struct notifier_block *nb);
int devm_regulator_register_notifier(struct regulator *regulator,
				     struct notifier_block *nb);
int regulator_unregister_notifier(struct regulator *regulator,
				struct notifier_block *nb);
void devm_regulator_unregister_notifier(struct regulator *regulator,
					struct notifier_block *nb);

/* regulator suspend */
int regulator_suspend_enable(struct regulator_dev *rdev,
			     suspend_state_t state);
int regulator_suspend_disable(struct regulator_dev *rdev,
			      suspend_state_t state);
int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
				  int max_uV, suspend_state_t state);

/* driver data - core doesn't touch */
void *regulator_get_drvdata(struct regulator *regulator);
void regulator_set_drvdata(struct regulator *regulator, void *data);

/* misc helpers */

void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
				     const char *const *supply_names,
				     unsigned int num_supplies);

bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2);
这些函数是Linux内核中用于电压和电流调节器(regulator)相关功能的辅助函数。以下是这些函数的详细说明和总结:

    int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb);
        作用:用于向指定的电压或电流调节器注册一个通知回调函数(notifier)。通知回调函数将在调节器状态变化时被触发,允许外部组件监听和响应调节器的变化。
        返回值:成功注册返回0,否则返回负数错误代码。

    int devm_regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb);
        作用:与 regulator_register_notifier 类似,但这是设备管理器(devres)版本的函数,会在设备释放时自动取消注册通知回调。

    int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb);
        作用:取消注册之前通过 regulator_register_notifier 注册的通知回调函数。
        返回值:成功取消注册返回0,否则返回负数错误代码。

    void devm_regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb);
        作用:与 regulator_unregister_notifier 类似,但这是设备管理器版本的函数,会在设备释放时自动取消注册通知回调。

    int regulator_suspend_enable(struct regulator_dev *rdev, suspend_state_t state);
        作用:在系统挂起期间启用指定电压或电流调节器。这通常用于确保系统在挂起期间仍然能够提供所需的电源供应。
        返回值:成功启用返回0,否则返回负数错误代码。

    int regulator_suspend_disable(struct regulator_dev *rdev, suspend_state_t state);
        作用:在系统挂起期间禁用指定电压或电流调节器。这用于在系统挂起时关闭电源供应,以减少功耗。
        返回值:成功禁用返回0,否则返回负数错误代码。

    int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, int max_uV, suspend_state_t state);
        作用:设置在指定挂起状态下的电压范围。这可以用于调整挂起期间的电压供应以降低功耗。
        返回值:成功设置返回0,否则返回负数错误代码。

    void *regulator_get_drvdata(struct regulator *regulator);
        作用:获取与指定电压或电流调节器相关联的驱动数据(driver data)指针。这允许驱动程序在调节器上附加自定义数据。
        返回值:指向驱动数据的指针。

    void regulator_set_drvdata(struct regulator *regulator, void *data);
        作用:设置与指定电压或电流调节器相关联的驱动数据指针。

    void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers, const char *const *supply_names, unsigned int num_supplies);
        作用:用于设置一组电压或电流调节器的供应别名,将这些别名关联到调节器。

    bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2);
        作用:检查两个电压或电流调节器是否相等,即它们是否引用相同的调节器。
        返回值:如果相等返回true,否则返回false。

这些函数提供了在Linux内核中操作和管理电压和电流调节器所需的一些辅助功能。它们用于注册通知、设置挂起状态下的电压范围、获取/设置驱动数据以及其他一些操作。

4.2 consumer模块向用户空间consumer提供的接口

sys/devices/platform/regulator-pcie
...

4.3 machine模块向regulator driver提供的接口

machine模块主要提供struct regulator_init_data、struct regulation_constraints constraints等数据结构,用于描述板级的regulator配置,具体可参考3.1中介绍。

4.4 driver模块向regulator driver提供的接口

regulator framework向regulator driver提供的接口位于“include/linux/regulator/driver.h”中,包括数据结构抽象、regulator注册等。

1)struct regulator_desc、struct regulator_config和struct regulator_dev

见3.2中的介绍。

2)regulator设备的注册接口

   1: struct regulator_dev *
   2: regulator_register(const struct regulator_desc *regulator_desc,
   3:                    const struct regulator_config *config);
   4: struct regulator_dev *
   5: devm_regulator_register(struct device *dev,
   6:                         const struct regulator_desc *regulator_desc,
   7:                         const struct regulator_config *config);
   8: void regulator_unregister(struct regulator_dev *rdev);
   9: void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);

4.5 core模块向用户空间提供的sysfs接口

regulator设备在内核中是以regulator class的形式存在的,regulator core通过class->dev_groups的方式,提供了一些默认的attribute,包括:

/sys/devices/platform/regulator-pcie/regulator/regulator.3/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值