Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thierry Reding and committed by
Mark Brown
62f6b087 1c8fa58f

+185
+97
Documentation/devicetree/bindings/regulator/tps6586x.txt
··· 1 + TPS6586x family of regulators 2 + 3 + Required properties: 4 + - compatible: "ti,tps6586x" 5 + - reg: I2C slave address 6 + - interrupts: the interrupt outputs of the controller 7 + - #gpio-cells: number of cells to describe a GPIO 8 + - gpio-controller: mark the device as a GPIO controller 9 + - regulators: list of regulators provided by this controller, must be named 10 + after their hardware counterparts: sm[0-2], ldo[0-9] and ldo_rtc 11 + 12 + Each regulator is defined using the standard binding for regulators. 13 + 14 + Example: 15 + 16 + pmu: tps6586x@34 { 17 + compatible = "ti,tps6586x"; 18 + reg = <0x34>; 19 + interrupts = <0 88 0x4>; 20 + 21 + #gpio-cells = <2>; 22 + gpio-controller; 23 + 24 + regulators { 25 + sm0_reg: sm0 { 26 + regulator-min-microvolt = < 725000>; 27 + regulator-max-microvolt = <1500000>; 28 + regulator-boot-on; 29 + regulator-always-on; 30 + }; 31 + 32 + sm1_reg: sm1 { 33 + regulator-min-microvolt = < 725000>; 34 + regulator-max-microvolt = <1500000>; 35 + regulator-boot-on; 36 + regulator-always-on; 37 + }; 38 + 39 + sm2_reg: sm2 { 40 + regulator-min-microvolt = <3000000>; 41 + regulator-max-microvolt = <4550000>; 42 + regulator-boot-on; 43 + regulator-always-on; 44 + }; 45 + 46 + ldo0_reg: ldo0 { 47 + regulator-name = "PCIE CLK"; 48 + regulator-min-microvolt = <3300000>; 49 + regulator-max-microvolt = <3300000>; 50 + }; 51 + 52 + ldo1_reg: ldo1 { 53 + regulator-min-microvolt = < 725000>; 54 + regulator-max-microvolt = <1500000>; 55 + }; 56 + 57 + ldo2_reg: ldo2 { 58 + regulator-min-microvolt = < 725000>; 59 + regulator-max-microvolt = <1500000>; 60 + }; 61 + 62 + ldo3_reg: ldo3 { 63 + regulator-min-microvolt = <1250000>; 64 + regulator-max-microvolt = <3300000>; 65 + }; 66 + 67 + ldo4_reg: ldo4 { 68 + regulator-min-microvolt = <1700000>; 69 + regulator-max-microvolt = <2475000>; 70 + }; 71 + 72 + ldo5_reg: ldo5 { 73 + regulator-min-microvolt = <1250000>; 74 + regulator-max-microvolt = <3300000>; 75 + }; 76 + 77 + ldo6_reg: ldo6 { 78 + regulator-min-microvolt = <1250000>; 79 + regulator-max-microvolt = <3300000>; 80 + }; 81 + 82 + ldo7_reg: ldo7 { 83 + regulator-min-microvolt = <1250000>; 84 + regulator-max-microvolt = <3300000>; 85 + }; 86 + 87 + ldo8_reg: ldo8 { 88 + regulator-min-microvolt = <1250000>; 89 + regulator-max-microvolt = <3300000>; 90 + }; 91 + 92 + ldo9_reg: ldo9 { 93 + regulator-min-microvolt = <1250000>; 94 + regulator-max-microvolt = <3300000>; 95 + }; 96 + }; 97 + };
+86
drivers/mfd/tps6586x.c
··· 23 23 #include <linux/slab.h> 24 24 #include <linux/gpio.h> 25 25 #include <linux/i2c.h> 26 + #include <linux/regulator/of_regulator.h> 26 27 27 28 #include <linux/mfd/core.h> 28 29 #include <linux/mfd/tps6586x.h> ··· 461 460 462 461 pdev->dev.parent = tps6586x->dev; 463 462 pdev->dev.platform_data = subdev->platform_data; 463 + pdev->dev.of_node = subdev->of_node; 464 464 465 465 ret = platform_device_add(pdev); 466 466 if (ret) { ··· 476 474 return ret; 477 475 } 478 476 477 + #ifdef CONFIG_OF 478 + static struct of_regulator_match tps6586x_matches[] = { 479 + { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, 480 + { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, 481 + { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, 482 + { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, 483 + { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, 484 + { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, 485 + { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, 486 + { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, 487 + { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, 488 + { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, 489 + { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, 490 + { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, 491 + { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, 492 + { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, 493 + }; 494 + 495 + static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) 496 + { 497 + const unsigned int num = ARRAY_SIZE(tps6586x_matches); 498 + struct device_node *np = client->dev.of_node; 499 + struct tps6586x_platform_data *pdata; 500 + struct tps6586x_subdev_info *devs; 501 + struct device_node *regs; 502 + unsigned int count; 503 + unsigned int i, j; 504 + int err; 505 + 506 + regs = of_find_node_by_name(np, "regulators"); 507 + if (!regs) 508 + return NULL; 509 + 510 + err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); 511 + if (err < 0) { 512 + of_node_put(regs); 513 + return NULL; 514 + } 515 + 516 + of_node_put(regs); 517 + count = err; 518 + 519 + devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); 520 + if (!devs) 521 + return NULL; 522 + 523 + for (i = 0, j = 0; i < num && j < count; i++) { 524 + if (!tps6586x_matches[i].init_data) 525 + continue; 526 + 527 + devs[j].name = "tps6586x-regulator"; 528 + devs[j].platform_data = tps6586x_matches[i].init_data; 529 + devs[j].id = (int)tps6586x_matches[i].driver_data; 530 + devs[j].of_node = tps6586x_matches[i].of_node; 531 + j++; 532 + } 533 + 534 + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 535 + if (!pdata) 536 + return NULL; 537 + 538 + pdata->num_subdevs = count; 539 + pdata->subdevs = devs; 540 + pdata->gpio_base = -1; 541 + pdata->irq_base = -1; 542 + 543 + return pdata; 544 + } 545 + 546 + static struct of_device_id tps6586x_of_match[] = { 547 + { .compatible = "ti,tps6586x", }, 548 + { }, 549 + }; 550 + #else 551 + static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) 552 + { 553 + return NULL; 554 + } 555 + #endif 556 + 479 557 static int __devinit tps6586x_i2c_probe(struct i2c_client *client, 480 558 const struct i2c_device_id *id) 481 559 { 482 560 struct tps6586x_platform_data *pdata = client->dev.platform_data; 483 561 struct tps6586x *tps6586x; 484 562 int ret; 563 + 564 + if (!pdata && client->dev.of_node) 565 + pdata = tps6586x_parse_dt(client); 485 566 486 567 if (!pdata) { 487 568 dev_err(&client->dev, "tps6586x requires platform data\n"); ··· 658 573 .driver = { 659 574 .name = "tps6586x", 660 575 .owner = THIS_MODULE, 576 + .of_match_table = of_match_ptr(tps6586x_of_match), 661 577 }, 662 578 .probe = tps6586x_i2c_probe, 663 579 .remove = __devexit_p(tps6586x_i2c_remove),
+1
drivers/regulator/tps6586x-regulator.c
··· 363 363 return err; 364 364 365 365 config.dev = &pdev->dev; 366 + config.of_node = pdev->dev.of_node; 366 367 config.init_data = pdev->dev.platform_data; 367 368 config.driver_data = ri; 368 369
+1
include/linux/mfd/tps6586x.h
··· 68 68 int id; 69 69 const char *name; 70 70 void *platform_data; 71 + struct device_node *of_node; 71 72 }; 72 73 73 74 struct tps6586x_platform_data {