aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
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 /drivers/regulator
parentb67a2ecb540b3ac08c962742d2142104390ff60c (diff)
parent0ce7d00d0d7bc04d917b8775da177dde962ce17e (diff)
Merge remote-tracking branch 'regulator/topic/tps6507x' into regulator-next
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/tps6507x-regulator.c92
1 files changed, 92 insertions, 0 deletions
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,