Skip to content

Commit

Permalink
Merge remote-tracking branch 'regulator/topic/tps6507x' into regulato…
Browse files Browse the repository at this point in the history
…r-next
  • Loading branch information
Mark Brown committed Feb 19, 2013
2 parents b67a2ec + 0ce7d00 commit da3522f
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
91 changes: 91 additions & 0 deletions Documentation/devicetree/bindings/mfd/tps6507x.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
TPS6507x Power Management Integrated Circuit

Required properties:
- compatible: "ti,tps6507x"
- reg: I2C slave address
- regulators: This is the list of child nodes that specify the regulator
initialization data for defined regulators. Not all regulators for the
given device need to be present. The definition for each of these nodes
is defined using the standard binding for regulators found at
Documentation/devicetree/bindings/regulator/regulator.txt.
The regulator is matched with the regulator-compatible.

The valid regulator-compatible values are:
tps6507x: vdcdc1, vdcdc2, vdcdc3, vldo1, vldo2
- xxx-supply: Input voltage supply regulator.
These entries are required if regulators are enabled for a device.
Missing of these properties can cause the regulator registration
fails.
If some of input supply is powered through battery or always-on
supply then also it is require to have these parameters with proper
node handle of always on power supply.
tps6507x:
vindcdc1_2-supply: VDCDC1 and VDCDC2 input.
vindcdc3-supply : VDCDC3 input.
vldo1_2-supply : VLDO1 and VLDO2 input.

Regulator Optional properties:
- defdcdc_default: It's property of DCDC2 and DCDC3 regulators.
0: If defdcdc pin of DCDC2/DCDC3 is pulled to GND.
1: If defdcdc pin of DCDC2/DCDC3 is driven HIGH.
If this property is not defined, it defaults to 0 (not enabled).

Example:

pmu: tps6507x@48 {
compatible = "ti,tps6507x";
reg = <0x48>;

vindcdc1_2-supply = <&vbat>;
vindcdc3-supply = <...>;
vinldo1_2-supply = <...>;

regulators {
#address-cells = <1>;
#size-cells = <0>;

vdcdc1_reg: regulator@0 {
regulator-compatible = "VDCDC1";
reg = <0>;
regulator-min-microvolt = <3150000>;
regulator-max-microvolt = <3450000>;
regulator-always-on;
regulator-boot-on;
};
vdcdc2_reg: regulator@1 {
regulator-compatible = "VDCDC2";
reg = <1>;
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <3450000>;
regulator-always-on;
regulator-boot-on;
defdcdc_default = <1>;
};
vdcdc3_reg: regulator@2 {
regulator-compatible = "VDCDC3";
reg = <2>;
regulator-min-microvolt = <950000>
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
defdcdc_default = <1>;
};
ldo1_reg: regulator@3 {
regulator-compatible = "LDO1";
reg = <3>;
regulator-min-microvolt = <1710000>;
regulator-max-microvolt = <1890000>;
regulator-always-on;
regulator-boot-on;
};
ldo2_reg: regulator@4 {
regulator-compatible = "LDO2";
reg = <4>;
regulator-min-microvolt = <1140000>;
regulator-max-microvolt = <1320000>;
regulator-always-on;
regulator-boot-on;
};
};

};
92 changes: 92 additions & 0 deletions drivers/regulator/tps6507x-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps6507x.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/mfd/tps6507x.h>
#include <linux/regulator/of_regulator.h>

/* DCDC's */
#define TPS6507X_DCDC_1 0
Expand Down Expand Up @@ -356,6 +358,80 @@ static struct regulator_ops tps6507x_pmic_ops = {
.list_voltage = regulator_list_voltage_table,
};

#ifdef CONFIG_OF
static struct of_regulator_match tps6507x_matches[] = {
{ .name = "VDCDC1"},
{ .name = "VDCDC2"},
{ .name = "VDCDC3"},
{ .name = "LDO1"},
{ .name = "LDO2"},
};

static struct tps6507x_board *tps6507x_parse_dt_reg_data(
struct platform_device *pdev,
struct of_regulator_match **tps6507x_reg_matches)
{
struct tps6507x_board *tps_board;
struct device_node *np = pdev->dev.parent->of_node;
struct device_node *regulators;
struct of_regulator_match *matches;
static struct regulator_init_data *reg_data;
int idx = 0, count, ret;

tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
GFP_KERNEL);
if (!tps_board) {
dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
return NULL;
}

regulators = of_find_node_by_name(np, "regulators");
if (!regulators) {
dev_err(&pdev->dev, "regulator node not found\n");
return NULL;
}

count = ARRAY_SIZE(tps6507x_matches);
matches = tps6507x_matches;

ret = of_regulator_match(&pdev->dev, regulators, matches, count);
if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
ret);
return NULL;
}

*tps6507x_reg_matches = matches;

reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
* TPS6507X_NUM_REGULATOR), GFP_KERNEL);
if (!reg_data) {
dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n");
return NULL;
}

tps_board->tps6507x_pmic_init_data = reg_data;

for (idx = 0; idx < count; idx++) {
if (!matches[idx].init_data || !matches[idx].of_node)
continue;

memcpy(&reg_data[idx], matches[idx].init_data,
sizeof(struct regulator_init_data));

}

return tps_board;
}
#else
static inline struct tps6507x_board *tps6507x_parse_dt_reg_data(
struct platform_device *pdev,
struct of_regulator_match **tps6507x_reg_matches)
{
*tps6507x_reg_matches = NULL;
return NULL;
}
#endif
static int tps6507x_pmic_probe(struct platform_device *pdev)
{
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
Expand All @@ -365,15 +441,20 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct tps6507x_pmic *tps;
struct tps6507x_board *tps_board;
struct of_regulator_match *tps6507x_reg_matches = NULL;
int i;
int error;
unsigned int prop;

/**
* tps_board points to pmic related constants
* coming from the board-evm file.
*/

tps_board = dev_get_platdata(tps6507x_dev->dev);
if (!tps_board && tps6507x_dev->dev->of_node)
tps_board = tps6507x_parse_dt_reg_data(pdev,
&tps6507x_reg_matches);
if (!tps_board)
return -EINVAL;

Expand Down Expand Up @@ -415,6 +496,17 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
config.init_data = init_data;
config.driver_data = tps;

if (tps6507x_reg_matches) {
error = of_property_read_u32(
tps6507x_reg_matches[i].of_node,
"ti,defdcdc_default", &prop);

if (!error)
tps->info[i]->defdcdc_default = prop;

config.of_node = tps6507x_reg_matches[i].of_node;
}

rdev = regulator_register(&tps->desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(tps6507x_dev->dev,
Expand Down

0 comments on commit da3522f

Please sign in to comment.