Linux regulator子系统分析2

Linux regulator子系统分析2(基于Linux6.6)---数据结构介绍

 


一、数据结构间的关联说明

针对regulator子系统,包括regulator device(电源提供者)、电源管理芯片(pmic)、电源使用者(consumer)、电源域等几个概念。而在regulator子系统的实现中,则抽象了数据结构regulator_device(表示一个regulator device)、regulator(对应一个电源使用者 consumer),然后围绕这两个数据结构,又定义了regulator_map、regulator_enable_gpio、regulator_desc、regulator_ops、regulator_constraints、regulator_config、regulator_init_data、regulator_consumer_supply等数据结构。

如下图所示,表示数据结构struct regulator_map、struct regulator、struct regulator_dev的关联图:

  1. 系统中所有注册的struct regulator_dev类型的变量,均会添加到链表regulator_list中,而这些操作由接口regulator_register实现。
  2. 在regulator_register接口中,针对一个regulator device的所有使用者,均为其创建struct regulator_map类型变量,并将其插入regulator_map_list链表上,而struct regulator_map中包含该使用者的名称(使用者对应的设备名称、使用类型、regulator_dev类型的指针指向该电源的提供者);
  3. 当电源的使用者(对应的device驱动)在驱动接口中调用regulator_get,申请一个电源使用信息时,则根据该设备的名称、supply名称,在regulator_map_list上查找对应struct regulator_map类型的变量,并创建struct regulator类型的变量,并将其加入到struct regulator_dev的consumer_list链表中,从而实现下图struct regulator、struct regulator_dev的关联(它们之间的关联,需要借助注册在regulator_map_list链表的regulator_map类型变量)。
  4. 若该regulator_dev通过gpio进行enable/disable的控制,则在调用接口regulator_register接口进行regulator_dev的注册时,则创建对应struct regulator_enable_gpio类型变量的创建,并注册到链表regulator_ena_gpio_list中。

下图的数据结构间的关联主要借助接口regulator_register、regulator_get实现。而在regulator_register接口中实现regulator_dev、regulator_map的关联时,还涉及数据结构regulator_enable_gpio、regulator_desc、regulator_ops、regulator_constraints、regulator_config、regulator_init_data、regulator_consumer_supply的关联(这在数据结构regulator_dev中说明)

 

二、regulator_dev相关数据结构说明

struct regulator_dev包含多个数据结构,因此将这几个数据结构间的关联进行说明。如下图所示即为regulator_dev相关的数据结构的关联图。

2.1、struct regulator_config相关数据结构

include/linux/regulator/driver.h

struct regulator_config {
	struct device *dev;
	const struct regulator_init_data *init_data;
	void *driver_data;
	struct device_node *of_node;
	struct regmap *regmap;

	struct gpio_desc *ena_gpiod;
};

struct regulator_config相关数据结构主要用于描述regulator_dev的所有使用者信息,以及该regulator_dev的输出参数信息,具体说明如下:

  1. struct regulator_consumer_supply表示一个regulator_dev的使用者描述,包含使用者对应的设备名称(也可为空)、supply名称,通过这些描述信息,在调用接口regulator_register接口进行regulator_dev的注册时,则根据该数据结构描述的信息,完成上面所说的struct regulator_map类型变量的注册,以便调用regulator_get时可实现struct regulator类型变量的创建;
  2. 若该regulator_dev通过gpio进行enable/disable的控制,则需要对该gpio进行描述(包含gpio号、gpio使能状态、gpio状态是否为invert等),在调用接口regulator_register接口进行regulator_dev的注册时,则创建对应struct regulator_enable_gpio类型变量的创建,并注册到链表regulator_ena_gpio_list中。
  3. 数据结构struct regulation_constraints描述该regulator dev相关的配置信息,包括最小输出电压、最大输出电压、初始模式、是否支持suspend state(suspend to memory、suspend to disk、suspend standby状态等)

2.2、struct regulator_desc相关数据结构

主要涉及struct regulator_desc、struct regulator_ops,具体说明如下:

  1. struct regulator_desc描述该regulator device的类型(电压、电流、电流和电压)、中断id、支持的输出电压个数、操作类型(可改变电压等)、输出模式(fast、normal、idle、standby等);若该regulator device在注册的时候支持通过regmap进行配置(如该regulator device可通过spi、iic接口访问,则可以通过spi/iic对应的regmap接口访问该regulator device的寄存器,进行配置操作),则需要定义enable_reg、enable_mask、apply_reg等参数的信息,以便通过regmap进行配置

以上介绍的是数据结构间关联的说明,下面对几个数据结构进行简要说明:

三、struct regulator_desc

该数据结构是一个regulator_dev的描述信息:

  1. regulator的名称;
  2. 若该regulator device是由别的的regulator device提供的电源(即该regulator device是另一个regulator device的使用者),则supply_name表示提供电源的regulator device名称;
  3. 说明该regulator device可提供的输出电压个数、支持的输出电压列表、单步电压调节值等
  4. 该regulator device的操作接口(struct regulator_ops,包括设置电压、设置电流、输出使能等接口)

include/linux/regulator/driver.h 

