diff options
author | Thierry Reding <thierry.reding@avionic-design.de> | 2012-04-26 10:52:21 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-04 08:25:16 -0400 |
commit | 62f6b0879304e2169d6bf6221612e8111e342ee7 (patch) | |
tree | 0a87bef6a43043c22146577dd33f82d06bca7b2f /drivers/mfd | |
parent | 1c8fa58f4750e9ad722fbf899866c312ffabab67 (diff) |
tps6586x: Add device tree support
This commit adds device tree support for the TPS6586x regulator.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/tps6586x.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index a5ddf31b60c..c84b5506d5f 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/regulator/of_regulator.h> | ||
26 | 27 | ||
27 | #include <linux/mfd/core.h> | 28 | #include <linux/mfd/core.h> |
28 | #include <linux/mfd/tps6586x.h> | 29 | #include <linux/mfd/tps6586x.h> |
@@ -460,6 +461,7 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, | |||
460 | 461 | ||
461 | pdev->dev.parent = tps6586x->dev; | 462 | pdev->dev.parent = tps6586x->dev; |
462 | pdev->dev.platform_data = subdev->platform_data; | 463 | pdev->dev.platform_data = subdev->platform_data; |
464 | pdev->dev.of_node = subdev->of_node; | ||
463 | 465 | ||
464 | ret = platform_device_add(pdev); | 466 | ret = platform_device_add(pdev); |
465 | if (ret) { | 467 | if (ret) { |
@@ -474,6 +476,86 @@ failed: | |||
474 | return ret; | 476 | return ret; |
475 | } | 477 | } |
476 | 478 | ||
479 | #ifdef CONFIG_OF | ||
480 | static struct of_regulator_match tps6586x_matches[] = { | ||
481 | { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, | ||
482 | { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, | ||
483 | { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, | ||
484 | { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, | ||
485 | { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, | ||
486 | { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, | ||
487 | { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, | ||
488 | { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, | ||
489 | { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, | ||
490 | { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, | ||
491 | { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, | ||
492 | { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, | ||
493 | { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, | ||
494 | { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, | ||
495 | }; | ||
496 | |||
497 | static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) | ||
498 | { | ||
499 | const unsigned int num = ARRAY_SIZE(tps6586x_matches); | ||
500 | struct device_node *np = client->dev.of_node; | ||
501 | struct tps6586x_platform_data *pdata; | ||
502 | struct tps6586x_subdev_info *devs; | ||
503 | struct device_node *regs; | ||
504 | unsigned int count; | ||
505 | unsigned int i, j; | ||
506 | int err; | ||
507 | |||
508 | regs = of_find_node_by_name(np, "regulators"); | ||
509 | if (!regs) | ||
510 | return NULL; | ||
511 | |||
512 | err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); | ||
513 | if (err < 0) { | ||
514 | of_node_put(regs); | ||
515 | return NULL; | ||
516 | } | ||
517 | |||
518 | of_node_put(regs); | ||
519 | count = err; | ||
520 | |||
521 | devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); | ||
522 | if (!devs) | ||
523 | return NULL; | ||
524 | |||
525 | for (i = 0, j = 0; i < num && j < count; i++) { | ||
526 | if (!tps6586x_matches[i].init_data) | ||
527 | continue; | ||
528 | |||
529 | devs[j].name = "tps6586x-regulator"; | ||
530 | devs[j].platform_data = tps6586x_matches[i].init_data; | ||
531 | devs[j].id = (int)tps6586x_matches[i].driver_data; | ||
532 | devs[j].of_node = tps6586x_matches[i].of_node; | ||
533 | j++; | ||
534 | } | ||
535 | |||
536 | pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); | ||
537 | if (!pdata) | ||
538 | return NULL; | ||
539 | |||
540 | pdata->num_subdevs = count; | ||
541 | pdata->subdevs = devs; | ||
542 | pdata->gpio_base = -1; | ||
543 | pdata->irq_base = -1; | ||
544 | |||
545 | return pdata; | ||
546 | } | ||
547 | |||
548 | static struct of_device_id tps6586x_of_match[] = { | ||
549 | { .compatible = "ti,tps6586x", }, | ||
550 | { }, | ||
551 | }; | ||
552 | #else | ||
553 | static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) | ||
554 | { | ||
555 | return NULL; | ||
556 | } | ||
557 | #endif | ||
558 | |||
477 | static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | 559 | static int __devinit tps6586x_i2c_probe(struct i2c_client *client, |
478 | const struct i2c_device_id *id) | 560 | const struct i2c_device_id *id) |
479 | { | 561 | { |
@@ -481,6 +563,9 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
481 | struct tps6586x *tps6586x; | 563 | struct tps6586x *tps6586x; |
482 | int ret; | 564 | int ret; |
483 | 565 | ||
566 | if (!pdata && client->dev.of_node) | ||
567 | pdata = tps6586x_parse_dt(client); | ||
568 | |||
484 | if (!pdata) { | 569 | if (!pdata) { |
485 | dev_err(&client->dev, "tps6586x requires platform data\n"); | 570 | dev_err(&client->dev, "tps6586x requires platform data\n"); |
486 | return -ENOTSUPP; | 571 | return -ENOTSUPP; |
@@ -573,6 +658,7 @@ static struct i2c_driver tps6586x_driver = { | |||
573 | .driver = { | 658 | .driver = { |
574 | .name = "tps6586x", | 659 | .name = "tps6586x", |
575 | .owner = THIS_MODULE, | 660 | .owner = THIS_MODULE, |
661 | .of_match_table = of_match_ptr(tps6586x_of_match), | ||
576 | }, | 662 | }, |
577 | .probe = tps6586x_i2c_probe, | 663 | .probe = tps6586x_i2c_probe, |
578 | .remove = __devexit_p(tps6586x_i2c_remove), | 664 | .remove = __devexit_p(tps6586x_i2c_remove), |