Linux regulator分析

转载 2012年03月21日 16:39:22

Regulator模块用于控制系统中某些设备的电压/电流供应。在嵌入式系统(尤其是手机)中,控制耗电量很重要,直接影响到电池的续航时间。所以,如果系统中某一个模块暂时不需要使用,就可以通过regulator关闭其电源供应;或者降低提供给该模块的电压、电流大小。

Regulator的文档在KERNEL/Documentation/Power/Regulator中。

 

Regulator与模块之间是树状关系。父regulator可以给设备供电,也可以给子regulator供电:

 父Regulator -+->子Regulator --> [Consumer A @ 1.8 - 2.0V] |

             +-> [Consumer B @ 3.3V]

具体细节可参考内核文档machine.txt。

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 */

};

Regulator的注册

Regulator的注册由regulator_register完成。

一般来说,为了添加regulator_dev,需要实现一个设备驱动程序,以及在板子的设备列表中增加一个该驱动对应的设备(比如platform_device)。在这个设备的struct device->platform_data域,需要设置regulator_init结构,填写该regulator的相关信息。另外,还需要定义一个regulator_desc结构。这样,在这个物理设备的驱动程序中,就可以通过regulator_register函数登记生成一个regulator_dev。

struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct device *dev, void *driver_data)

           struct regulator_init_data *init_data = dev->platform_data;//得到init_data

           //完整性检查

           …

           //分配regulator_dev结构

           struct regulator_dev *rdev = kzalloc (sizeof(struct regulator_dev), GFP_KERNEL);

           //初始化regulator_dev结构

           …

           //执行regulator_init,该函数中实现regulator代表的硬件设备的初始化

           if (init_data->regulator_init)

                       ret = init_data->regulator_init(rdev->reg_data);

           rdev->dev.class = &regulator_class;         // 指定class为regulator_class

           rdev->dev.parent = dev;

           device_register(&rdev->dev);                 // 注册设备

           //设置constraints,其中可能会包括供电状态的初始化(设置初始电压,enable/disable等等)

           set_machine_constraints(rdev, &init_data->constraints);

           add_regulator_attributes (rdev);

           //如果此regulator有父regulator,设置父regulator

           if (init_data->supply_regulator_dev) {

                       ret = set_supply(rdev,

                                   dev_get_drvdata(init_data->supply_regulator_dev));

                       if (ret < 0)

                                   goto scrub;

           }

           //设置此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, &regulator_list);

 

set_consumer_device_supply函数用于登记regulator_dev与comsumer_dev(regulator负责供电的设备)之间的对应关系。对于每一个regulator_dev—comsumer_dev的配对,都会有一个regulator_map结构,这些结构会被加入到全局链表regulator_map_list中。

Regulator的使用

在设备驱动使用regulator对其驱动的设备供电时,需要首先保证设备与对应regulator之间的匹配关系已经被登记到regulator框架中。这可通过填写regulator_init_data结构实现。(具体可参考内核文档machine.txt)

之后,设备驱动通过regulator_get函数得到regulator结构,此函数通过前文所述regulator_map_list找到对应regulator_dev,再生成regulator结构给用户使用。

通过regulator_enable / regulator_disable打开、关闭regulator,这两个函数最终都是调用struct regulator_ops里的对应成员。

除此之外,还有regualtor_set_voltage / regulator_get_voltage等等。

Regulator能够支持的所有功能列表都在struct regulator_ops中定义,具体可参考代码中的注释。

struct regulator_ops {

           /* get/set regulator voltage */

           int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);

           int (*get_voltage) (struct regulator_dev *);

           /* get/set regulator current */

           int (*set_current_limit) (struct regulator_dev *,

                                                int min_uA, int max_uA);

           int (*get_current_limit) (struct regulator_dev *);

           /* enable/disable regulator */

           int (*enable) (struct regulator_dev *);

           int (*disable) (struct regulator_dev *);

           int (*is_enabled) (struct regulator_dev *);

           /* get/set regulator operating mode (defined in regulator.h) */

           int (*set_mode) (struct regulator_dev *, unsigned int mode);

           unsigned int (*get_mode) (struct regulator_dev *);

           /* get most efficient regulator operating mode for load */

           unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,

                                                            int output_uV, int load_uA);

           /* the operations below are for configuration of regulator state when

            * its parent PMIC enters a global STANDBY/HIBERNATE state */

           /* set regulator suspend voltage */

           int (*set_suspend_voltage) (struct regulator_dev *, int uV);

           /* enable/disable regulator in suspend state */

           int (*set_suspend_enable) (struct regulator_dev *);

           int (*set_suspend_disable) (struct regulator_dev *);

           /* set regulator suspend operating mode (defined in regulator.h) */

           int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);

};

 http://blog.csdn.net/walkingman321/article/details/6987769


相关文章推荐

Linux regulator分析 .

目录(?)[-] regulator_devregulator_init_dataRegulator的注册Regulator的使用   Regulator模块用于控制系统中某些设备的电压...

Linux下regulator驱动程序分析

原文地址::http://blog.csdn.net/lishuiwang/article/details/6130299     // /*regulator 是驱动中电源管理的基础设施。要...

Linux regulator分析

Regulator模块用于控制系统中某些设备的电压/电流供应。在嵌入式系统(尤其是手机)中,控制耗电量很重要,直接影响到电池的续航时间。所以,如果系统中某一个模块暂时不需要使用,就可以通过regula...

Linux下regulator的基础知识

1: 校准器的基本概念 所谓校准器实际是在软件控制下把输入的电源调节精心输出。 Regulator模块用于控制系统中某些设备的电压/电流供应。在嵌入式系统(尤其是手机)中,控制耗电量很重要,直...

linux中的regulator

Regulator模块用于控制系统中某些设备的电压/电流供应。在嵌入式系统(尤其是手机)中,控制耗电量很重要,直接影响到电池的续航时间。所以,如果系统中某一个模块暂时不需要使用,就可以通过regula...

linux 3.x下的regulator_consumer_supply的变化

linux3.x下采用dts的方式建立设备树,自然给驱动带来很多改变。regulator也有很多变化。 结构体regulator_init_data struct regulator_in...
  • fouweng
  • fouweng
  • 2016年11月30日 11:29
  • 118

Linux内核regulator架构和编写

电源种类介绍       (百度百科)LDO是low dropout regulator,意为低压差线性稳压器,是相对于传统的线性稳压器来说的。传统的线性稳压器,如78xx系列的芯片都要求输入电压要比...
  • pseraph
  • pseraph
  • 2014年05月23日 01:31
  • 2000

关于linux regulator dirver(2) OMAP PMIC regulator:

http://blog.chinaunix.net/uid-20514606-id-3045109.html 这个regulator 比较复杂点,主要调节是通过I2C,先看下sys目录: ...

关于linux regulator dirver(1) fixed regulator:

http://blog.chinaunix.net/uid-20514606-id-3045107.html 关于fixed regulator 的使用:    1. 提供一组,消耗和供电...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux regulator分析
举报原因:
原因补充:

(最多只允许输入30个字)