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

Merge remote-tracking branch 'regulator/topic/tps6507x' into regulator-next

+183
+91
Documentation/devicetree/bindings/mfd/tps6507x.txt
··· 1 + TPS6507x Power Management Integrated Circuit 2 + 3 + Required 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 + 27 + Regulator 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 + 33 + Example: 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 + };
+92
drivers/regulator/tps6507x-regulator.c
··· 23 23 #include <linux/regulator/driver.h> 24 24 #include <linux/regulator/machine.h> 25 25 #include <linux/regulator/tps6507x.h> 26 + #include <linux/of.h> 26 27 #include <linux/slab.h> 27 28 #include <linux/mfd/tps6507x.h> 29 + #include <linux/regulator/of_regulator.h> 28 30 29 31 /* DCDC's */ 30 32 #define TPS6507X_DCDC_1 0 ··· 358 356 .list_voltage = regulator_list_voltage_table, 359 357 }; 360 358 359 + #ifdef CONFIG_OF 360 + static struct of_regulator_match tps6507x_matches[] = { 361 + { .name = "VDCDC1"}, 362 + { .name = "VDCDC2"}, 363 + { .name = "VDCDC3"}, 364 + { .name = "LDO1"}, 365 + { .name = "LDO2"}, 366 + }; 367 + 368 + static struct tps6507x_board *tps6507x_parse_dt_reg_data( 369 + struct platform_device *pdev, 370 + struct of_regulator_match **tps6507x_reg_matches) 371 + { 372 + struct tps6507x_board *tps_board; 373 + struct device_node *np = pdev->dev.parent->of_node; 374 + struct device_node *regulators; 375 + struct of_regulator_match *matches; 376 + static struct regulator_init_data *reg_data; 377 + int idx = 0, count, ret; 378 + 379 + tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), 380 + GFP_KERNEL); 381 + if (!tps_board) { 382 + dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); 383 + return NULL; 384 + } 385 + 386 + regulators = of_find_node_by_name(np, "regulators"); 387 + if (!regulators) { 388 + dev_err(&pdev->dev, "regulator node not found\n"); 389 + return NULL; 390 + } 391 + 392 + count = ARRAY_SIZE(tps6507x_matches); 393 + matches = tps6507x_matches; 394 + 395 + ret = of_regulator_match(&pdev->dev, regulators, matches, count); 396 + if (ret < 0) { 397 + dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", 398 + ret); 399 + return NULL; 400 + } 401 + 402 + *tps6507x_reg_matches = matches; 403 + 404 + reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) 405 + * TPS6507X_NUM_REGULATOR), GFP_KERNEL); 406 + if (!reg_data) { 407 + dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n"); 408 + return NULL; 409 + } 410 + 411 + tps_board->tps6507x_pmic_init_data = reg_data; 412 + 413 + for (idx = 0; idx < count; idx++) { 414 + if (!matches[idx].init_data || !matches[idx].of_node) 415 + continue; 416 + 417 + memcpy(&reg_data[idx], matches[idx].init_data, 418 + sizeof(struct regulator_init_data)); 419 + 420 + } 421 + 422 + return tps_board; 423 + } 424 + #else 425 + static inline struct tps6507x_board *tps6507x_parse_dt_reg_data( 426 + struct platform_device *pdev, 427 + struct of_regulator_match **tps6507x_reg_matches) 428 + { 429 + *tps6507x_reg_matches = NULL; 430 + return NULL; 431 + } 432 + #endif 361 433 static int tps6507x_pmic_probe(struct platform_device *pdev) 362 434 { 363 435 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); ··· 441 365 struct regulator_dev *rdev; 442 366 struct tps6507x_pmic *tps; 443 367 struct tps6507x_board *tps_board; 368 + struct of_regulator_match *tps6507x_reg_matches = NULL; 444 369 int i; 445 370 int error; 371 + unsigned int prop; 446 372 447 373 /** 448 374 * tps_board points to pmic related constants ··· 452 374 */ 453 375 454 376 tps_board = dev_get_platdata(tps6507x_dev->dev); 377 + if (!tps_board && tps6507x_dev->dev->of_node) 378 + tps_board = tps6507x_parse_dt_reg_data(pdev, 379 + &tps6507x_reg_matches); 455 380 if (!tps_board) 456 381 return -EINVAL; 457 382 ··· 495 414 config.dev = tps6507x_dev->dev; 496 415 config.init_data = init_data; 497 416 config.driver_data = tps; 417 + 418 + if (tps6507x_reg_matches) { 419 + error = of_property_read_u32( 420 + tps6507x_reg_matches[i].of_node, 421 + "ti,defdcdc_default", &prop); 422 + 423 + if (!error) 424 + tps->info[i]->defdcdc_default = prop; 425 + 426 + config.of_node = tps6507x_reg_matches[i].of_node; 427 + } 498 428 499 429 rdev = regulator_register(&tps->desc[i], &config); 500 430 if (IS_ERR(rdev)) {