regulator_get 调用过程【转】
本文转载自:http://blog.csdn.net/u012719256/article/details/52083961
Touch panel DTS 分析(MSM8994平台,Atmel 芯片)
在MSM8994平台下,Touch panel的DTS节点写在/kernel/arch/arm/boot/dts/qcom/msm8994-mtp.dtsi文件中。具体代码如下:
&soc {
i2c@f9924000 {
atmel_mxt_ts@4a {
compatible = "atmel,atmel_mxt_ts";
reg = <0x4a>;
interrupt-parent = <&msm_gpio>;
interrupts = <61 0x2008>;
avdd-supply = <&pm8994_l22>;
vdd_io-supply = <&pm8994_l14>;
.........
};
};
在DTS节点中,我们主要看一下avdd-supply and vdd_io-supply两个属性。这两个属性在C代码里的使用方式如下:
/kernel/drivers/input/touchscreen/atmel_mxt_ts.c
mxt_probe_regulators(struct mxt_data *data)
{
........
data->reg_vdd_io = regulator_get(dev, "vdd_io");
........
data->reg_avdd = regulator_get(dev, "avdd");
........
}
/kernel/drivers/regulator/core.c
struct regulator *regulator_get(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 0);
}
static struct regulator *_regulator_get(struct device *dev, const char *id, int exclusive)
{
.......
rdev = regulator_dev_lookup(dev, id, &ret);
if(rdev)
goto found;
......
}
static struct regulator_dev *regulator_dev_lookup(struct devic *dev, const char *supply, int *ret)
{
struct regulator_dev *r;
struct device_node *node;
........
/* first do a dt based lookup */
if (dev && dev->of_node) {
node = of_get_regulator(dev, supply)
if (node) {
list_for_each_entry(r, ®ulator_list, list)
if ( r->dev.parent && node == r->dev.of_node)
return r;
........
}
}
}
static struct device_node *of_get_regulator(struct device *dev, const char *supply)
{
struct device_node *regnode = NULL;
char prop_name[32];
.......
snprintf(prop_name, 32, "%s-supply", supply);
regnode = of_parse_phandle(dev->of_node, prop_name, 0);
........
}
从上述代码大致上可以看到DTS里的vdd_io-supply and avdd-supply属性是如何解析和使用的。在mxt_probe()函数中将字符串“avdd”和“vdd_io”传给regulator_get()函数,一步步调用下来后,在of_get_regulator()函数中将字符串合并成DTS中符合要求的字符串属性,之后通过属性的值来找到相应的regulator_dev 结构体!