struct regulator_desc {
	const char *name;
	const char *supply_name;
	const char *of_match;
	bool of_match_full_name;
	const char *regulators_node;
	int (*of_parse_cb)(struct device_node *,
			    const struct regulator_desc *,
			    struct regulator_config *);
	int id;
	unsigned int continuous_voltage_range:1;
	unsigned n_voltages;
	unsigned int n_current_limits;
	const struct regulator_ops *ops;
	int irq;
	enum regulator_type type;
	struct module *owner;

	unsigned int min_uV;
	unsigned int uV_step;
	unsigned int linear_min_sel;
	int fixed_uV;
	unsigned int ramp_delay;
	int min_dropout_uV;

	const struct linear_range *linear_ranges;
	const unsigned int *linear_range_selectors_bitfield;

	int n_linear_ranges;

	const unsigned int *volt_table;
	const unsigned int *curr_table;

	unsigned int vsel_range_reg;
	unsigned int vsel_range_mask;
	unsigned int vsel_reg;
	unsigned int vsel_mask;
	unsigned int vsel_step;
	unsigned int csel_reg;
	unsigned int csel_mask;
	unsigned int apply_reg;
	unsigned int apply_bit;
	unsigned int enable_reg;
	unsigned int enable_mask;
	unsigned int enable_val;
	unsigned int disable_val;
	bool enable_is_inverted;
	unsigned int bypass_reg;
	unsigned int bypass_mask;
	unsigned int bypass_val_on;
	unsigned int bypass_val_off;
	unsigned int active_discharge_on;
	unsigned int active_discharge_off;
	unsigned int active_discharge_mask;
	unsigned int active_discharge_reg;
	unsigned int soft_start_reg;
	unsigned int soft_start_mask;
	unsigned int soft_start_val_on;
	unsigned int pull_down_reg;
	unsigned int pull_down_mask;
	unsigned int pull_down_val_on;
	unsigned int ramp_reg;
	unsigned int ramp_mask;
	const unsigned int *ramp_delay_table;
	unsigned int n_ramp_values;

	unsigned int enable_time;

	unsigned int off_on_delay;

	unsigned int poll_enabled_time;

	unsigned int (*of_map_mode)(unsigned int mode);
};

四、struct regulation_constraints

该数据结构描述regulator device的约束信息,定义如下:

  1. 输出电压范围;
  2. 输出电流范围;
  3. 该regulator device支持的模式(fast、normal、idle、standby等);
  4. 该regulator device支持的操作模式,包括change volt、change current、change bypass mode等;
  5. 该regulator device支持的suspend 状态下的输出控制(如在suspend to disk状态下的输出控制等);

include/linux/regulator/machine.h 

struct regulation_constraints {

	const char *name;

	/* voltage output range (inclusive) - for voltage control */
	int min_uV;
	int max_uV;

	int uV_offset;

	/* current output range (inclusive) - for current control */
	int min_uA;
	int max_uA;
	int ilim_uA;

	int system_load;

	/* valid regulator operating modes for this machine */
	unsigned int valid_modes_mask;

	/* valid operations for regulator on this machine */
	unsigned int valid_ops_mask;

	/* regulator input voltage - only if supply is another regulator */
	int input_uV;

	/* regulator suspend states for global PMIC STANDBY/HIBERNATE */
	struct regulator_state state_disk;
	struct regulator_state state_mem;
	struct regulator_state state_standby;
	suspend_state_t initial_state; /* suspend state to set at init */

	/* mode to set on startup */
	unsigned int initial_mode;

	unsigned int ramp_delay;
	unsigned int enable_time;

	unsigned int active_discharge;

	/* constraint flags */
	unsigned always_on:1;	/* regulator never off when system is on */
	unsigned boot_on:1;	/* bootloader/firmware enabled regulator */
	unsigned apply_uV:1;	/* apply uV constraint if min == max */
	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 */
};

五、struct regulator_dev

该数据结构表示一个regulator device,定义如下;

  1. 该regulator device的描述信息,struct regulator_desc类型的变量,描述regulator_dev的电压输出信息、操作信息(使能去使能接口、电压设置与获取接口、电流设置与获取接口);
  2. 该regulator_dev所有使用者的信息(consumer_list链表上的regulator成员);
  3. 该regulator_dev是另一个regulator_dev的使用者,则通过supply作为使用者信息;
  4. 该regulator_dev是否支持通过regmap访问;
  5. notifier链表,用于regulator_dev状态变化的通知链;

include/linux/regulator/driver.h 

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 ww_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;

	void *reg_data;		/* regulator_dev data */

	struct dentry *debugfs;

	struct regulator_enable_gpio *ena_pin;
	unsigned int ena_gpio_state:1;

	unsigned int is_switch:1;

	/* time when this regulator was disabled last time */
	ktime_t last_off;
	int cached_err;
	bool use_cached_err;
	spinlock_t err_lock;
};

六、struct regulator

该数据结构表示一个regulator device的使用者,包括是否一直使能、是否使用bypass模式(bypass模式指regulator device输入电压直接作为输出,不做限制)、电压范围、电流值、设备属性信息、该regulator对应的supply名称等。

drivers/regulator/internal.h 

/*
 * struct regulator
 *
 * One for each consumer device.
 */
struct regulator {
	struct device *dev;
	struct list_head list;
	unsigned int always_on:1;
	unsigned int bypass:1;
	int uA_load;
	int min_uV;
	int max_uV;
	int enabled;
	char *supply_name;
	struct device_attribute dev_attr;
	struct regulator_dev *rdev;
	struct dentry *debugfs;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值