linux下regulator的应用

linux下regulator的应用

 

备注:下面提到的充电IC 用charger表示

 

1.     OTG VBUS 5V供电

接入OTG设备,比如U盘,具体是怎么通过charger驱动来给U盘供电5V的

 

2.     设备树

charger:xxx@6B{
                        regulator-name = " xxx_otg_vreg";
            …
      };
 
&usb_otg {
              …
      vbus_otg-supply = <& charger >;
};
 

3.     调用流程

3.1  usb otg驱动

对应phy-msm-usb.c文件,usb otg驱动加载的时候,调用msm_otg_set_host(),此函数通过:

vbus_otg =devm_regulator_get(motg->phy.dev, "vbus_otg");

通过supply name,这里是vbus_otg-supply,找到regulator设备节点,这里是xxx_otg_supply,调用之后让vbus_otg指向给otg vbus供电的regulator,

 

devm_regulator_get的调用流程:

devm_regulator_get(motg->phy.dev,"vbus_otg")--->regulator_get()
--->_regulator_get()--->regulator_dev_lookup()--->of_get_regulator()
/**
 *of_get_regulator - get a regulator device node based on supply name
 *@dev: Device pointer for the consumer (of regulator) device
 *@supply: regulator supply name
 *
 *Extract the regulator device node corresponding to the supply name.
 *returns the device node corresponding to the regulator if found, else
 *returns NULL.
 */
static struct device_node*of_get_regulator(struct device *dev, const char *supply)
{
       structdevice_node *regnode = NULL;
       charprop_name[32]; /* 32 is max size of property name */
 
       dev_dbg(dev,"Looking up %s-supply from device tree\n", supply);
 
       snprintf(prop_name,32, "%s-supply", supply);
       regnode= of_parse_phandle(dev->of_node, prop_name, 0);
 
       if(!regnode) {
              dev_dbg(dev,"Looking up %s property in node %s failed",
                            prop_name,dev->of_node->full_name);
              returnNULL;
       }
       returnregnode;
}

通过节点xxx下的regulator-name找到regulator的名字为xxx_otg_vreg,

 

Usb otg驱动找到xxx_otg_vreg这个regulator后,在接入OTG设备时,会调用其对应的regulator_desc(描述regulator的静态信息,包括:名字、supply regulator的名字、中断号、操作函数集(structregulator_ops))下的操作表ops下的enable(),拔出OTG设备时调用disable()

msm_hsusb_vbus_power()--->regulator_enable(vbus_otg)

那enable()和disable()具体在charger驱动中实现。

 

3.2  charger驱动

(1)  驱动初始化

调用regulator_register()向regulator框架层注册一个regulator设备,用regulator_dev结构体表示。

struct regulator_ops xxx_otg_reg_ops = {
       .enable         = xxx_otg_regulator_enable,
       .disable  = xxx_otg_regulator_disable,
       .is_enabled   = xxx_otg_regulator_is_enable,
};
 
static int xxx_regulator_init(struct xxx_device_info*chip)
{
       intrc = 0;
       structregulator_init_data *init_data;
       structregulator_config cfg = {};
 
       init_data= of_get_regulator_init_data(chip->dev, chip->dev->of_node);
       if(!init_data) {
              dev_err(chip->dev,"Unable to allocate memory\n");
              return-ENOMEM;
       }
 
       if(init_data->constraints.name) {
              chip->otg_vreg.rdesc.owner= THIS_MODULE;
              chip->otg_vreg.rdesc.type= REGULATOR_VOLTAGE;
              chip->otg_vreg.rdesc.ops= &xxx_otg_reg_ops;
              chip->otg_vreg.rdesc.name= init_data->constraints.name;
 
              cfg.dev= chip->dev;
              cfg.init_data= init_data;
              cfg.driver_data= chip;
              cfg.of_node= chip->dev->of_node;
 
              init_data->constraints.valid_ops_mask
                     |=REGULATOR_CHANGE_STATUS;
 
              chip->otg_vreg.rdev= regulator_register(
                                   &chip->otg_vreg.rdesc,&cfg);
              if(IS_ERR(chip->otg_vreg.rdev)) {
                     rc= PTR_ERR(chip->otg_vreg.rdev);
                     chip->otg_vreg.rdev= NULL;
                     if(rc != -EPROBE_DEFER)
                            dev_err(chip->dev,
                                   "OTGreg failed, rc=%d\n", rc);
              }
       }
 
       returnrc;
}

(2)  插拔OTG设备

比如插入OTG设备时,usb otg驱动通过调用名为xxx_otg_vreg的regulator的enable,来实现otg vbus的供电,对应调用xxx_otg_regulator_enable()

 

你可能感兴趣的:(linux下regulator的应用)