Chinaunix首页 | 论坛 | 博客
  • 博客访问: 395481
  • 博文数量: 53
  • 博客积分: 1910
  • 博客等级: 中尉
  • 技术积分: 1130
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-10 14:56
文章分类

全部博文(53)

文章存档

2013年(1)

2012年(17)

2011年(33)

2010年(2)

分类: LINUX

2011-12-19 08:20:18

关于fixed regulator 的使用:
   1. 提供一组,消耗和供电的maps
      比如模块电源使能:
      static struct regulator_consumer_supply omap3evm_vmmc2_supply =
        REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
       vmmc 表示supply 的名字
    mmci-omap-hs.1 dev 名字
    他们的map关系名字为vmmc 的regulator 给名字为mmci-omap-hs.1供电
   
   2. 设置regulator_init_data ,该结构,是用来register regulator class
      device,包含上面的maps,和约束等数据
      比如:
      static struct regulator_init_data omap3evm_vmmc2 = {
      num_consumer_supplies 指定上面 regulator_consumer_supply maps 有几组
      constraints
            中valid_ops_mask 包含regulator    操作的能力
          #define REGULATOR_CHANGE_VOLTAGE 电压调节
          #define REGULATOR_CHANGE_CURRENT 电流调节
          #define REGULATOR_CHANGE_MODE  
          #define REGULATOR_CHANGE_STATUS 开关
          #define REGULATOR_CHANGE_DRMS 
         
            valid_modes_mask 包含操作mode:
            #define REGULATOR_MODE_FAST 0x1    电压可以快速调
            #define REGULATOR_MODE_NORMAL 0x2  正常模式
            #define REGULATOR_MODE_IDLE 0x4    低负载(loading小)
            #define REGULATOR_MODE_STANDBY 0x8  sleep standby 状态下低功耗

   3. 声明fixed regulator 所需要的fixed_voltage_config 数据结构
      其中包括supply 名字,电压mv,开关gpio,使能电平等,并包含上面的initdata
      static struct fixed_voltage_config omap3evm_vwlan = {
 .supply_name            = "vwl1271",
 .microvolts             = 1800000, /* 1.80V */
 .gpio                   = OMAP3EVM_WLAN_PMENA_GPIO,
 .startup_delay          = 70000, /* 70ms */
 .enable_high            = 1,
 .enabled_at_boot        = 0,
 .init_data              = &omap3evm_vmmc2,
      };
  
    4. 声明一个reg-fixed-voltage 名字的platform device
       和fixed.c中reg-fixed-voltage名字的driver 匹配,
       在platform bus 上执行 fixed regulator driver 的probe
       比如:
       其中fixed_voltage_config 做为platform data 传入probe
       static struct platform_device omap3evm_wlan_regulator = {
 .name           = "reg-fixed-voltage",
 .id             = 1,
 .dev = {
  .platform_data  = &omap3evm_vwlan,
 },
        };

        最后注册 该platform device
        platform_device_register(&omap3evm_wlan_regulator);

关于fixed regulator init
   1.  fixed regulator driver (fixed.c) 会probe  reg-fixed-voltage1
       static struct platform_driver regulator_fixed_voltage_driver = {
 .probe  = reg_fixed_voltage_probe,
 .remove  = __devexit_p(reg_fixed_voltage_remove),
 .driver  = {
  .name  = "reg-fixed-voltage",
  .owner  = THIS_MODULE,
 },
       };

   2. probe 中,通过struct fixed_voltage_config *config
      (regulator platformdevice 的platformdata传入)
       获得信息来产生下面结构:
      struct fixed_voltage_data {
 struct regulator_desc desc;
 struct regulator_dev *dev;
 int microvolts;
 int gpio;
 unsigned startup_delay;
 bool enable_high;
 bool is_enabled;
      };

      并通过struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 struct device *dev, struct regulator_init_data *init_data,
 void *driver_data)
    注册regulator_dev (class device) 到kernel,
    这样/sys/class/regulator 下面 就包含regulator.1 实际link到
    /sys/devices/platform/reg-fixed-voltage.1/regulator/regulator.1
    这个platform device!

    在注册过程中主要进行struct regulator_dev (class device)的初始化
    struct regulator_dev {
 struct regulator_desc *desc;
 int use_count;
 int open_count;
 int exclusive;

 /* lists we belong to */
 struct list_head list; /* list of all regulators */
 struct list_head slist; /* list of supplied regulators */
        /* slist 用来link 到susply 给该reg dev 的supply_list 上*/

 /* lists we own */
 struct list_head consumer_list; /* consumers we supply */
 struct list_head supply_list; /* regulators we supply */
        /* supply_list link 子regulator list 用*/

 struct blocking_notifier_head notifier;
 struct mutex mutex; /* consumer lock */
 struct module *owner;
 struct device dev;
 struct regulation_constraints *constraints;
 struct regulator_dev *supply; /* for tree */

 void *reg_data;  /* regulator_dev data */
        /* 私有数据,c 实现多态性的套路*/
     };

     上面注册成功regulator class dev 后,赋给 fixed_voltage_data
     的struct regulator_dev *dev

     最后通过platform_set_drvdata(pdev, drvdata);
     这样可以方便的使用platform_get_drvdata 来通过
     regulator platform device 来获其对应的fixed_voltage_data

     在probe中,主要完成
     * fixed_voltage_ops 操作函数组设置
     不同的regulator 有不同ops
     * regulator class device 注册
     * 约束设置
       比如有电压约束(min ,max)
       则ops->set_voltage(min,max)
     * 父rugulator dev 关联
       这样可以把LDO 串成1棵树
     * set_consumer_device_supply
       通过该函数建立 consummer  supply ,regulator dev 的map
       并link 到regulator_map_list
       这是regulator get 所需要查找的list
     * 最后所有regulator 都挂到全局regulator_list


关于fixed regulator 的调用
     在其他driver 中需要通过fixed regulator 上电时:
     regulator_get(dev,supply name) 来获得
     struct regulator {
 struct device *dev;
 struct list_head list;
 int uA_load;
 int min_uV;
 int max_uV;
 char *supply_name;
 struct device_attribute dev_attr;
 struct regulator_dev *rdev;
     };
     这个结构是通用的结构,对不同的regulator 通过
     rdev_get_drvdata(rdev) 来获得不同子类型来进行操作

     对于fixed regulator 比较简单
     在获得regulator 后可以在poweron ,off时
     调用regulator_enable(reg) 或
      regulator_disable(reg)
   
     比如:sdio 2的vmmc   
      omap_hsmmc_probe =>
      omap_hsmmc_reg_get  => host=>vcc 获得regulator结构
     
      omap_hsmmc_23_set_power =>
            =>mmc_regulator_set_ocr
                => regulator_enable(supply);
      去enable


core.c  应该看做为1个接口,或者抽象类
fixed ,或其他regulator 是对core 接口的具体实现
对外统一使用core.c 中提供的接口函数

阅读(6980) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~