aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-19 07:43:10 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-19 07:43:10 -0500
commitda3522f85b49989a67fedb0c31062adb5ce936e7 (patch)
tree2e8574c5b021c101310d4930a88def780cb30dcf
parentb67a2ecb540b3ac08c962742d2142104390ff60c (diff)
parent0ce7d00d0d7bc04d917b8775da177dde962ce17e (diff)
Merge remote-tracking branch 'regulator/topic/tps6507x' into regulator-next
-rwxr-xr-xDocumentation/devicetree/bindings/mfd/tps6507x.txt91
-rw-r--r--drivers/regulator/tps6507x-regulator.c92
2 files changed, 183 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mfd/tps6507x.txt b/Documentation/devicetree/bindings/mfd/tps6507x.txt
new file mode 100755
index 000000000000..8fffa3c5ed40
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/tps6507x.txt
@@ -0,0 +1,91 @@
1TPS6507x Power Management Integrated Circuit
2
3Required properties:
4- compatible: "ti,tps6507x"
5- reg: I2C slave address
6- regulators: This is the list of child nodes that specify the regulator
7 initialization data for defined regulators. Not all regulators for the
8 given device need to be present. The definition for each of these nodes
9 is defined using the standard binding for regulators found at
10 Documentation/devicetree/bindings/regulator/regulator.txt.
11 The regulator is matched with the regulator-compatible.
12
13 The valid regulator-compatible values are:
14 tps6507x: vdcdc1, vdcdc2, vdcdc3, vldo1, vldo2
15- xxx-supply: Input voltage supply regulator.
16 These entries are required if regulators are enabled for a device.
17 Missing of these properties can cause the regulator registration
18 fails.
19 If some of input supply is powered through battery or always-on
20 supply then also it is require to have these parameters with proper
21 node handle of always on power supply.
22 tps6507x:
23 vindcdc1_2-supply: VDCDC1 and VDCDC2 input.
24 vindcdc3-supply : VDCDC3 input.
25 vldo1_2-supply : VLDO1 and VLDO2 input.
26
27Regulator Optional properties:
28- defdcdc_default: It's property of DCDC2 and DCDC3 regulators.
29 0: If defdcdc pin of DCDC2/DCDC3 is pulled to GND.
30 1: If defdcdc pin of DCDC2/DCDC3 is driven HIGH.
31 If this property is not defined, it defaults to 0 (not enabled).
32
33Example:
34
35 pmu: tps6507x@48 {
36 compatible = "ti,tps6507x";
37 reg = <0x48>;
38
39 vindcdc1_2-supply = <&vbat>;
40 vindcdc3-supply = <...>;
41 vinldo1_2-supply = <...>;
42
43 regulators {
44 #address-cells = <1>;
45 #size-cells = <0>;
46
47 vdcdc1_reg: regulator@0 {
48 regulator-compatible = "VDCDC1";
49 reg = <0>;
50 regulator-min-microvolt = <3150000>;
51 regulator-max-microvolt = <3450000>;
52 regulator-always-on;
53 regulator-boot-on;
54 };
55 vdcdc2_reg: regulator@1 {
56 regulator-compatible = "VDCDC2";
57 reg = <1>;
58 regulator-min-microvolt = <1710000>;
59 regulator-max-microvolt = <3450000>;
60 regulator-always-on;
61 regulator-boot-on;
62 defdcdc_default = <1>;
63 };
64 vdcdc3_reg: regulator@2 {
65 regulator-compatible = "VDCDC3";
66 reg = <2>;
67 regulator-min-microvolt = <950000>
68 regulator-max-microvolt = <1350000>;
69 regulator-always-on;
70 regulator-boot-on;
71 defdcdc_default = <1>;
72 };
73 ldo1_reg: regulator@3 {
74 regulator-compatible = "LDO1";
75 reg = <3>;
76 regulator-min-microvolt = <1710000>;
77 regulator-max-microvolt = <1890000>;
78 regulator-always-on;
79 regulator-boot-on;
80 };
81 ldo2_reg: regulator@4 {
82 regulator-compatible = "LDO2";
83 reg = <4>;
84 regulator-min-microvolt = <1140000>;
85 regulator-max-microvolt = <1320000>;
86 regulator-always-on;
87 regulator-boot-on;
88 };
89 };
90
91 };
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index 0233cfb56560..54aa2da7283b 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -23,8 +23,10 @@
23#include <linux/regulator/driver.h> 23#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h> 24#include <linux/regulator/machine.h>
25#include <linux/regulator/tps6507x.h> 25#include <linux/regulator/tps6507x.h>
26#include <linux/of.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <linux/mfd/tps6507x.h> 28#include <linux/mfd/tps6507x.h>
29#include <linux/regulator/of_regulator.h>
28 30
29/* DCDC's */ 31/* DCDC's */
30#define TPS6507X_DCDC_1 0 32#define TPS6507X_DCDC_1 0
@@ -356,6 +358,80 @@ static struct regulator_ops tps6507x_pmic_ops = {
356 .list_voltage = regulator_list_voltage_table, 358 .list_voltage = regulator_list_voltage_table,
357}; 359};
358 360
361#ifdef CONFIG_OF
362static struct of_regulator_match tps6507x_matches[] = {
363 { .name = "VDCDC1"},
364 { .name = "VDCDC2"},
365 { .name = "VDCDC3"},
366 { .name = "LDO1"},
367 { .name = "LDO2"},
368};
369
370static struct tps6507x_board *tps6507x_parse_dt_reg_data(
371 struct platform_device *pdev,
372 struct of_regulator_match **tps6507x_reg_matches)
373{
374 struct tps6507x_board *tps_board;
375 struct device_node *np = pdev->dev.parent->of_node;
376 struct device_node *regulators;
377 struct of_regulator_match *matches;
378 static struct regulator_init_data *reg_data;
379 int idx = 0, count, ret;
380
381 tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board),
382 GFP_KERNEL);
383 if (!tps_board) {
384 dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n");
385 return NULL;
386 }
387
388 regulators = of_find_node_by_name(np, "regulators");
389 if (!regulators) {
390 dev_err(&pdev->dev, "regulator node not found\n");
391 return NULL;
392 }
393
394 count = ARRAY_SIZE(tps6507x_matches);
395 matches = tps6507x_matches;
396
397 ret = of_regulator_match(&pdev->dev, regulators, matches, count);
398 if (ret < 0) {
399 dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
400 ret);
401 return NULL;
402 }
403
404 *tps6507x_reg_matches = matches;
405
406 reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data)
407 * TPS6507X_NUM_REGULATOR), GFP_KERNEL);
408 if (!reg_data) {
409 dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n");
410 return NULL;
411 }
412
413 tps_board->tps6507x_pmic_init_data = reg_data;
414
415 for (idx = 0; idx < count; idx++) {
416 if (!matches[idx].init_data || !matches[idx].of_node)
417 continue;
418
419 memcpy(&reg_data[idx], matches[idx].init_data,
420 sizeof(struct regulator_init_data));
421
422 }
423
424 return tps_board;
425}
426#else
427static inline struct tps6507x_board *tps6507x_parse_dt_reg_data(
428 struct platform_device *pdev,
429 struct of_regulator_match **tps6507x_reg_matches)
430{
431 *tps6507x_reg_matches = NULL;
432 return NULL;
433}
434#endif
359static int tps6507x_pmic_probe(struct platform_device *pdev) 435static int tps6507x_pmic_probe(struct platform_device *pdev)
360{ 436{
361 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); 437 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
@@ -365,8 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
365 struct regulator_dev *rdev; 441 struct regulator_dev *rdev;
366 struct tps6507x_pmic *tps; 442 struct tps6507x_pmic *tps;
367 struct tps6507x_board *tps_board; 443 struct tps6507x_board *tps_board;
444 struct of_regulator_match *tps6507x_reg_matches = NULL;
368 int i; 445 int i;
369 int error; 446 int error;
447 unsigned int prop;
370 448
371 /** 449 /**
372 * tps_board points to pmic related constants 450 * tps_board points to pmic related constants
@@ -374,6 +452,9 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
374 */ 452 */
375 453
376 tps_board = dev_get_platdata(tps6507x_dev->dev); 454 tps_board = dev_get_platdata(tps6507x_dev->dev);
455 if (!tps_board && tps6507x_dev->dev->of_node)
456 tps_board = tps6507x_parse_dt_reg_data(pdev,
457 &tps6507x_reg_matches);
377 if (!tps_board) 458 if (!tps_board)
378 return -EINVAL; 459 return -EINVAL;
379 460
@@ -415,6 +496,17 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
415 config.init_data = init_data; 496 config.init_data = init_data;
416 config.driver_data = tps; 497 config.driver_data = tps;
417 498
499 if (tps6507x_reg_matches) {
500 error = of_property_read_u32(
501 tps6507x_reg_matches[i].of_node,
502 "ti,defdcdc_default", &prop);
503
504 if (!error)
505 tps->info[i]->defdcdc_default = prop;
506
507 config.of_node = tps6507x_reg_matches[i].of_node;
508 }
509
418 rdev = regulator_register(&tps->desc[i], &config); 510 rdev = regulator_register(&tps->desc[i], &config);
419 if (IS_ERR(rdev)) { 511 if (IS_ERR(rdev)) {
420 dev_err(tps6507x_dev->dev, 512 dev_err(tps6507x_dev->dev,