diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/tps6507x-regulator.c | 92 |
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 | ||
362 | static struct of_regulator_match tps6507x_matches[] = { | ||
363 | { .name = "VDCDC1"}, | ||
364 | { .name = "VDCDC2"}, | ||
365 | { .name = "VDCDC3"}, | ||
366 | { .name = "LDO1"}, | ||
367 | { .name = "LDO2"}, | ||
368 | }; | ||
369 | |||
370 | static 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(®_data[idx], matches[idx].init_data, | ||
420 | sizeof(struct regulator_init_data)); | ||
421 | |||
422 | } | ||
423 | |||
424 | return tps_board; | ||
425 | } | ||
426 | #else | ||
427 | static 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 | ||
359 | static int tps6507x_pmic_probe(struct platform_device *pdev) | 435 | static 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, |