diff options
Diffstat (limited to 'drivers/regulator')
51 files changed, 2216 insertions, 670 deletions
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index d333f7eac106..7a721d67e6ac 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c | |||
| @@ -310,10 +310,8 @@ static int pm800_regulator_probe(struct platform_device *pdev) | |||
| 310 | 310 | ||
| 311 | pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), | 311 | pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), |
| 312 | GFP_KERNEL); | 312 | GFP_KERNEL); |
| 313 | if (!pm800_data) { | 313 | if (!pm800_data) |
| 314 | dev_err(&pdev->dev, "Failed to allocate pm800_regualtors"); | ||
| 315 | return -ENOMEM; | 314 | return -ENOMEM; |
| 316 | } | ||
| 317 | 315 | ||
| 318 | pm800_data->map = chip->subchip->regmap_power; | 316 | pm800_data->map = chip->subchip->regmap_power; |
| 319 | pm800_data->chip = chip; | 317 | pm800_data->chip = chip; |
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index f704d83c93c4..337634ad0562 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Regulators driver for Marvell 88PM8607 | 2 | * Regulators driver for Marvell 88PM8607 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Marvell International Ltd. | 4 | * Copyright (C) 2009 Marvell International Ltd. |
| 5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | 5 | * Haojian Zhuang <haojian.zhuang@marvell.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -78,7 +78,7 @@ static const unsigned int BUCK2_suspend_table[] = { | |||
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | static const unsigned int BUCK3_table[] = { | 80 | static const unsigned int BUCK3_table[] = { |
| 81 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, | 81 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, |
| 82 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, | 82 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, |
| 83 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, | 83 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, |
| 84 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, | 84 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, |
| @@ -89,7 +89,7 @@ static const unsigned int BUCK3_table[] = { | |||
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | static const unsigned int BUCK3_suspend_table[] = { | 91 | static const unsigned int BUCK3_suspend_table[] = { |
| 92 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, | 92 | 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, |
| 93 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, | 93 | 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, |
| 94 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, | 94 | 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, |
| 95 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, | 95 | 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, |
| @@ -322,7 +322,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev, | |||
| 322 | nproot = of_node_get(pdev->dev.parent->of_node); | 322 | nproot = of_node_get(pdev->dev.parent->of_node); |
| 323 | if (!nproot) | 323 | if (!nproot) |
| 324 | return -ENODEV; | 324 | return -ENODEV; |
| 325 | nproot = of_find_node_by_name(nproot, "regulators"); | 325 | nproot = of_get_child_by_name(nproot, "regulators"); |
| 326 | if (!nproot) { | 326 | if (!nproot) { |
| 327 | dev_err(&pdev->dev, "failed to find regulators node\n"); | 327 | dev_err(&pdev->dev, "failed to find regulators node\n"); |
| 328 | return -ENODEV; | 328 | return -ENODEV; |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 6a7932822e37..8f3866c44a3f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -139,6 +139,14 @@ config REGULATOR_AS3722 | |||
| 139 | AS3722 PMIC. This will enable support for all the software | 139 | AS3722 PMIC. This will enable support for all the software |
| 140 | controllable DCDC/LDO regulators. | 140 | controllable DCDC/LDO regulators. |
| 141 | 141 | ||
| 142 | config REGULATOR_BCM590XX | ||
| 143 | tristate "Broadcom BCM590xx PMU Regulators" | ||
| 144 | depends on MFD_BCM590XX | ||
| 145 | help | ||
| 146 | This driver provides support for the voltage regulators on the | ||
| 147 | BCM590xx PMUs. This will enable support for the software | ||
| 148 | controllable LDO/Switching regulators. | ||
| 149 | |||
| 142 | config REGULATOR_DA903X | 150 | config REGULATOR_DA903X |
| 143 | tristate "Dialog Semiconductor DA9030/DA9034 regulators" | 151 | tristate "Dialog Semiconductor DA9030/DA9034 regulators" |
| 144 | depends on PMIC_DA903X | 152 | depends on PMIC_DA903X |
| @@ -399,12 +407,12 @@ config REGULATOR_PCF50633 | |||
| 399 | on PCF50633 | 407 | on PCF50633 |
| 400 | 408 | ||
| 401 | config REGULATOR_PFUZE100 | 409 | config REGULATOR_PFUZE100 |
| 402 | tristate "Freescale PFUZE100 regulator driver" | 410 | tristate "Freescale PFUZE100/PFUZE200 regulator driver" |
| 403 | depends on I2C | 411 | depends on I2C |
| 404 | select REGMAP_I2C | 412 | select REGMAP_I2C |
| 405 | help | 413 | help |
| 406 | Say y here to support the regulators found on the Freescale PFUZE100 | 414 | Say y here to support the regulators found on the Freescale |
| 407 | PMIC. | 415 | PFUZE100/PFUZE200 PMIC. |
| 408 | 416 | ||
| 409 | config REGULATOR_RC5T583 | 417 | config REGULATOR_RC5T583 |
| 410 | tristate "RICOH RC5T583 Power regulators" | 418 | tristate "RICOH RC5T583 Power regulators" |
| @@ -416,13 +424,21 @@ config REGULATOR_RC5T583 | |||
| 416 | through regulator interface. The device supports multiple DCDC/LDO | 424 | through regulator interface. The device supports multiple DCDC/LDO |
| 417 | outputs which can be controlled by i2c communication. | 425 | outputs which can be controlled by i2c communication. |
| 418 | 426 | ||
| 427 | config REGULATOR_S2MPA01 | ||
| 428 | tristate "Samsung S2MPA01 voltage regulator" | ||
| 429 | depends on MFD_SEC_CORE | ||
| 430 | help | ||
| 431 | This driver controls Samsung S2MPA01 voltage output regulator | ||
| 432 | via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. | ||
| 433 | |||
| 419 | config REGULATOR_S2MPS11 | 434 | config REGULATOR_S2MPS11 |
| 420 | tristate "Samsung S2MPS11 voltage regulator" | 435 | tristate "Samsung S2MPS11/S2MPS14 voltage regulator" |
| 421 | depends on MFD_SEC_CORE | 436 | depends on MFD_SEC_CORE |
| 422 | help | 437 | help |
| 423 | This driver supports a Samsung S2MPS11 voltage output regulator | 438 | This driver supports a Samsung S2MPS11/S2MPS14 voltage output |
| 424 | via I2C bus. S2MPS11 is comprised of high efficient Buck converters | 439 | regulator via I2C bus. The chip is comprised of high efficient Buck |
| 425 | including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. | 440 | converters including Dual-Phase Buck converter, Buck-Boost converter, |
| 441 | various LDOs. | ||
| 426 | 442 | ||
| 427 | config REGULATOR_S5M8767 | 443 | config REGULATOR_S5M8767 |
| 428 | tristate "Samsung S5M8767A voltage regulator" | 444 | tristate "Samsung S5M8767A voltage regulator" |
| @@ -432,6 +448,12 @@ config REGULATOR_S5M8767 | |||
| 432 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and | 448 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and |
| 433 | supports DVS mode with 8bits of output voltage control. | 449 | supports DVS mode with 8bits of output voltage control. |
| 434 | 450 | ||
| 451 | config REGULATOR_ST_PWM | ||
| 452 | tristate "STMicroelectronics PWM voltage regulator" | ||
| 453 | depends on ARCH_STI | ||
| 454 | help | ||
| 455 | This driver supports ST's PWM controlled voltage regulators. | ||
| 456 | |||
| 435 | config REGULATOR_TI_ABB | 457 | config REGULATOR_TI_ABB |
| 436 | tristate "TI Adaptive Body Bias on-chip LDO" | 458 | tristate "TI Adaptive Body Bias on-chip LDO" |
| 437 | depends on ARCH_OMAP | 459 | depends on ARCH_OMAP |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 979f9ddcf259..0cfca37941ec 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
| @@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | |||
| 20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o | 20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o |
| 21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o | 21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o |
| 22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o | 22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o |
| 23 | obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o | ||
| 23 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 24 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
| 24 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 25 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
| 25 | obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o | 26 | obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o |
| @@ -57,8 +58,10 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | |||
| 57 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 58 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
| 58 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 59 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
| 59 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 60 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
| 61 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o | ||
| 60 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o | 62 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
| 61 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | 63 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
| 64 | obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o | ||
| 62 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o | 65 | obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o |
| 63 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o | 66 | obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o |
| 64 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o | 67 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o |
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index f70a9bfa5ff2..c873ee0082cf 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c | |||
| @@ -99,6 +99,7 @@ static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) | |||
| 99 | 99 | ||
| 100 | static struct regulator_ops aat2870_ldo_ops = { | 100 | static struct regulator_ops aat2870_ldo_ops = { |
| 101 | .list_voltage = regulator_list_voltage_table, | 101 | .list_voltage = regulator_list_voltage_table, |
| 102 | .map_voltage = regulator_map_voltage_ascend, | ||
| 102 | .set_voltage_sel = aat2870_ldo_set_voltage_sel, | 103 | .set_voltage_sel = aat2870_ldo_set_voltage_sel, |
| 103 | .get_voltage_sel = aat2870_ldo_get_voltage_sel, | 104 | .get_voltage_sel = aat2870_ldo_get_voltage_sel, |
| 104 | .enable = aat2870_ldo_enable, | 105 | .enable = aat2870_ldo_enable, |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 77b46d0b37a6..e10febe9ec34 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
| @@ -498,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev, | |||
| 498 | struct ab3100_platform_data *plfdata, | 498 | struct ab3100_platform_data *plfdata, |
| 499 | struct regulator_init_data *init_data, | 499 | struct regulator_init_data *init_data, |
| 500 | struct device_node *np, | 500 | struct device_node *np, |
| 501 | int id) | 501 | unsigned long id) |
| 502 | { | 502 | { |
| 503 | struct regulator_desc *desc; | 503 | struct regulator_desc *desc; |
| 504 | struct ab3100_regulator *reg; | 504 | struct ab3100_regulator *reg; |
| @@ -646,7 +646,7 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) | |||
| 646 | err = ab3100_regulator_register( | 646 | err = ab3100_regulator_register( |
| 647 | pdev, NULL, ab3100_regulator_matches[i].init_data, | 647 | pdev, NULL, ab3100_regulator_matches[i].init_data, |
| 648 | ab3100_regulator_matches[i].of_node, | 648 | ab3100_regulator_matches[i].of_node, |
| 649 | (int) ab3100_regulator_matches[i].driver_data); | 649 | (unsigned long)ab3100_regulator_matches[i].driver_data); |
| 650 | if (err) { | 650 | if (err) { |
| 651 | ab3100_regulators_remove(pdev); | 651 | ab3100_regulators_remove(pdev); |
| 652 | return err; | 652 | return err; |
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 084cc0819a52..b92d7dd01a18 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c | |||
| @@ -62,7 +62,6 @@ | |||
| 62 | #define ACT8865_VOLTAGE_NUM 64 | 62 | #define ACT8865_VOLTAGE_NUM 64 |
| 63 | 63 | ||
| 64 | struct act8865 { | 64 | struct act8865 { |
| 65 | struct regulator_dev *rdev[ACT8865_REG_NUM]; | ||
| 66 | struct regmap *regmap; | 65 | struct regmap *regmap; |
| 67 | }; | 66 | }; |
| 68 | 67 | ||
| @@ -213,7 +212,7 @@ static int act8865_pdata_from_dt(struct device *dev, | |||
| 213 | struct device_node *np; | 212 | struct device_node *np; |
| 214 | struct act8865_regulator_data *regulator; | 213 | struct act8865_regulator_data *regulator; |
| 215 | 214 | ||
| 216 | np = of_find_node_by_name(dev->of_node, "regulators"); | 215 | np = of_get_child_by_name(dev->of_node, "regulators"); |
| 217 | if (!np) { | 216 | if (!np) { |
| 218 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | 217 | dev_err(dev, "missing 'regulators' subnode in DT\n"); |
| 219 | return -EINVAL; | 218 | return -EINVAL; |
| @@ -221,17 +220,15 @@ static int act8865_pdata_from_dt(struct device *dev, | |||
| 221 | 220 | ||
| 222 | matched = of_regulator_match(dev, np, | 221 | matched = of_regulator_match(dev, np, |
| 223 | act8865_matches, ARRAY_SIZE(act8865_matches)); | 222 | act8865_matches, ARRAY_SIZE(act8865_matches)); |
| 223 | of_node_put(np); | ||
| 224 | if (matched <= 0) | 224 | if (matched <= 0) |
| 225 | return matched; | 225 | return matched; |
| 226 | 226 | ||
| 227 | pdata->regulators = devm_kzalloc(dev, | 227 | pdata->regulators = devm_kzalloc(dev, |
| 228 | sizeof(struct act8865_regulator_data) * | 228 | sizeof(struct act8865_regulator_data) * |
| 229 | ARRAY_SIZE(act8865_matches), GFP_KERNEL); | 229 | ARRAY_SIZE(act8865_matches), GFP_KERNEL); |
| 230 | if (!pdata->regulators) { | 230 | if (!pdata->regulators) |
| 231 | dev_err(dev, "%s: failed to allocate act8865 registor\n", | ||
| 232 | __func__); | ||
| 233 | return -ENOMEM; | 231 | return -ENOMEM; |
| 234 | } | ||
| 235 | 232 | ||
| 236 | pdata->num_regulators = matched; | 233 | pdata->num_regulators = matched; |
| 237 | regulator = pdata->regulators; | 234 | regulator = pdata->regulators; |
| @@ -258,7 +255,7 @@ static inline int act8865_pdata_from_dt(struct device *dev, | |||
| 258 | static int act8865_pmic_probe(struct i2c_client *client, | 255 | static int act8865_pmic_probe(struct i2c_client *client, |
| 259 | const struct i2c_device_id *i2c_id) | 256 | const struct i2c_device_id *i2c_id) |
| 260 | { | 257 | { |
| 261 | struct regulator_dev **rdev; | 258 | struct regulator_dev *rdev; |
| 262 | struct device *dev = &client->dev; | 259 | struct device *dev = &client->dev; |
| 263 | struct act8865_platform_data *pdata = dev_get_platdata(dev); | 260 | struct act8865_platform_data *pdata = dev_get_platdata(dev); |
| 264 | struct regulator_config config = { }; | 261 | struct regulator_config config = { }; |
| @@ -292,8 +289,6 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
| 292 | if (!act8865) | 289 | if (!act8865) |
| 293 | return -ENOMEM; | 290 | return -ENOMEM; |
| 294 | 291 | ||
| 295 | rdev = act8865->rdev; | ||
| 296 | |||
| 297 | act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); | 292 | act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); |
| 298 | if (IS_ERR(act8865->regmap)) { | 293 | if (IS_ERR(act8865->regmap)) { |
| 299 | error = PTR_ERR(act8865->regmap); | 294 | error = PTR_ERR(act8865->regmap); |
| @@ -313,12 +308,12 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
| 313 | config.driver_data = act8865; | 308 | config.driver_data = act8865; |
| 314 | config.regmap = act8865->regmap; | 309 | config.regmap = act8865->regmap; |
| 315 | 310 | ||
| 316 | rdev[i] = devm_regulator_register(&client->dev, | 311 | rdev = devm_regulator_register(&client->dev, &act8865_reg[i], |
| 317 | &act8865_reg[i], &config); | 312 | &config); |
| 318 | if (IS_ERR(rdev[i])) { | 313 | if (IS_ERR(rdev)) { |
| 319 | dev_err(dev, "failed to register %s\n", | 314 | dev_err(dev, "failed to register %s\n", |
| 320 | act8865_reg[id].name); | 315 | act8865_reg[id].name); |
| 321 | return PTR_ERR(rdev[i]); | 316 | return PTR_ERR(rdev); |
| 322 | } | 317 | } |
| 323 | } | 318 | } |
| 324 | 319 | ||
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 862e63e451d0..7c397bb81e01 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ | 34 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ |
| 35 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ | 35 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ |
| 36 | 36 | ||
| 37 | #define LDO_POWER_GATE 0x00 | ||
| 38 | #define LDO_FET_FULL_ON 0x1f | ||
| 39 | |||
| 37 | struct anatop_regulator { | 40 | struct anatop_regulator { |
| 38 | const char *name; | 41 | const char *name; |
| 39 | u32 control_reg; | 42 | u32 control_reg; |
| @@ -48,19 +51,10 @@ struct anatop_regulator { | |||
| 48 | int max_voltage; | 51 | int max_voltage; |
| 49 | struct regulator_desc rdesc; | 52 | struct regulator_desc rdesc; |
| 50 | struct regulator_init_data *initdata; | 53 | struct regulator_init_data *initdata; |
| 54 | bool bypass; | ||
| 55 | int sel; | ||
| 51 | }; | 56 | }; |
| 52 | 57 | ||
| 53 | static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, | ||
| 54 | unsigned selector) | ||
| 55 | { | ||
| 56 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 57 | |||
| 58 | if (!anatop_reg->control_reg) | ||
| 59 | return -ENOTSUPP; | ||
| 60 | |||
| 61 | return regulator_set_voltage_sel_regmap(reg, selector); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, | 58 | static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, |
| 65 | unsigned int old_sel, | 59 | unsigned int old_sel, |
| 66 | unsigned int new_sel) | 60 | unsigned int new_sel) |
| @@ -87,22 +81,99 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, | |||
| 87 | return ret; | 81 | return ret; |
| 88 | } | 82 | } |
| 89 | 83 | ||
| 90 | static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) | 84 | static int anatop_regmap_enable(struct regulator_dev *reg) |
| 91 | { | 85 | { |
| 92 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 86 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
| 87 | int sel; | ||
| 93 | 88 | ||
| 94 | if (!anatop_reg->control_reg) | 89 | sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel; |
| 95 | return -ENOTSUPP; | 90 | return regulator_set_voltage_sel_regmap(reg, sel); |
| 91 | } | ||
| 92 | |||
| 93 | static int anatop_regmap_disable(struct regulator_dev *reg) | ||
| 94 | { | ||
| 95 | return regulator_set_voltage_sel_regmap(reg, LDO_POWER_GATE); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int anatop_regmap_is_enabled(struct regulator_dev *reg) | ||
| 99 | { | ||
| 100 | return regulator_get_voltage_sel_regmap(reg) != LDO_POWER_GATE; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg, | ||
| 104 | unsigned selector) | ||
| 105 | { | ||
| 106 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 107 | int ret; | ||
| 108 | |||
| 109 | if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) { | ||
| 110 | anatop_reg->sel = selector; | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | ret = regulator_set_voltage_sel_regmap(reg, selector); | ||
| 115 | if (!ret) | ||
| 116 | anatop_reg->sel = selector; | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg) | ||
| 121 | { | ||
| 122 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 123 | |||
| 124 | if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) | ||
| 125 | return anatop_reg->sel; | ||
| 96 | 126 | ||
| 97 | return regulator_get_voltage_sel_regmap(reg); | 127 | return regulator_get_voltage_sel_regmap(reg); |
| 98 | } | 128 | } |
| 99 | 129 | ||
| 130 | static int anatop_regmap_get_bypass(struct regulator_dev *reg, bool *enable) | ||
| 131 | { | ||
| 132 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 133 | int sel; | ||
| 134 | |||
| 135 | sel = regulator_get_voltage_sel_regmap(reg); | ||
| 136 | if (sel == LDO_FET_FULL_ON) | ||
| 137 | WARN_ON(!anatop_reg->bypass); | ||
| 138 | else if (sel != LDO_POWER_GATE) | ||
| 139 | WARN_ON(anatop_reg->bypass); | ||
| 140 | |||
| 141 | *enable = anatop_reg->bypass; | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable) | ||
| 146 | { | ||
| 147 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
| 148 | int sel; | ||
| 149 | |||
| 150 | if (enable == anatop_reg->bypass) | ||
| 151 | return 0; | ||
| 152 | |||
| 153 | sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel; | ||
| 154 | anatop_reg->bypass = enable; | ||
| 155 | |||
| 156 | return regulator_set_voltage_sel_regmap(reg, sel); | ||
| 157 | } | ||
| 158 | |||
| 100 | static struct regulator_ops anatop_rops = { | 159 | static struct regulator_ops anatop_rops = { |
| 101 | .set_voltage_sel = anatop_regmap_set_voltage_sel, | 160 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 161 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 162 | .list_voltage = regulator_list_voltage_linear, | ||
| 163 | .map_voltage = regulator_map_voltage_linear, | ||
| 164 | }; | ||
| 165 | |||
| 166 | static struct regulator_ops anatop_core_rops = { | ||
| 167 | .enable = anatop_regmap_enable, | ||
| 168 | .disable = anatop_regmap_disable, | ||
| 169 | .is_enabled = anatop_regmap_is_enabled, | ||
| 170 | .set_voltage_sel = anatop_regmap_core_set_voltage_sel, | ||
| 102 | .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, | 171 | .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, |
| 103 | .get_voltage_sel = anatop_regmap_get_voltage_sel, | 172 | .get_voltage_sel = anatop_regmap_core_get_voltage_sel, |
| 104 | .list_voltage = regulator_list_voltage_linear, | 173 | .list_voltage = regulator_list_voltage_linear, |
| 105 | .map_voltage = regulator_map_voltage_linear, | 174 | .map_voltage = regulator_map_voltage_linear, |
| 175 | .get_bypass = anatop_regmap_get_bypass, | ||
| 176 | .set_bypass = anatop_regmap_set_bypass, | ||
| 106 | }; | 177 | }; |
| 107 | 178 | ||
| 108 | static int anatop_regulator_probe(struct platform_device *pdev) | 179 | static int anatop_regulator_probe(struct platform_device *pdev) |
| @@ -116,6 +187,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 116 | struct regulator_init_data *initdata; | 187 | struct regulator_init_data *initdata; |
| 117 | struct regulator_config config = { }; | 188 | struct regulator_config config = { }; |
| 118 | int ret = 0; | 189 | int ret = 0; |
| 190 | u32 val; | ||
| 119 | 191 | ||
| 120 | initdata = of_get_regulator_init_data(dev, np); | 192 | initdata = of_get_regulator_init_data(dev, np); |
| 121 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); | 193 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); |
| @@ -125,7 +197,6 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 125 | sreg->name = of_get_property(np, "regulator-name", NULL); | 197 | sreg->name = of_get_property(np, "regulator-name", NULL); |
| 126 | rdesc = &sreg->rdesc; | 198 | rdesc = &sreg->rdesc; |
| 127 | rdesc->name = sreg->name; | 199 | rdesc->name = sreg->name; |
| 128 | rdesc->ops = &anatop_rops; | ||
| 129 | rdesc->type = REGULATOR_VOLTAGE; | 200 | rdesc->type = REGULATOR_VOLTAGE; |
| 130 | rdesc->owner = THIS_MODULE; | 201 | rdesc->owner = THIS_MODULE; |
| 131 | 202 | ||
| @@ -197,6 +268,25 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
| 197 | config.of_node = pdev->dev.of_node; | 268 | config.of_node = pdev->dev.of_node; |
| 198 | config.regmap = sreg->anatop; | 269 | config.regmap = sreg->anatop; |
| 199 | 270 | ||
| 271 | /* Only core regulators have the ramp up delay configuration. */ | ||
| 272 | if (sreg->control_reg && sreg->delay_bit_width) { | ||
| 273 | rdesc->ops = &anatop_core_rops; | ||
| 274 | |||
| 275 | ret = regmap_read(config.regmap, rdesc->vsel_reg, &val); | ||
| 276 | if (ret) { | ||
| 277 | dev_err(dev, "failed to read initial state\n"); | ||
| 278 | return ret; | ||
| 279 | } | ||
| 280 | |||
| 281 | sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift; | ||
| 282 | if (sreg->sel == LDO_FET_FULL_ON) { | ||
| 283 | sreg->sel = 0; | ||
| 284 | sreg->bypass = true; | ||
| 285 | } | ||
| 286 | } else { | ||
| 287 | rdesc->ops = &anatop_rops; | ||
| 288 | } | ||
| 289 | |||
| 200 | /* register regulator */ | 290 | /* register regulator */ |
| 201 | rdev = devm_regulator_register(dev, rdesc, &config); | 291 | rdev = devm_regulator_register(dev, rdesc, &config); |
| 202 | if (IS_ERR(rdev)) { | 292 | if (IS_ERR(rdev)) { |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4f6c2055f6b2..b1033d30b504 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
| @@ -153,11 +153,9 @@ static const struct regulator_desc arizona_ldo1 = { | |||
| 153 | 153 | ||
| 154 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, | 154 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, |
| 155 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, | 155 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, |
| 156 | .bypass_reg = ARIZONA_LDO1_CONTROL_1, | ||
| 157 | .bypass_mask = ARIZONA_LDO1_BYPASS, | ||
| 158 | .min_uV = 900000, | 156 | .min_uV = 900000, |
| 159 | .uV_step = 50000, | 157 | .uV_step = 25000, |
| 160 | .n_voltages = 7, | 158 | .n_voltages = 13, |
| 161 | .enable_time = 500, | 159 | .enable_time = 500, |
| 162 | 160 | ||
| 163 | .owner = THIS_MODULE, | 161 | .owner = THIS_MODULE, |
| @@ -189,10 +187,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
| 189 | int ret; | 187 | int ret; |
| 190 | 188 | ||
| 191 | ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); | 189 | ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); |
| 192 | if (ldo1 == NULL) { | 190 | if (!ldo1) |
| 193 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 194 | return -ENOMEM; | 191 | return -ENOMEM; |
| 195 | } | ||
| 196 | 192 | ||
| 197 | ldo1->arizona = arizona; | 193 | ldo1->arizona = arizona; |
| 198 | 194 | ||
| @@ -203,6 +199,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
| 203 | */ | 199 | */ |
| 204 | switch (arizona->type) { | 200 | switch (arizona->type) { |
| 205 | case WM5102: | 201 | case WM5102: |
| 202 | case WM8997: | ||
| 206 | desc = &arizona_ldo1_hc; | 203 | desc = &arizona_ldo1_hc; |
| 207 | ldo1->init_data = arizona_ldo1_dvfs; | 204 | ldo1->init_data = arizona_ldo1_dvfs; |
| 208 | break; | 205 | break; |
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 034ece707083..6fdd9bf6927f 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c | |||
| @@ -204,10 +204,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) | |||
| 204 | int ret; | 204 | int ret; |
| 205 | 205 | ||
| 206 | micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); | 206 | micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); |
| 207 | if (micsupp == NULL) { | 207 | if (!micsupp) |
| 208 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | ||
| 209 | return -ENOMEM; | 208 | return -ENOMEM; |
| 210 | } | ||
| 211 | 209 | ||
| 212 | micsupp->arizona = arizona; | 210 | micsupp->arizona = arizona; |
| 213 | INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); | 211 | INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); |
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index c77a58478cca..b47283f91e2d 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c | |||
| @@ -191,7 +191,7 @@ static int as3711_regulator_parse_dt(struct device *dev, | |||
| 191 | { | 191 | { |
| 192 | struct as3711_regulator_pdata *pdata = dev_get_platdata(dev); | 192 | struct as3711_regulator_pdata *pdata = dev_get_platdata(dev); |
| 193 | struct device_node *regulators = | 193 | struct device_node *regulators = |
| 194 | of_find_node_by_name(dev->parent->of_node, "regulators"); | 194 | of_get_child_by_name(dev->parent->of_node, "regulators"); |
| 195 | struct of_regulator_match *match; | 195 | struct of_regulator_match *match; |
| 196 | int ret, i; | 196 | int ret, i; |
| 197 | 197 | ||
| @@ -221,7 +221,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
| 221 | { | 221 | { |
| 222 | struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); | 222 | struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); |
| 223 | struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); | 223 | struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); |
| 224 | struct regulator_init_data *reg_data; | ||
| 225 | struct regulator_config config = {.dev = &pdev->dev,}; | 224 | struct regulator_config config = {.dev = &pdev->dev,}; |
| 226 | struct as3711_regulator *reg = NULL; | 225 | struct as3711_regulator *reg = NULL; |
| 227 | struct as3711_regulator *regs; | 226 | struct as3711_regulator *regs; |
| @@ -246,22 +245,14 @@ static int as3711_regulator_probe(struct platform_device *pdev) | |||
| 246 | 245 | ||
| 247 | regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * | 246 | regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * |
| 248 | sizeof(struct as3711_regulator), GFP_KERNEL); | 247 | sizeof(struct as3711_regulator), GFP_KERNEL); |
| 249 | if (!regs) { | 248 | if (!regs) |
| 250 | dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); | ||
| 251 | return -ENOMEM; | 249 | return -ENOMEM; |
| 252 | } | ||
| 253 | 250 | ||
| 254 | for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { | 251 | for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { |
| 255 | reg_data = pdata->init_data[id]; | ||
| 256 | |||
| 257 | /* No need to register if there is no regulator data */ | ||
| 258 | if (!reg_data) | ||
| 259 | continue; | ||
| 260 | |||
| 261 | reg = ®s[id]; | 252 | reg = ®s[id]; |
| 262 | reg->reg_info = ri; | 253 | reg->reg_info = ri; |
| 263 | 254 | ||
| 264 | config.init_data = reg_data; | 255 | config.init_data = pdata->init_data[id]; |
| 265 | config.driver_data = reg; | 256 | config.driver_data = reg; |
| 266 | config.regmap = as3711->regmap; | 257 | config.regmap = as3711->regmap; |
| 267 | config.of_node = of_node[id]; | 258 | config.of_node = of_node[id]; |
diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 8b17d786cb71..85585219ce82 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c | |||
| @@ -719,6 +719,7 @@ static int as3722_get_regulator_dt_data(struct platform_device *pdev, | |||
| 719 | 719 | ||
| 720 | ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, | 720 | ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, |
| 721 | ARRAY_SIZE(as3722_regulator_matches)); | 721 | ARRAY_SIZE(as3722_regulator_matches)); |
| 722 | of_node_put(np); | ||
| 722 | if (ret < 0) { | 723 | if (ret < 0) { |
| 723 | dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", | 724 | dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", |
| 724 | ret); | 725 | ret); |
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c new file mode 100644 index 000000000000..ab08ca7cfb08 --- /dev/null +++ b/drivers/regulator/bcm590xx-regulator.c | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | /* | ||
| 2 | * Broadcom BCM590xx regulator driver | ||
| 3 | * | ||
| 4 | * Copyright 2014 Linaro Limited | ||
| 5 | * Author: Matt Porter <mporter@linaro.org> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/mfd/bcm590xx.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/regulator/driver.h> | ||
| 21 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/regulator/of_regulator.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | |||
| 25 | /* Register defs */ | ||
| 26 | #define BCM590XX_RFLDOPMCTRL1 0x60 | ||
| 27 | #define BCM590XX_IOSR1PMCTRL1 0x7a | ||
| 28 | #define BCM590XX_IOSR2PMCTRL1 0x7c | ||
| 29 | #define BCM590XX_CSRPMCTRL1 0x7e | ||
| 30 | #define BCM590XX_SDSR1PMCTRL1 0x82 | ||
| 31 | #define BCM590XX_SDSR2PMCTRL1 0x86 | ||
| 32 | #define BCM590XX_MSRPMCTRL1 0x8a | ||
| 33 | #define BCM590XX_VSRPMCTRL1 0x8e | ||
| 34 | #define BCM590XX_REG_ENABLE BIT(7) | ||
| 35 | |||
| 36 | #define BCM590XX_RFLDOCTRL 0x96 | ||
| 37 | #define BCM590XX_CSRVOUT1 0xc0 | ||
| 38 | #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) | ||
| 39 | #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) | ||
| 40 | |||
| 41 | /* LDO regulator IDs */ | ||
| 42 | #define BCM590XX_REG_RFLDO 0 | ||
| 43 | #define BCM590XX_REG_CAMLDO1 1 | ||
| 44 | #define BCM590XX_REG_CAMLDO2 2 | ||
| 45 | #define BCM590XX_REG_SIMLDO1 3 | ||
| 46 | #define BCM590XX_REG_SIMLDO2 4 | ||
| 47 | #define BCM590XX_REG_SDLDO 5 | ||
| 48 | #define BCM590XX_REG_SDXLDO 6 | ||
| 49 | #define BCM590XX_REG_MMCLDO1 7 | ||
| 50 | #define BCM590XX_REG_MMCLDO2 8 | ||
| 51 | #define BCM590XX_REG_AUDLDO 9 | ||
| 52 | #define BCM590XX_REG_MICLDO 10 | ||
| 53 | #define BCM590XX_REG_USBLDO 11 | ||
| 54 | #define BCM590XX_REG_VIBLDO 12 | ||
| 55 | |||
| 56 | /* DCDC regulator IDs */ | ||
| 57 | #define BCM590XX_REG_CSR 13 | ||
| 58 | #define BCM590XX_REG_IOSR1 14 | ||
| 59 | #define BCM590XX_REG_IOSR2 15 | ||
| 60 | #define BCM590XX_REG_MSR 16 | ||
| 61 | #define BCM590XX_REG_SDSR1 17 | ||
| 62 | #define BCM590XX_REG_SDSR2 18 | ||
| 63 | #define BCM590XX_REG_VSR 19 | ||
| 64 | |||
| 65 | #define BCM590XX_NUM_REGS 20 | ||
| 66 | |||
| 67 | #define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR) | ||
| 68 | |||
| 69 | struct bcm590xx_board { | ||
| 70 | struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; | ||
| 71 | }; | ||
| 72 | |||
| 73 | /* LDO group A: supported voltages in microvolts */ | ||
| 74 | static const unsigned int ldo_a_table[] = { | ||
| 75 | 1200000, 1800000, 2500000, 2700000, 2800000, | ||
| 76 | 2900000, 3000000, 3300000, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* LDO group C: supported voltages in microvolts */ | ||
| 80 | static const unsigned int ldo_c_table[] = { | ||
| 81 | 3100000, 1800000, 2500000, 2700000, 2800000, | ||
| 82 | 2900000, 3000000, 3300000, | ||
| 83 | }; | ||
| 84 | |||
| 85 | /* DCDC group CSR: supported voltages in microvolts */ | ||
| 86 | static const struct regulator_linear_range dcdc_csr_ranges[] = { | ||
| 87 | REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), | ||
| 88 | REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), | ||
| 89 | REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), | ||
| 90 | }; | ||
| 91 | |||
| 92 | /* DCDC group IOSR1: supported voltages in microvolts */ | ||
| 93 | static const struct regulator_linear_range dcdc_iosr1_ranges[] = { | ||
| 94 | REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), | ||
| 95 | REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), | ||
| 96 | REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), | ||
| 97 | REGULATOR_LINEAR_RANGE(900000, 54, 63, 0), | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* DCDC group SDSR1: supported voltages in microvolts */ | ||
| 101 | static const struct regulator_linear_range dcdc_sdsr1_ranges[] = { | ||
| 102 | REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), | ||
| 103 | REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), | ||
| 104 | REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), | ||
| 105 | }; | ||
| 106 | |||
| 107 | struct bcm590xx_info { | ||
| 108 | const char *name; | ||
| 109 | const char *vin_name; | ||
| 110 | u8 n_voltages; | ||
| 111 | const unsigned int *volt_table; | ||
| 112 | u8 n_linear_ranges; | ||
| 113 | const struct regulator_linear_range *linear_ranges; | ||
| 114 | }; | ||
| 115 | |||
| 116 | #define BCM590XX_REG_TABLE(_name, _table) \ | ||
| 117 | { \ | ||
| 118 | .name = #_name, \ | ||
| 119 | .n_voltages = ARRAY_SIZE(_table), \ | ||
| 120 | .volt_table = _table, \ | ||
| 121 | } | ||
| 122 | |||
| 123 | #define BCM590XX_REG_RANGES(_name, _ranges) \ | ||
| 124 | { \ | ||
| 125 | .name = #_name, \ | ||
| 126 | .n_linear_ranges = ARRAY_SIZE(_ranges), \ | ||
| 127 | .linear_ranges = _ranges, \ | ||
| 128 | } | ||
| 129 | |||
| 130 | static struct bcm590xx_info bcm590xx_regs[] = { | ||
| 131 | BCM590XX_REG_TABLE(rfldo, ldo_a_table), | ||
| 132 | BCM590XX_REG_TABLE(camldo1, ldo_c_table), | ||
| 133 | BCM590XX_REG_TABLE(camldo2, ldo_c_table), | ||
| 134 | BCM590XX_REG_TABLE(simldo1, ldo_a_table), | ||
| 135 | BCM590XX_REG_TABLE(simldo2, ldo_a_table), | ||
| 136 | BCM590XX_REG_TABLE(sdldo, ldo_c_table), | ||
| 137 | BCM590XX_REG_TABLE(sdxldo, ldo_a_table), | ||
| 138 | BCM590XX_REG_TABLE(mmcldo1, ldo_a_table), | ||
| 139 | BCM590XX_REG_TABLE(mmcldo2, ldo_a_table), | ||
| 140 | BCM590XX_REG_TABLE(audldo, ldo_a_table), | ||
| 141 | BCM590XX_REG_TABLE(micldo, ldo_a_table), | ||
| 142 | BCM590XX_REG_TABLE(usbldo, ldo_a_table), | ||
| 143 | BCM590XX_REG_TABLE(vibldo, ldo_c_table), | ||
| 144 | BCM590XX_REG_RANGES(csr, dcdc_csr_ranges), | ||
| 145 | BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges), | ||
| 146 | BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges), | ||
| 147 | BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges), | ||
| 148 | BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges), | ||
| 149 | BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges), | ||
| 150 | BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges), | ||
| 151 | }; | ||
| 152 | |||
| 153 | struct bcm590xx_reg { | ||
| 154 | struct regulator_desc *desc; | ||
| 155 | struct bcm590xx *mfd; | ||
| 156 | struct bcm590xx_info **info; | ||
| 157 | }; | ||
| 158 | |||
| 159 | static int bcm590xx_get_vsel_register(int id) | ||
| 160 | { | ||
| 161 | if (BCM590XX_REG_IS_LDO(id)) | ||
| 162 | return BCM590XX_RFLDOCTRL + id; | ||
| 163 | else | ||
| 164 | return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int bcm590xx_get_enable_register(int id) | ||
| 168 | { | ||
| 169 | int reg = 0; | ||
| 170 | |||
| 171 | if (BCM590XX_REG_IS_LDO(id)) | ||
| 172 | reg = BCM590XX_RFLDOPMCTRL1 + id * 2; | ||
| 173 | else | ||
| 174 | switch (id) { | ||
| 175 | case BCM590XX_REG_CSR: | ||
| 176 | reg = BCM590XX_CSRPMCTRL1; | ||
| 177 | break; | ||
| 178 | case BCM590XX_REG_IOSR1: | ||
| 179 | reg = BCM590XX_IOSR1PMCTRL1; | ||
| 180 | break; | ||
| 181 | case BCM590XX_REG_IOSR2: | ||
| 182 | reg = BCM590XX_IOSR2PMCTRL1; | ||
| 183 | break; | ||
| 184 | case BCM590XX_REG_MSR: | ||
| 185 | reg = BCM590XX_MSRPMCTRL1; | ||
| 186 | break; | ||
| 187 | case BCM590XX_REG_SDSR1: | ||
| 188 | reg = BCM590XX_SDSR1PMCTRL1; | ||
| 189 | break; | ||
| 190 | case BCM590XX_REG_SDSR2: | ||
| 191 | reg = BCM590XX_SDSR2PMCTRL1; | ||
| 192 | break; | ||
| 193 | }; | ||
| 194 | |||
| 195 | return reg; | ||
| 196 | } | ||
| 197 | |||
| 198 | static struct regulator_ops bcm590xx_ops_ldo = { | ||
| 199 | .is_enabled = regulator_is_enabled_regmap, | ||
| 200 | .enable = regulator_enable_regmap, | ||
| 201 | .disable = regulator_disable_regmap, | ||
| 202 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 203 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 204 | .list_voltage = regulator_list_voltage_table, | ||
| 205 | .map_voltage = regulator_map_voltage_iterate, | ||
| 206 | }; | ||
| 207 | |||
| 208 | static struct regulator_ops bcm590xx_ops_dcdc = { | ||
| 209 | .is_enabled = regulator_is_enabled_regmap, | ||
| 210 | .enable = regulator_enable_regmap, | ||
| 211 | .disable = regulator_disable_regmap, | ||
| 212 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 213 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 214 | .list_voltage = regulator_list_voltage_linear_range, | ||
| 215 | .map_voltage = regulator_map_voltage_linear_range, | ||
| 216 | }; | ||
| 217 | |||
| 218 | #define BCM590XX_MATCH(_name, _id) \ | ||
| 219 | { \ | ||
| 220 | .name = #_name, \ | ||
| 221 | .driver_data = (void *)&bcm590xx_regs[BCM590XX_REG_##_id], \ | ||
| 222 | } | ||
| 223 | |||
| 224 | static struct of_regulator_match bcm590xx_matches[] = { | ||
| 225 | BCM590XX_MATCH(rfldo, RFLDO), | ||
| 226 | BCM590XX_MATCH(camldo1, CAMLDO1), | ||
| 227 | BCM590XX_MATCH(camldo2, CAMLDO2), | ||
| 228 | BCM590XX_MATCH(simldo1, SIMLDO1), | ||
| 229 | BCM590XX_MATCH(simldo2, SIMLDO2), | ||
| 230 | BCM590XX_MATCH(sdldo, SDLDO), | ||
| 231 | BCM590XX_MATCH(sdxldo, SDXLDO), | ||
| 232 | BCM590XX_MATCH(mmcldo1, MMCLDO1), | ||
| 233 | BCM590XX_MATCH(mmcldo2, MMCLDO2), | ||
| 234 | BCM590XX_MATCH(audldo, AUDLDO), | ||
| 235 | BCM590XX_MATCH(micldo, MICLDO), | ||
| 236 | BCM590XX_MATCH(usbldo, USBLDO), | ||
| 237 | BCM590XX_MATCH(vibldo, VIBLDO), | ||
| 238 | BCM590XX_MATCH(csr, CSR), | ||
| 239 | BCM590XX_MATCH(iosr1, IOSR1), | ||
| 240 | BCM590XX_MATCH(iosr2, IOSR2), | ||
| 241 | BCM590XX_MATCH(msr, MSR), | ||
| 242 | BCM590XX_MATCH(sdsr1, SDSR1), | ||
| 243 | BCM590XX_MATCH(sdsr2, SDSR2), | ||
| 244 | BCM590XX_MATCH(vsr, VSR), | ||
| 245 | }; | ||
| 246 | |||
| 247 | static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( | ||
| 248 | struct platform_device *pdev, | ||
| 249 | struct of_regulator_match **bcm590xx_reg_matches) | ||
| 250 | { | ||
| 251 | struct bcm590xx_board *data; | ||
| 252 | struct device_node *np = pdev->dev.parent->of_node; | ||
| 253 | struct device_node *regulators; | ||
| 254 | struct of_regulator_match *matches = bcm590xx_matches; | ||
| 255 | int count = ARRAY_SIZE(bcm590xx_matches); | ||
| 256 | int idx = 0; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | if (!np) { | ||
| 260 | dev_err(&pdev->dev, "of node not found\n"); | ||
| 261 | return NULL; | ||
| 262 | } | ||
| 263 | |||
| 264 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
| 265 | if (!data) { | ||
| 266 | dev_err(&pdev->dev, "failed to allocate regulator board data\n"); | ||
| 267 | return NULL; | ||
| 268 | } | ||
| 269 | |||
| 270 | np = of_node_get(np); | ||
| 271 | regulators = of_get_child_by_name(np, "regulators"); | ||
| 272 | if (!regulators) { | ||
| 273 | dev_warn(&pdev->dev, "regulator node not found\n"); | ||
| 274 | return NULL; | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); | ||
| 278 | of_node_put(regulators); | ||
| 279 | if (ret < 0) { | ||
| 280 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | ||
| 281 | ret); | ||
| 282 | return NULL; | ||
| 283 | } | ||
| 284 | |||
| 285 | *bcm590xx_reg_matches = matches; | ||
| 286 | |||
| 287 | for (idx = 0; idx < count; idx++) { | ||
| 288 | if (!matches[idx].init_data || !matches[idx].of_node) | ||
| 289 | continue; | ||
| 290 | |||
| 291 | data->bcm590xx_pmu_init_data[idx] = matches[idx].init_data; | ||
| 292 | } | ||
| 293 | |||
| 294 | return data; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int bcm590xx_probe(struct platform_device *pdev) | ||
| 298 | { | ||
| 299 | struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); | ||
| 300 | struct bcm590xx_board *pmu_data = NULL; | ||
| 301 | struct bcm590xx_reg *pmu; | ||
| 302 | struct regulator_config config = { }; | ||
| 303 | struct bcm590xx_info *info; | ||
| 304 | struct regulator_init_data *reg_data; | ||
| 305 | struct regulator_dev *rdev; | ||
| 306 | struct of_regulator_match *bcm590xx_reg_matches = NULL; | ||
| 307 | int i; | ||
| 308 | |||
| 309 | pmu_data = bcm590xx_parse_dt_reg_data(pdev, | ||
| 310 | &bcm590xx_reg_matches); | ||
| 311 | |||
| 312 | pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); | ||
| 313 | if (!pmu) { | ||
| 314 | dev_err(&pdev->dev, "Memory allocation failed for pmu\n"); | ||
| 315 | return -ENOMEM; | ||
| 316 | } | ||
| 317 | |||
| 318 | pmu->mfd = bcm590xx; | ||
| 319 | |||
| 320 | platform_set_drvdata(pdev, pmu); | ||
| 321 | |||
| 322 | pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
| 323 | sizeof(struct regulator_desc), GFP_KERNEL); | ||
| 324 | if (!pmu->desc) { | ||
| 325 | dev_err(&pdev->dev, "Memory alloc fails for desc\n"); | ||
| 326 | return -ENOMEM; | ||
| 327 | } | ||
| 328 | |||
| 329 | pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * | ||
| 330 | sizeof(struct bcm590xx_info *), GFP_KERNEL); | ||
| 331 | if (!pmu->info) { | ||
| 332 | dev_err(&pdev->dev, "Memory alloc fails for info\n"); | ||
| 333 | return -ENOMEM; | ||
| 334 | } | ||
| 335 | |||
| 336 | info = bcm590xx_regs; | ||
| 337 | |||
| 338 | for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { | ||
| 339 | if (pmu_data) | ||
| 340 | reg_data = pmu_data->bcm590xx_pmu_init_data[i]; | ||
| 341 | else | ||
| 342 | reg_data = NULL; | ||
| 343 | |||
| 344 | /* Register the regulators */ | ||
| 345 | pmu->info[i] = info; | ||
| 346 | |||
| 347 | pmu->desc[i].name = info->name; | ||
| 348 | pmu->desc[i].supply_name = info->vin_name; | ||
| 349 | pmu->desc[i].id = i; | ||
| 350 | pmu->desc[i].volt_table = info->volt_table; | ||
| 351 | pmu->desc[i].n_voltages = info->n_voltages; | ||
| 352 | pmu->desc[i].linear_ranges = info->linear_ranges; | ||
| 353 | pmu->desc[i].n_linear_ranges = info->n_linear_ranges; | ||
| 354 | |||
| 355 | if (BCM590XX_REG_IS_LDO(i)) { | ||
| 356 | pmu->desc[i].ops = &bcm590xx_ops_ldo; | ||
| 357 | pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK; | ||
| 358 | } else { | ||
| 359 | pmu->desc[i].ops = &bcm590xx_ops_dcdc; | ||
| 360 | pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK; | ||
| 361 | } | ||
| 362 | |||
| 363 | pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i); | ||
| 364 | pmu->desc[i].enable_is_inverted = true; | ||
| 365 | pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE; | ||
| 366 | pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i); | ||
| 367 | pmu->desc[i].type = REGULATOR_VOLTAGE; | ||
| 368 | pmu->desc[i].owner = THIS_MODULE; | ||
| 369 | |||
| 370 | config.dev = bcm590xx->dev; | ||
| 371 | config.init_data = reg_data; | ||
| 372 | config.driver_data = pmu; | ||
| 373 | config.regmap = bcm590xx->regmap; | ||
| 374 | |||
| 375 | if (bcm590xx_reg_matches) | ||
| 376 | config.of_node = bcm590xx_reg_matches[i].of_node; | ||
| 377 | |||
| 378 | rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i], | ||
| 379 | &config); | ||
| 380 | if (IS_ERR(rdev)) { | ||
| 381 | dev_err(bcm590xx->dev, | ||
| 382 | "failed to register %s regulator\n", | ||
| 383 | pdev->name); | ||
| 384 | return PTR_ERR(rdev); | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | static struct platform_driver bcm590xx_regulator_driver = { | ||
| 392 | .driver = { | ||
| 393 | .name = "bcm590xx-vregs", | ||
| 394 | .owner = THIS_MODULE, | ||
| 395 | }, | ||
| 396 | .probe = bcm590xx_probe, | ||
| 397 | }; | ||
| 398 | module_platform_driver(bcm590xx_regulator_driver); | ||
| 399 | |||
| 400 | MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); | ||
| 401 | MODULE_DESCRIPTION("BCM590xx voltage regulator driver"); | ||
| 402 | MODULE_LICENSE("GPL v2"); | ||
| 403 | MODULE_ALIAS("platform:bcm590xx-vregs"); | ||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b38a6b669e8c..bac485acc7f3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -953,6 +953,8 @@ static int machine_constraints_current(struct regulator_dev *rdev, | |||
| 953 | return 0; | 953 | return 0; |
| 954 | } | 954 | } |
| 955 | 955 | ||
| 956 | static int _regulator_do_enable(struct regulator_dev *rdev); | ||
| 957 | |||
| 956 | /** | 958 | /** |
| 957 | * set_machine_constraints - sets regulator constraints | 959 | * set_machine_constraints - sets regulator constraints |
| 958 | * @rdev: regulator source | 960 | * @rdev: regulator source |
| @@ -1013,10 +1015,9 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
| 1013 | /* If the constraints say the regulator should be on at this point | 1015 | /* If the constraints say the regulator should be on at this point |
| 1014 | * and we have control then make sure it is enabled. | 1016 | * and we have control then make sure it is enabled. |
| 1015 | */ | 1017 | */ |
| 1016 | if ((rdev->constraints->always_on || rdev->constraints->boot_on) && | 1018 | if (rdev->constraints->always_on || rdev->constraints->boot_on) { |
| 1017 | ops->enable) { | 1019 | ret = _regulator_do_enable(rdev); |
| 1018 | ret = ops->enable(rdev); | 1020 | if (ret < 0 && ret != -EINVAL) { |
| 1019 | if (ret < 0) { | ||
| 1020 | rdev_err(rdev, "failed to enable\n"); | 1021 | rdev_err(rdev, "failed to enable\n"); |
| 1021 | goto out; | 1022 | goto out; |
| 1022 | } | 1023 | } |
| @@ -1272,6 +1273,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, | |||
| 1272 | if (r->dev.parent && | 1273 | if (r->dev.parent && |
| 1273 | node == r->dev.of_node) | 1274 | node == r->dev.of_node) |
| 1274 | return r; | 1275 | return r; |
| 1276 | *ret = -EPROBE_DEFER; | ||
| 1277 | return NULL; | ||
| 1275 | } else { | 1278 | } else { |
| 1276 | /* | 1279 | /* |
| 1277 | * If we couldn't even get the node then it's | 1280 | * If we couldn't even get the node then it's |
| @@ -1312,7 +1315,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
| 1312 | struct regulator_dev *rdev; | 1315 | struct regulator_dev *rdev; |
| 1313 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); | 1316 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); |
| 1314 | const char *devname = NULL; | 1317 | const char *devname = NULL; |
| 1315 | int ret = -EPROBE_DEFER; | 1318 | int ret; |
| 1316 | 1319 | ||
| 1317 | if (id == NULL) { | 1320 | if (id == NULL) { |
| 1318 | pr_err("get() with no identifier\n"); | 1321 | pr_err("get() with no identifier\n"); |
| @@ -1322,6 +1325,11 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
| 1322 | if (dev) | 1325 | if (dev) |
| 1323 | devname = dev_name(dev); | 1326 | devname = dev_name(dev); |
| 1324 | 1327 | ||
| 1328 | if (have_full_constraints()) | ||
| 1329 | ret = -ENODEV; | ||
| 1330 | else | ||
| 1331 | ret = -EPROBE_DEFER; | ||
| 1332 | |||
| 1325 | mutex_lock(®ulator_list_mutex); | 1333 | mutex_lock(®ulator_list_mutex); |
| 1326 | 1334 | ||
| 1327 | rdev = regulator_dev_lookup(dev, id, &ret); | 1335 | rdev = regulator_dev_lookup(dev, id, &ret); |
| @@ -1352,7 +1360,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
| 1352 | goto found; | 1360 | goto found; |
| 1353 | /* Don't log an error when called from regulator_get_optional() */ | 1361 | /* Don't log an error when called from regulator_get_optional() */ |
| 1354 | } else if (!have_full_constraints() || exclusive) { | 1362 | } else if (!have_full_constraints() || exclusive) { |
| 1355 | dev_err(dev, "dummy supplies not allowed\n"); | 1363 | dev_warn(dev, "dummy supplies not allowed\n"); |
| 1356 | } | 1364 | } |
| 1357 | 1365 | ||
| 1358 | mutex_unlock(®ulator_list_mutex); | 1366 | mutex_unlock(®ulator_list_mutex); |
| @@ -1900,8 +1908,6 @@ static int _regulator_do_disable(struct regulator_dev *rdev) | |||
| 1900 | 1908 | ||
| 1901 | trace_regulator_disable_complete(rdev_get_name(rdev)); | 1909 | trace_regulator_disable_complete(rdev_get_name(rdev)); |
| 1902 | 1910 | ||
| 1903 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | ||
| 1904 | NULL); | ||
| 1905 | return 0; | 1911 | return 0; |
| 1906 | } | 1912 | } |
| 1907 | 1913 | ||
| @@ -1925,6 +1931,8 @@ static int _regulator_disable(struct regulator_dev *rdev) | |||
| 1925 | rdev_err(rdev, "failed to disable\n"); | 1931 | rdev_err(rdev, "failed to disable\n"); |
| 1926 | return ret; | 1932 | return ret; |
| 1927 | } | 1933 | } |
| 1934 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | ||
| 1935 | NULL); | ||
| 1928 | } | 1936 | } |
| 1929 | 1937 | ||
| 1930 | rdev->use_count = 0; | 1938 | rdev->use_count = 0; |
| @@ -1977,20 +1985,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev) | |||
| 1977 | { | 1985 | { |
| 1978 | int ret = 0; | 1986 | int ret = 0; |
| 1979 | 1987 | ||
| 1980 | /* force disable */ | 1988 | ret = _regulator_do_disable(rdev); |
| 1981 | if (rdev->desc->ops->disable) { | 1989 | if (ret < 0) { |
| 1982 | /* ah well, who wants to live forever... */ | 1990 | rdev_err(rdev, "failed to force disable\n"); |
| 1983 | ret = rdev->desc->ops->disable(rdev); | 1991 | return ret; |
| 1984 | if (ret < 0) { | ||
| 1985 | rdev_err(rdev, "failed to force disable\n"); | ||
| 1986 | return ret; | ||
| 1987 | } | ||
| 1988 | /* notify other consumers that power has been forced off */ | ||
| 1989 | _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | | ||
| 1990 | REGULATOR_EVENT_DISABLE, NULL); | ||
| 1991 | } | 1992 | } |
| 1992 | 1993 | ||
| 1993 | return ret; | 1994 | _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | |
| 1995 | REGULATOR_EVENT_DISABLE, NULL); | ||
| 1996 | |||
| 1997 | return 0; | ||
| 1994 | } | 1998 | } |
| 1995 | 1999 | ||
| 1996 | /** | 2000 | /** |
| @@ -2395,6 +2399,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
| 2395 | struct regulator_dev *rdev = regulator->rdev; | 2399 | struct regulator_dev *rdev = regulator->rdev; |
| 2396 | int ret = 0; | 2400 | int ret = 0; |
| 2397 | int old_min_uV, old_max_uV; | 2401 | int old_min_uV, old_max_uV; |
| 2402 | int current_uV; | ||
| 2398 | 2403 | ||
| 2399 | mutex_lock(&rdev->mutex); | 2404 | mutex_lock(&rdev->mutex); |
| 2400 | 2405 | ||
| @@ -2405,6 +2410,19 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
| 2405 | if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) | 2410 | if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) |
| 2406 | goto out; | 2411 | goto out; |
| 2407 | 2412 | ||
| 2413 | /* If we're trying to set a range that overlaps the current voltage, | ||
| 2414 | * return succesfully even though the regulator does not support | ||
| 2415 | * changing the voltage. | ||
| 2416 | */ | ||
| 2417 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | ||
| 2418 | current_uV = _regulator_get_voltage(rdev); | ||
| 2419 | if (min_uV <= current_uV && current_uV <= max_uV) { | ||
| 2420 | regulator->min_uV = min_uV; | ||
| 2421 | regulator->max_uV = max_uV; | ||
| 2422 | goto out; | ||
| 2423 | } | ||
| 2424 | } | ||
| 2425 | |||
| 2408 | /* sanity check */ | 2426 | /* sanity check */ |
| 2409 | if (!rdev->desc->ops->set_voltage && | 2427 | if (!rdev->desc->ops->set_voltage && |
| 2410 | !rdev->desc->ops->set_voltage_sel) { | 2428 | !rdev->desc->ops->set_voltage_sel) { |
| @@ -3623,23 +3641,18 @@ int regulator_suspend_finish(void) | |||
| 3623 | 3641 | ||
| 3624 | mutex_lock(®ulator_list_mutex); | 3642 | mutex_lock(®ulator_list_mutex); |
| 3625 | list_for_each_entry(rdev, ®ulator_list, list) { | 3643 | list_for_each_entry(rdev, ®ulator_list, list) { |
| 3626 | struct regulator_ops *ops = rdev->desc->ops; | ||
| 3627 | |||
| 3628 | mutex_lock(&rdev->mutex); | 3644 | mutex_lock(&rdev->mutex); |
| 3629 | if ((rdev->use_count > 0 || rdev->constraints->always_on) && | 3645 | if (rdev->use_count > 0 || rdev->constraints->always_on) { |
| 3630 | ops->enable) { | 3646 | error = _regulator_do_enable(rdev); |
| 3631 | error = ops->enable(rdev); | ||
| 3632 | if (error) | 3647 | if (error) |
| 3633 | ret = error; | 3648 | ret = error; |
| 3634 | } else { | 3649 | } else { |
| 3635 | if (!have_full_constraints()) | 3650 | if (!have_full_constraints()) |
| 3636 | goto unlock; | 3651 | goto unlock; |
| 3637 | if (!ops->disable) | ||
| 3638 | goto unlock; | ||
| 3639 | if (!_regulator_is_enabled(rdev)) | 3652 | if (!_regulator_is_enabled(rdev)) |
| 3640 | goto unlock; | 3653 | goto unlock; |
| 3641 | 3654 | ||
| 3642 | error = ops->disable(rdev); | 3655 | error = _regulator_do_disable(rdev); |
| 3643 | if (error) | 3656 | if (error) |
| 3644 | ret = error; | 3657 | ret = error; |
| 3645 | } | 3658 | } |
| @@ -3813,7 +3826,7 @@ static int __init regulator_init_complete(void) | |||
| 3813 | ops = rdev->desc->ops; | 3826 | ops = rdev->desc->ops; |
| 3814 | c = rdev->constraints; | 3827 | c = rdev->constraints; |
| 3815 | 3828 | ||
| 3816 | if (!ops->disable || (c && c->always_on)) | 3829 | if (c && c->always_on) |
| 3817 | continue; | 3830 | continue; |
| 3818 | 3831 | ||
| 3819 | mutex_lock(&rdev->mutex); | 3832 | mutex_lock(&rdev->mutex); |
| @@ -3834,7 +3847,7 @@ static int __init regulator_init_complete(void) | |||
| 3834 | /* We log since this may kill the system if it | 3847 | /* We log since this may kill the system if it |
| 3835 | * goes wrong. */ | 3848 | * goes wrong. */ |
| 3836 | rdev_info(rdev, "disabling\n"); | 3849 | rdev_info(rdev, "disabling\n"); |
| 3837 | ret = ops->disable(rdev); | 3850 | ret = _regulator_do_disable(rdev); |
| 3838 | if (ret != 0) | 3851 | if (ret != 0) |
| 3839 | rdev_err(rdev, "couldn't disable: %d\n", ret); | 3852 | rdev_err(rdev, "couldn't disable: %d\n", ret); |
| 3840 | } else { | 3853 | } else { |
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 3adeaeffc485..fdb6ea8ae7e6 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
| @@ -240,6 +240,31 @@ static int da9052_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
| 240 | return ret; | 240 | return ret; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 244 | unsigned int old_sel, | ||
| 245 | unsigned int new_sel) | ||
| 246 | { | ||
| 247 | struct da9052_regulator *regulator = rdev_get_drvdata(rdev); | ||
| 248 | struct da9052_regulator_info *info = regulator->info; | ||
| 249 | int id = rdev_get_id(rdev); | ||
| 250 | int ret = 0; | ||
| 251 | |||
| 252 | /* The DVC controlled LDOs and DCDCs ramp with 6.25mV/µs after enabling | ||
| 253 | * the activate bit. | ||
| 254 | */ | ||
| 255 | switch (id) { | ||
| 256 | case DA9052_ID_BUCK1: | ||
| 257 | case DA9052_ID_BUCK2: | ||
| 258 | case DA9052_ID_BUCK3: | ||
| 259 | case DA9052_ID_LDO2: | ||
| 260 | case DA9052_ID_LDO3: | ||
| 261 | ret = (new_sel - old_sel) * info->step_uV / 6250; | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | |||
| 265 | return ret; | ||
| 266 | } | ||
| 267 | |||
| 243 | static struct regulator_ops da9052_dcdc_ops = { | 268 | static struct regulator_ops da9052_dcdc_ops = { |
| 244 | .get_current_limit = da9052_dcdc_get_current_limit, | 269 | .get_current_limit = da9052_dcdc_get_current_limit, |
| 245 | .set_current_limit = da9052_dcdc_set_current_limit, | 270 | .set_current_limit = da9052_dcdc_set_current_limit, |
| @@ -248,6 +273,7 @@ static struct regulator_ops da9052_dcdc_ops = { | |||
| 248 | .map_voltage = da9052_map_voltage, | 273 | .map_voltage = da9052_map_voltage, |
| 249 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 274 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 250 | .set_voltage_sel = da9052_regulator_set_voltage_sel, | 275 | .set_voltage_sel = da9052_regulator_set_voltage_sel, |
| 276 | .set_voltage_time_sel = da9052_regulator_set_voltage_time_sel, | ||
| 251 | .is_enabled = regulator_is_enabled_regmap, | 277 | .is_enabled = regulator_is_enabled_regmap, |
| 252 | .enable = regulator_enable_regmap, | 278 | .enable = regulator_enable_regmap, |
| 253 | .disable = regulator_disable_regmap, | 279 | .disable = regulator_disable_regmap, |
| @@ -258,6 +284,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
| 258 | .map_voltage = da9052_map_voltage, | 284 | .map_voltage = da9052_map_voltage, |
| 259 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 285 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 260 | .set_voltage_sel = da9052_regulator_set_voltage_sel, | 286 | .set_voltage_sel = da9052_regulator_set_voltage_sel, |
| 287 | .set_voltage_time_sel = da9052_regulator_set_voltage_time_sel, | ||
| 261 | .is_enabled = regulator_is_enabled_regmap, | 288 | .is_enabled = regulator_is_enabled_regmap, |
| 262 | .enable = regulator_enable_regmap, | 289 | .enable = regulator_enable_regmap, |
| 263 | .disable = regulator_disable_regmap, | 290 | .disable = regulator_disable_regmap, |
| @@ -401,7 +428,7 @@ static int da9052_regulator_probe(struct platform_device *pdev) | |||
| 401 | if (!nproot) | 428 | if (!nproot) |
| 402 | return -ENODEV; | 429 | return -ENODEV; |
| 403 | 430 | ||
| 404 | nproot = of_find_node_by_name(nproot, "regulators"); | 431 | nproot = of_get_child_by_name(nproot, "regulators"); |
| 405 | if (!nproot) | 432 | if (!nproot) |
| 406 | return -ENODEV; | 433 | return -ENODEV; |
| 407 | 434 | ||
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 7f340206d329..9516317e1a9f 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/regulator/driver.h> | 20 | #include <linux/regulator/driver.h> |
| 21 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/regulator/of_regulator.h> | ||
| 22 | 24 | ||
| 23 | #include <linux/mfd/da9055/core.h> | 25 | #include <linux/mfd/da9055/core.h> |
| 24 | #include <linux/mfd/da9055/reg.h> | 26 | #include <linux/mfd/da9055/reg.h> |
| @@ -446,6 +448,9 @@ static int da9055_gpio_init(struct da9055_regulator *regulator, | |||
| 446 | struct da9055_regulator_info *info = regulator->info; | 448 | struct da9055_regulator_info *info = regulator->info; |
| 447 | int ret = 0; | 449 | int ret = 0; |
| 448 | 450 | ||
| 451 | if (!pdata) | ||
| 452 | return 0; | ||
| 453 | |||
| 449 | if (pdata->gpio_ren && pdata->gpio_ren[id]) { | 454 | if (pdata->gpio_ren && pdata->gpio_ren[id]) { |
| 450 | char name[18]; | 455 | char name[18]; |
| 451 | int gpio_mux = pdata->gpio_ren[id]; | 456 | int gpio_mux = pdata->gpio_ren[id]; |
| @@ -530,6 +535,59 @@ static inline struct da9055_regulator_info *find_regulator_info(int id) | |||
| 530 | return NULL; | 535 | return NULL; |
| 531 | } | 536 | } |
| 532 | 537 | ||
| 538 | #ifdef CONFIG_OF | ||
| 539 | static struct of_regulator_match da9055_reg_matches[] = { | ||
| 540 | { .name = "BUCK1", }, | ||
| 541 | { .name = "BUCK2", }, | ||
| 542 | { .name = "LDO1", }, | ||
| 543 | { .name = "LDO2", }, | ||
| 544 | { .name = "LDO3", }, | ||
| 545 | { .name = "LDO4", }, | ||
| 546 | { .name = "LDO5", }, | ||
| 547 | { .name = "LDO6", }, | ||
| 548 | }; | ||
| 549 | |||
| 550 | static int da9055_regulator_dt_init(struct platform_device *pdev, | ||
| 551 | struct da9055_regulator *regulator, | ||
| 552 | struct regulator_config *config, | ||
| 553 | int regid) | ||
| 554 | { | ||
| 555 | struct device_node *nproot, *np; | ||
| 556 | int ret; | ||
| 557 | |||
| 558 | nproot = of_node_get(pdev->dev.parent->of_node); | ||
| 559 | if (!nproot) | ||
| 560 | return -ENODEV; | ||
| 561 | |||
| 562 | np = of_get_child_by_name(nproot, "regulators"); | ||
| 563 | if (!np) | ||
| 564 | return -ENODEV; | ||
| 565 | |||
| 566 | ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1); | ||
| 567 | of_node_put(nproot); | ||
| 568 | if (ret < 0) { | ||
| 569 | dev_err(&pdev->dev, "Error matching regulator: %d\n", ret); | ||
| 570 | return ret; | ||
| 571 | } | ||
| 572 | |||
| 573 | config->init_data = da9055_reg_matches[regid].init_data; | ||
| 574 | config->of_node = da9055_reg_matches[regid].of_node; | ||
| 575 | |||
| 576 | if (!config->of_node) | ||
| 577 | return -ENODEV; | ||
| 578 | |||
| 579 | return 0; | ||
| 580 | } | ||
| 581 | #else | ||
| 582 | static inline int da9055_regulator_dt_init(struct platform_device *pdev, | ||
| 583 | struct da9055_regulator *regulator, | ||
| 584 | struct regulator_config *config, | ||
| 585 | int regid) | ||
| 586 | { | ||
| 587 | return -ENODEV; | ||
| 588 | } | ||
| 589 | #endif /* CONFIG_OF */ | ||
| 590 | |||
| 533 | static int da9055_regulator_probe(struct platform_device *pdev) | 591 | static int da9055_regulator_probe(struct platform_device *pdev) |
| 534 | { | 592 | { |
| 535 | struct regulator_config config = { }; | 593 | struct regulator_config config = { }; |
| @@ -538,9 +596,6 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
| 538 | struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); | 596 | struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); |
| 539 | int ret, irq; | 597 | int ret, irq; |
| 540 | 598 | ||
| 541 | if (pdata == NULL || pdata->regulators[pdev->id] == NULL) | ||
| 542 | return -ENODEV; | ||
| 543 | |||
| 544 | regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), | 599 | regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), |
| 545 | GFP_KERNEL); | 600 | GFP_KERNEL); |
| 546 | if (!regulator) | 601 | if (!regulator) |
| @@ -557,8 +612,14 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
| 557 | config.driver_data = regulator; | 612 | config.driver_data = regulator; |
| 558 | config.regmap = da9055->regmap; | 613 | config.regmap = da9055->regmap; |
| 559 | 614 | ||
| 560 | if (pdata && pdata->regulators) | 615 | if (pdata && pdata->regulators) { |
| 561 | config.init_data = pdata->regulators[pdev->id]; | 616 | config.init_data = pdata->regulators[pdev->id]; |
| 617 | } else { | ||
| 618 | ret = da9055_regulator_dt_init(pdev, regulator, &config, | ||
| 619 | pdev->id); | ||
| 620 | if (ret < 0) | ||
| 621 | return ret; | ||
| 622 | } | ||
| 562 | 623 | ||
| 563 | ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); | 624 | ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); |
| 564 | if (ret < 0) | 625 | if (ret < 0) |
| @@ -576,7 +637,9 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
| 576 | /* Only LDO 5 and 6 has got the over current interrupt */ | 637 | /* Only LDO 5 and 6 has got the over current interrupt */ |
| 577 | if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { | 638 | if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { |
| 578 | irq = platform_get_irq_byname(pdev, "REGULATOR"); | 639 | irq = platform_get_irq_byname(pdev, "REGULATOR"); |
| 579 | irq = regmap_irq_get_virq(da9055->irq_data, irq); | 640 | if (irq < 0) |
| 641 | return irq; | ||
| 642 | |||
| 580 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 643 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
| 581 | da9055_ldo5_6_oc_irq, | 644 | da9055_ldo5_6_oc_irq, |
| 582 | IRQF_TRIGGER_HIGH | | 645 | IRQF_TRIGGER_HIGH | |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 56727eb745df..7c9461d13313 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | |||
| 1 | /* | 2 | /* |
| 2 | * Regulator driver for DA9063 PMIC series | 3 | * Regulator driver for DA9063 PMIC series |
| 3 | * | 4 | * |
| @@ -60,7 +61,8 @@ struct da9063_regulator_info { | |||
| 60 | .desc.ops = &da9063_ldo_ops, \ | 61 | .desc.ops = &da9063_ldo_ops, \ |
| 61 | .desc.min_uV = (min_mV) * 1000, \ | 62 | .desc.min_uV = (min_mV) * 1000, \ |
| 62 | .desc.uV_step = (step_mV) * 1000, \ | 63 | .desc.uV_step = (step_mV) * 1000, \ |
| 63 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1), \ | 64 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1 \ |
| 65 | + (DA9063_V##regl_name##_BIAS)), \ | ||
| 64 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ | 66 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ |
| 65 | .desc.enable_mask = DA9063_LDO_EN, \ | 67 | .desc.enable_mask = DA9063_LDO_EN, \ |
| 66 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ | 68 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ |
| @@ -363,7 +365,7 @@ static int da9063_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 363 | 365 | ||
| 364 | sel = regulator_map_voltage_linear(rdev, uV, uV); | 366 | sel = regulator_map_voltage_linear(rdev, uV, uV); |
| 365 | if (sel < 0) | 367 | if (sel < 0) |
| 366 | return -EINVAL; | 368 | return sel; |
| 367 | 369 | ||
| 368 | sel <<= ffs(rdev->desc->vsel_mask) - 1; | 370 | sel <<= ffs(rdev->desc->vsel_mask) - 1; |
| 369 | 371 | ||
| @@ -664,7 +666,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 664 | struct device_node *node; | 666 | struct device_node *node; |
| 665 | int i, n, num; | 667 | int i, n, num; |
| 666 | 668 | ||
| 667 | node = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 669 | node = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); |
| 668 | if (!node) { | 670 | if (!node) { |
| 669 | dev_err(&pdev->dev, "Regulators device node not found\n"); | 671 | dev_err(&pdev->dev, "Regulators device node not found\n"); |
| 670 | return ERR_PTR(-ENODEV); | 672 | return ERR_PTR(-ENODEV); |
| @@ -672,6 +674,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 672 | 674 | ||
| 673 | num = of_regulator_match(&pdev->dev, node, da9063_matches, | 675 | num = of_regulator_match(&pdev->dev, node, da9063_matches, |
| 674 | ARRAY_SIZE(da9063_matches)); | 676 | ARRAY_SIZE(da9063_matches)); |
| 677 | of_node_put(node); | ||
| 675 | if (num < 0) { | 678 | if (num < 0) { |
| 676 | dev_err(&pdev->dev, "Failed to match regulators\n"); | 679 | dev_err(&pdev->dev, "Failed to match regulators\n"); |
| 677 | return ERR_PTR(-EINVAL); | 680 | return ERR_PTR(-EINVAL); |
| @@ -708,7 +711,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
| 708 | struct platform_device *pdev, | 711 | struct platform_device *pdev, |
| 709 | struct of_regulator_match **da9063_reg_matches) | 712 | struct of_regulator_match **da9063_reg_matches) |
| 710 | { | 713 | { |
| 711 | da9063_reg_matches = NULL; | 714 | *da9063_reg_matches = NULL; |
| 712 | return ERR_PTR(-ENODEV); | 715 | return ERR_PTR(-ENODEV); |
| 713 | } | 716 | } |
| 714 | #endif | 717 | #endif |
| @@ -754,7 +757,7 @@ static int da9063_regulator_probe(struct platform_device *pdev) | |||
| 754 | if (ret < 0) { | 757 | if (ret < 0) { |
| 755 | dev_err(&pdev->dev, | 758 | dev_err(&pdev->dev, |
| 756 | "Error while reading BUCKs configuration\n"); | 759 | "Error while reading BUCKs configuration\n"); |
| 757 | return -EIO; | 760 | return ret; |
| 758 | } | 761 | } |
| 759 | bcores_merged = val & DA9063_BCORE_MERGE; | 762 | bcores_merged = val & DA9063_BCORE_MERGE; |
| 760 | bmem_bio_merged = val & DA9063_BUCK_MERGE; | 763 | bmem_bio_merged = val & DA9063_BUCK_MERGE; |
| @@ -773,10 +776,8 @@ static int da9063_regulator_probe(struct platform_device *pdev) | |||
| 773 | size = sizeof(struct da9063_regulators) + | 776 | size = sizeof(struct da9063_regulators) + |
| 774 | n_regulators * sizeof(struct da9063_regulator); | 777 | n_regulators * sizeof(struct da9063_regulator); |
| 775 | regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | 778 | regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
| 776 | if (!regulators) { | 779 | if (!regulators) |
| 777 | dev_err(&pdev->dev, "No memory for regulators\n"); | ||
| 778 | return -ENOMEM; | 780 | return -ENOMEM; |
| 779 | } | ||
| 780 | 781 | ||
| 781 | regulators->n_regulators = n_regulators; | 782 | regulators->n_regulators = n_regulators; |
| 782 | platform_set_drvdata(pdev, regulators); | 783 | platform_set_drvdata(pdev, regulators); |
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 6f5ecbe1132e..7a320dd11c46 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c | |||
| @@ -134,11 +134,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c, | |||
| 134 | int error; | 134 | int error; |
| 135 | 135 | ||
| 136 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9210), GFP_KERNEL); | 136 | chip = devm_kzalloc(&i2c->dev, sizeof(struct da9210), GFP_KERNEL); |
| 137 | if (NULL == chip) { | 137 | if (!chip) |
| 138 | dev_err(&i2c->dev, | ||
| 139 | "Cannot kzalloc memory for regulator structure\n"); | ||
| 140 | return -ENOMEM; | 138 | return -ENOMEM; |
| 141 | } | ||
| 142 | 139 | ||
| 143 | chip->regmap = devm_regmap_init_i2c(i2c, &da9210_regmap_config); | 140 | chip->regmap = devm_regmap_init_i2c(i2c, &da9210_regmap_config); |
| 144 | if (IS_ERR(chip->regmap)) { | 141 | if (IS_ERR(chip->regmap)) { |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 846acf240e48..617c1adca816 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
| @@ -263,6 +263,8 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { | |||
| 263 | .ops = &db8500_regulator_ops, | 263 | .ops = &db8500_regulator_ops, |
| 264 | .type = REGULATOR_VOLTAGE, | 264 | .type = REGULATOR_VOLTAGE, |
| 265 | .owner = THIS_MODULE, | 265 | .owner = THIS_MODULE, |
| 266 | .fixed_uV = 1800000, | ||
| 267 | .n_voltages = 1, | ||
| 266 | }, | 268 | }, |
| 267 | .exclude_from_power_state = true, | 269 | .exclude_from_power_state = true, |
| 268 | }, | 270 | }, |
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index ce89f7848a57..2d16b9f16de7 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c | |||
| @@ -78,6 +78,7 @@ static struct ux500_regulator_debug { | |||
| 78 | void ux500_regulator_suspend_debug(void) | 78 | void ux500_regulator_suspend_debug(void) |
| 79 | { | 79 | { |
| 80 | int i; | 80 | int i; |
| 81 | |||
| 81 | for (i = 0; i < rdebug.num_regulators; i++) | 82 | for (i = 0; i < rdebug.num_regulators; i++) |
| 82 | rdebug.state_before_suspend[i] = | 83 | rdebug.state_before_suspend[i] = |
| 83 | rdebug.regulator_array[i].is_enabled; | 84 | rdebug.regulator_array[i].is_enabled; |
| @@ -86,6 +87,7 @@ void ux500_regulator_suspend_debug(void) | |||
| 86 | void ux500_regulator_resume_debug(void) | 87 | void ux500_regulator_resume_debug(void) |
| 87 | { | 88 | { |
| 88 | int i; | 89 | int i; |
| 90 | |||
| 89 | for (i = 0; i < rdebug.num_regulators; i++) | 91 | for (i = 0; i < rdebug.num_regulators; i++) |
| 90 | rdebug.state_after_suspend[i] = | 92 | rdebug.state_after_suspend[i] = |
| 91 | rdebug.regulator_array[i].is_enabled; | 93 | rdebug.regulator_array[i].is_enabled; |
| @@ -127,9 +129,9 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p) | |||
| 127 | int i; | 129 | int i; |
| 128 | 130 | ||
| 129 | /* print dump header */ | 131 | /* print dump header */ |
| 130 | err = seq_printf(s, "ux500-regulator status:\n"); | 132 | err = seq_puts(s, "ux500-regulator status:\n"); |
| 131 | if (err < 0) | 133 | if (err < 0) |
| 132 | dev_err(dev, "seq_printf overflow\n"); | 134 | dev_err(dev, "seq_puts overflow\n"); |
| 133 | 135 | ||
| 134 | err = seq_printf(s, "%31s : %8s : %8s\n", "current", | 136 | err = seq_printf(s, "%31s : %8s : %8s\n", "current", |
| 135 | "before", "after"); | 137 | "before", "after"); |
| @@ -202,18 +204,12 @@ ux500_regulator_debug_init(struct platform_device *pdev, | |||
| 202 | rdebug.num_regulators = num_regulators; | 204 | rdebug.num_regulators = num_regulators; |
| 203 | 205 | ||
| 204 | rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); | 206 | rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); |
| 205 | if (!rdebug.state_before_suspend) { | 207 | if (!rdebug.state_before_suspend) |
| 206 | dev_err(&pdev->dev, | ||
| 207 | "could not allocate memory for saving state\n"); | ||
| 208 | goto exit_destroy_power_state; | 208 | goto exit_destroy_power_state; |
| 209 | } | ||
| 210 | 209 | ||
| 211 | rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); | 210 | rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); |
| 212 | if (!rdebug.state_after_suspend) { | 211 | if (!rdebug.state_after_suspend) |
| 213 | dev_err(&pdev->dev, | ||
| 214 | "could not allocate memory for saving state\n"); | ||
| 215 | goto exit_free; | 212 | goto exit_free; |
| 216 | } | ||
| 217 | 213 | ||
| 218 | dbx500_regulator_testcase(regulator_info, num_regulators); | 214 | dbx500_regulator_testcase(regulator_info, num_regulators); |
| 219 | return 0; | 215 | return 0; |
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index df9f42524abb..2436db9e2ca3 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c | |||
| @@ -25,7 +25,11 @@ | |||
| 25 | 25 | ||
| 26 | struct regulator_dev *dummy_regulator_rdev; | 26 | struct regulator_dev *dummy_regulator_rdev; |
| 27 | 27 | ||
| 28 | static struct regulator_init_data dummy_initdata; | 28 | static struct regulator_init_data dummy_initdata = { |
| 29 | .constraints = { | ||
| 30 | .always_on = 1, | ||
| 31 | }, | ||
| 32 | }; | ||
| 29 | 33 | ||
| 30 | static struct regulator_ops dummy_ops; | 34 | static struct regulator_ops dummy_ops; |
| 31 | 35 | ||
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 7ca3d9e3b0fe..714fd9a89aa1 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
| @@ -90,11 +90,11 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) | |||
| 90 | return 0; | 90 | return 0; |
| 91 | ret = regulator_map_voltage_linear(rdev, uV, uV); | 91 | ret = regulator_map_voltage_linear(rdev, uV, uV); |
| 92 | if (ret < 0) | 92 | if (ret < 0) |
| 93 | return -EINVAL; | 93 | return ret; |
| 94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, | 94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, |
| 95 | VSEL_NSEL_MASK, ret); | 95 | VSEL_NSEL_MASK, ret); |
| 96 | if (ret < 0) | 96 | if (ret < 0) |
| 97 | return -EINVAL; | 97 | return ret; |
| 98 | /* Cache the sleep voltage setting. | 98 | /* Cache the sleep voltage setting. |
| 99 | * Might not be the real voltage which is rounded */ | 99 | * Might not be the real voltage which is rounded */ |
| 100 | di->sleep_vol_cache = uV; | 100 | di->sleep_vol_cache = uV; |
| @@ -244,10 +244,9 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
| 244 | 244 | ||
| 245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | 245 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), |
| 246 | GFP_KERNEL); | 246 | GFP_KERNEL); |
| 247 | if (!di) { | 247 | if (!di) |
| 248 | dev_err(&client->dev, "Failed to allocate device info data!\n"); | ||
| 249 | return -ENOMEM; | 248 | return -ENOMEM; |
| 250 | } | 249 | |
| 251 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); | 250 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); |
| 252 | if (IS_ERR(di->regmap)) { | 251 | if (IS_ERR(di->regmap)) { |
| 253 | dev_err(&client->dev, "Failed to allocate regmap!\n"); | 252 | dev_err(&client->dev, "Failed to allocate regmap!\n"); |
| @@ -260,14 +259,14 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
| 260 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); | 259 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); |
| 261 | if (ret < 0) { | 260 | if (ret < 0) { |
| 262 | dev_err(&client->dev, "Failed to get chip ID!\n"); | 261 | dev_err(&client->dev, "Failed to get chip ID!\n"); |
| 263 | return -ENODEV; | 262 | return ret; |
| 264 | } | 263 | } |
| 265 | di->chip_id = val & DIE_ID; | 264 | di->chip_id = val & DIE_ID; |
| 266 | /* Get chip revision */ | 265 | /* Get chip revision */ |
| 267 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); | 266 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); |
| 268 | if (ret < 0) { | 267 | if (ret < 0) { |
| 269 | dev_err(&client->dev, "Failed to get chip Rev!\n"); | 268 | dev_err(&client->dev, "Failed to get chip Rev!\n"); |
| 270 | return -ENODEV; | 269 | return ret; |
| 271 | } | 270 | } |
| 272 | di->chip_rev = val & DIE_REV; | 271 | di->chip_rev = val & DIE_REV; |
| 273 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", | 272 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 5ea64b94341c..c61f7e97e4f8 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
| @@ -130,17 +130,15 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 130 | 130 | ||
| 131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), | 131 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), |
| 132 | GFP_KERNEL); | 132 | GFP_KERNEL); |
| 133 | if (drvdata == NULL) { | 133 | if (!drvdata) |
| 134 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | 134 | return -ENOMEM; |
| 135 | ret = -ENOMEM; | ||
| 136 | goto err; | ||
| 137 | } | ||
| 138 | 135 | ||
| 139 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 136 | drvdata->desc.name = devm_kstrdup(&pdev->dev, |
| 137 | config->supply_name, | ||
| 138 | GFP_KERNEL); | ||
| 140 | if (drvdata->desc.name == NULL) { | 139 | if (drvdata->desc.name == NULL) { |
| 141 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); | 140 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); |
| 142 | ret = -ENOMEM; | 141 | return -ENOMEM; |
| 143 | goto err; | ||
| 144 | } | 142 | } |
| 145 | drvdata->desc.type = REGULATOR_VOLTAGE; | 143 | drvdata->desc.type = REGULATOR_VOLTAGE; |
| 146 | drvdata->desc.owner = THIS_MODULE; | 144 | drvdata->desc.owner = THIS_MODULE; |
| @@ -149,13 +147,13 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 149 | drvdata->desc.enable_time = config->startup_delay; | 147 | drvdata->desc.enable_time = config->startup_delay; |
| 150 | 148 | ||
| 151 | if (config->input_supply) { | 149 | if (config->input_supply) { |
| 152 | drvdata->desc.supply_name = kstrdup(config->input_supply, | 150 | drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, |
| 153 | GFP_KERNEL); | 151 | config->input_supply, |
| 152 | GFP_KERNEL); | ||
| 154 | if (!drvdata->desc.supply_name) { | 153 | if (!drvdata->desc.supply_name) { |
| 155 | dev_err(&pdev->dev, | 154 | dev_err(&pdev->dev, |
| 156 | "Failed to allocate input supply\n"); | 155 | "Failed to allocate input supply\n"); |
| 157 | ret = -ENOMEM; | 156 | return -ENOMEM; |
| 158 | goto err_name; | ||
| 159 | } | 157 | } |
| 160 | } | 158 | } |
| 161 | 159 | ||
| @@ -186,11 +184,12 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 186 | cfg.driver_data = drvdata; | 184 | cfg.driver_data = drvdata; |
| 187 | cfg.of_node = pdev->dev.of_node; | 185 | cfg.of_node = pdev->dev.of_node; |
| 188 | 186 | ||
| 189 | drvdata->dev = regulator_register(&drvdata->desc, &cfg); | 187 | drvdata->dev = devm_regulator_register(&pdev->dev, &drvdata->desc, |
| 188 | &cfg); | ||
| 190 | if (IS_ERR(drvdata->dev)) { | 189 | if (IS_ERR(drvdata->dev)) { |
| 191 | ret = PTR_ERR(drvdata->dev); | 190 | ret = PTR_ERR(drvdata->dev); |
| 192 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); | 191 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); |
| 193 | goto err_input; | 192 | return ret; |
| 194 | } | 193 | } |
| 195 | 194 | ||
| 196 | platform_set_drvdata(pdev, drvdata); | 195 | platform_set_drvdata(pdev, drvdata); |
| @@ -199,24 +198,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
| 199 | drvdata->desc.fixed_uV); | 198 | drvdata->desc.fixed_uV); |
| 200 | 199 | ||
| 201 | return 0; | 200 | return 0; |
| 202 | |||
| 203 | err_input: | ||
| 204 | kfree(drvdata->desc.supply_name); | ||
| 205 | err_name: | ||
| 206 | kfree(drvdata->desc.name); | ||
| 207 | err: | ||
| 208 | return ret; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int reg_fixed_voltage_remove(struct platform_device *pdev) | ||
| 212 | { | ||
| 213 | struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev); | ||
| 214 | |||
| 215 | regulator_unregister(drvdata->dev); | ||
| 216 | kfree(drvdata->desc.supply_name); | ||
| 217 | kfree(drvdata->desc.name); | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | 201 | } |
| 221 | 202 | ||
| 222 | #if defined(CONFIG_OF) | 203 | #if defined(CONFIG_OF) |
| @@ -229,7 +210,6 @@ MODULE_DEVICE_TABLE(of, fixed_of_match); | |||
| 229 | 210 | ||
| 230 | static struct platform_driver regulator_fixed_voltage_driver = { | 211 | static struct platform_driver regulator_fixed_voltage_driver = { |
| 231 | .probe = reg_fixed_voltage_probe, | 212 | .probe = reg_fixed_voltage_probe, |
| 232 | .remove = reg_fixed_voltage_remove, | ||
| 233 | .driver = { | 213 | .driver = { |
| 234 | .name = "reg-fixed-voltage", | 214 | .name = "reg-fixed-voltage", |
| 235 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index c0a1d00b78c9..989b23b377c0 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
| @@ -136,7 +136,6 @@ static struct gpio_regulator_config * | |||
| 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) |
| 137 | { | 137 | { |
| 138 | struct gpio_regulator_config *config; | 138 | struct gpio_regulator_config *config; |
| 139 | struct property *prop; | ||
| 140 | const char *regtype; | 139 | const char *regtype; |
| 141 | int proplen, gpio, i; | 140 | int proplen, gpio, i; |
| 142 | int ret; | 141 | int ret; |
| @@ -172,22 +171,35 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
| 172 | if (!config->gpios) | 171 | if (!config->gpios) |
| 173 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |
| 174 | 173 | ||
| 174 | proplen = of_property_count_u32_elems(np, "gpios-states"); | ||
| 175 | /* optional property */ | ||
| 176 | if (proplen < 0) | ||
| 177 | proplen = 0; | ||
| 178 | |||
| 179 | if (proplen > 0 && proplen != config->nr_gpios) { | ||
| 180 | dev_warn(dev, "gpios <-> gpios-states mismatch\n"); | ||
| 181 | proplen = 0; | ||
| 182 | } | ||
| 183 | |||
| 175 | for (i = 0; i < config->nr_gpios; i++) { | 184 | for (i = 0; i < config->nr_gpios; i++) { |
| 176 | gpio = of_get_named_gpio(np, "gpios", i); | 185 | gpio = of_get_named_gpio(np, "gpios", i); |
| 177 | if (gpio < 0) | 186 | if (gpio < 0) |
| 178 | break; | 187 | break; |
| 179 | config->gpios[i].gpio = gpio; | 188 | config->gpios[i].gpio = gpio; |
| 189 | if (proplen > 0) { | ||
| 190 | of_property_read_u32_index(np, "gpios-states", i, &ret); | ||
| 191 | if (ret) | ||
| 192 | config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; | ||
| 193 | } | ||
| 180 | } | 194 | } |
| 181 | 195 | ||
| 182 | /* Fetch states. */ | 196 | /* Fetch states. */ |
| 183 | prop = of_find_property(np, "states", NULL); | 197 | proplen = of_property_count_u32_elems(np, "states"); |
| 184 | if (!prop) { | 198 | if (proplen < 0) { |
| 185 | dev_err(dev, "No 'states' property found\n"); | 199 | dev_err(dev, "No 'states' property found\n"); |
| 186 | return ERR_PTR(-EINVAL); | 200 | return ERR_PTR(-EINVAL); |
| 187 | } | 201 | } |
| 188 | 202 | ||
| 189 | proplen = prop->length / sizeof(int); | ||
| 190 | |||
| 191 | config->states = devm_kzalloc(dev, | 203 | config->states = devm_kzalloc(dev, |
| 192 | sizeof(struct gpio_regulator_state) | 204 | sizeof(struct gpio_regulator_state) |
| 193 | * (proplen / 2), | 205 | * (proplen / 2), |
| @@ -196,10 +208,10 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
| 196 | return ERR_PTR(-ENOMEM); | 208 | return ERR_PTR(-ENOMEM); |
| 197 | 209 | ||
| 198 | for (i = 0; i < proplen / 2; i++) { | 210 | for (i = 0; i < proplen / 2; i++) { |
| 199 | config->states[i].value = | 211 | of_property_read_u32_index(np, "states", i * 2, |
| 200 | be32_to_cpup((int *)prop->value + (i * 2)); | 212 | &config->states[i].value); |
| 201 | config->states[i].gpios = | 213 | of_property_read_u32_index(np, "states", i * 2 + 1, |
| 202 | be32_to_cpup((int *)prop->value + (i * 2 + 1)); | 214 | &config->states[i].gpios); |
| 203 | } | 215 | } |
| 204 | config->nr_states = i; | 216 | config->nr_states = i; |
| 205 | 217 | ||
| @@ -239,10 +251,8 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
| 239 | 251 | ||
| 240 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), | 252 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), |
| 241 | GFP_KERNEL); | 253 | GFP_KERNEL); |
| 242 | if (drvdata == NULL) { | 254 | if (drvdata == NULL) |
| 243 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
| 244 | return -ENOMEM; | 255 | return -ENOMEM; |
| 245 | } | ||
| 246 | 256 | ||
| 247 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 257 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); |
| 248 | if (drvdata->desc.name == NULL) { | 258 | if (drvdata->desc.name == NULL) { |
diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index e221a271ba56..cbc39096c78d 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c | |||
| @@ -37,10 +37,17 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev) | |||
| 37 | if (ret != 0) | 37 | if (ret != 0) |
| 38 | return ret; | 38 | return ret; |
| 39 | 39 | ||
| 40 | if (rdev->desc->enable_is_inverted) | 40 | val &= rdev->desc->enable_mask; |
| 41 | return (val & rdev->desc->enable_mask) == 0; | 41 | |
| 42 | else | 42 | if (rdev->desc->enable_is_inverted) { |
| 43 | return (val & rdev->desc->enable_mask) != 0; | 43 | if (rdev->desc->enable_val) |
| 44 | return val != rdev->desc->enable_val; | ||
| 45 | return val == 0; | ||
| 46 | } else { | ||
| 47 | if (rdev->desc->enable_val) | ||
| 48 | return val == rdev->desc->enable_val; | ||
| 49 | return val != 0; | ||
| 50 | } | ||
| 44 | } | 51 | } |
| 45 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); | 52 | EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); |
| 46 | 53 | ||
| @@ -57,10 +64,13 @@ int regulator_enable_regmap(struct regulator_dev *rdev) | |||
| 57 | { | 64 | { |
| 58 | unsigned int val; | 65 | unsigned int val; |
| 59 | 66 | ||
| 60 | if (rdev->desc->enable_is_inverted) | 67 | if (rdev->desc->enable_is_inverted) { |
| 61 | val = 0; | 68 | val = rdev->desc->disable_val; |
| 62 | else | 69 | } else { |
| 63 | val = rdev->desc->enable_mask; | 70 | val = rdev->desc->enable_val; |
| 71 | if (!val) | ||
| 72 | val = rdev->desc->enable_mask; | ||
| 73 | } | ||
| 64 | 74 | ||
| 65 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 75 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
| 66 | rdev->desc->enable_mask, val); | 76 | rdev->desc->enable_mask, val); |
| @@ -80,10 +90,13 @@ int regulator_disable_regmap(struct regulator_dev *rdev) | |||
| 80 | { | 90 | { |
| 81 | unsigned int val; | 91 | unsigned int val; |
| 82 | 92 | ||
| 83 | if (rdev->desc->enable_is_inverted) | 93 | if (rdev->desc->enable_is_inverted) { |
| 84 | val = rdev->desc->enable_mask; | 94 | val = rdev->desc->enable_val; |
| 85 | else | 95 | if (!val) |
| 86 | val = 0; | 96 | val = rdev->desc->enable_mask; |
| 97 | } else { | ||
| 98 | val = rdev->desc->disable_val; | ||
| 99 | } | ||
| 87 | 100 | ||
| 88 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 101 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
| 89 | rdev->desc->enable_mask, val); | 102 | rdev->desc->enable_mask, val); |
| @@ -419,10 +432,13 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |||
| 419 | { | 432 | { |
| 420 | unsigned int val; | 433 | unsigned int val; |
| 421 | 434 | ||
| 422 | if (enable) | 435 | if (enable) { |
| 423 | val = rdev->desc->bypass_mask; | 436 | val = rdev->desc->bypass_val_on; |
| 424 | else | 437 | if (!val) |
| 425 | val = 0; | 438 | val = rdev->desc->bypass_mask; |
| 439 | } else { | ||
| 440 | val = rdev->desc->bypass_val_off; | ||
| 441 | } | ||
| 426 | 442 | ||
| 427 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | 443 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, |
| 428 | rdev->desc->bypass_mask, val); | 444 | rdev->desc->bypass_mask, val); |
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 3b1102b75071..66fd2330dca0 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
| @@ -327,7 +327,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, | |||
| 327 | return -EIO; | 327 | return -EIO; |
| 328 | ret = i2c_smbus_read_byte_data(i2c, reg); | 328 | ret = i2c_smbus_read_byte_data(i2c, reg); |
| 329 | if (ret < 0) | 329 | if (ret < 0) |
| 330 | return -EIO; | 330 | return ret; |
| 331 | 331 | ||
| 332 | *dest = ret; | 332 | *dest = ret; |
| 333 | return 0; | 333 | return 0; |
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 2e4734ff79fc..2e022aabd951 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c | |||
| @@ -211,7 +211,7 @@ static int lp872x_get_timestep_usec(struct lp872x *lp) | |||
| 211 | 211 | ||
| 212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); | 212 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); |
| 213 | if (ret) | 213 | if (ret) |
| 214 | return -EINVAL; | 214 | return ret; |
| 215 | 215 | ||
| 216 | val = (val & mask) >> shift; | 216 | val = (val & mask) >> shift; |
| 217 | if (val >= size) | 217 | if (val >= size) |
| @@ -229,7 +229,7 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) | |||
| 229 | u8 addr, val; | 229 | u8 addr, val; |
| 230 | 230 | ||
| 231 | if (time_step_us < 0) | 231 | if (time_step_us < 0) |
| 232 | return -EINVAL; | 232 | return time_step_us; |
| 233 | 233 | ||
| 234 | switch (rid) { | 234 | switch (rid) { |
| 235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: | 235 | case LP8720_ID_LDO1 ... LP8720_ID_BUCK: |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index b1078ba3f393..ed60baaeceec 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * max14577.c - Regulator driver for the Maxim 14577 | 2 | * max14577.c - Regulator driver for the Maxim 14577 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2013 Samsung Electronics | 4 | * Copyright (C) 2013,2014 Samsung Electronics |
| 5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 5 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -22,12 +22,6 @@ | |||
| 22 | #include <linux/mfd/max14577-private.h> | 22 | #include <linux/mfd/max14577-private.h> |
| 23 | #include <linux/regulator/of_regulator.h> | 23 | #include <linux/regulator/of_regulator.h> |
| 24 | 24 | ||
| 25 | struct max14577_regulator { | ||
| 26 | struct device *dev; | ||
| 27 | struct max14577 *max14577; | ||
| 28 | struct regulator_dev **regulators; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) | 25 | static int max14577_reg_is_enabled(struct regulator_dev *rdev) |
| 32 | { | 26 | { |
| 33 | int rid = rdev_get_id(rdev); | 27 | int rid = rdev_get_id(rdev); |
| @@ -166,12 +160,14 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) | |||
| 166 | 160 | ||
| 167 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, | 161 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, |
| 168 | MAX14577_REG_MAX); | 162 | MAX14577_REG_MAX); |
| 169 | if (ret < 0) { | 163 | if (ret < 0) |
| 170 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); | 164 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); |
| 171 | return ret; | 165 | else |
| 172 | } | 166 | ret = 0; |
| 173 | 167 | ||
| 174 | return 0; | 168 | of_node_put(np); |
| 169 | |||
| 170 | return ret; | ||
| 175 | } | 171 | } |
| 176 | 172 | ||
| 177 | static inline struct regulator_init_data *match_init_data(int index) | 173 | static inline struct regulator_init_data *match_init_data(int index) |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index e242dd316d36..d23d0577754b 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
| @@ -46,8 +46,6 @@ struct max1586_data { | |||
| 46 | 46 | ||
| 47 | unsigned int v3_curr_sel; | 47 | unsigned int v3_curr_sel; |
| 48 | unsigned int v6_curr_sel; | 48 | unsigned int v6_curr_sel; |
| 49 | |||
| 50 | struct regulator_dev *rdev[0]; | ||
| 51 | }; | 49 | }; |
| 52 | 50 | ||
| 53 | /* | 51 | /* |
| @@ -162,14 +160,12 @@ static struct regulator_desc max1586_reg[] = { | |||
| 162 | static int max1586_pmic_probe(struct i2c_client *client, | 160 | static int max1586_pmic_probe(struct i2c_client *client, |
| 163 | const struct i2c_device_id *i2c_id) | 161 | const struct i2c_device_id *i2c_id) |
| 164 | { | 162 | { |
| 165 | struct regulator_dev **rdev; | ||
| 166 | struct max1586_platform_data *pdata = dev_get_platdata(&client->dev); | 163 | struct max1586_platform_data *pdata = dev_get_platdata(&client->dev); |
| 167 | struct regulator_config config = { }; | 164 | struct regulator_config config = { }; |
| 168 | struct max1586_data *max1586; | 165 | struct max1586_data *max1586; |
| 169 | int i, id; | 166 | int i, id; |
| 170 | 167 | ||
| 171 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) + | 168 | max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data), |
| 172 | sizeof(struct regulator_dev *) * (MAX1586_V6 + 1), | ||
| 173 | GFP_KERNEL); | 169 | GFP_KERNEL); |
| 174 | if (!max1586) | 170 | if (!max1586) |
| 175 | return -ENOMEM; | 171 | return -ENOMEM; |
| @@ -186,8 +182,9 @@ static int max1586_pmic_probe(struct i2c_client *client, | |||
| 186 | max1586->v3_curr_sel = 24; /* 1.3V */ | 182 | max1586->v3_curr_sel = 24; /* 1.3V */ |
| 187 | max1586->v6_curr_sel = 0; | 183 | max1586->v6_curr_sel = 0; |
| 188 | 184 | ||
| 189 | rdev = max1586->rdev; | ||
| 190 | for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { | 185 | for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { |
| 186 | struct regulator_dev *rdev; | ||
| 187 | |||
| 191 | id = pdata->subdevs[i].id; | 188 | id = pdata->subdevs[i].id; |
| 192 | if (!pdata->subdevs[i].platform_data) | 189 | if (!pdata->subdevs[i].platform_data) |
| 193 | continue; | 190 | continue; |
| @@ -207,12 +204,12 @@ static int max1586_pmic_probe(struct i2c_client *client, | |||
| 207 | config.init_data = pdata->subdevs[i].platform_data; | 204 | config.init_data = pdata->subdevs[i].platform_data; |
| 208 | config.driver_data = max1586; | 205 | config.driver_data = max1586; |
| 209 | 206 | ||
| 210 | rdev[i] = devm_regulator_register(&client->dev, | 207 | rdev = devm_regulator_register(&client->dev, |
| 211 | &max1586_reg[id], &config); | 208 | &max1586_reg[id], &config); |
| 212 | if (IS_ERR(rdev[i])) { | 209 | if (IS_ERR(rdev)) { |
| 213 | dev_err(&client->dev, "failed to register %s\n", | 210 | dev_err(&client->dev, "failed to register %s\n", |
| 214 | max1586_reg[id].name); | 211 | max1586_reg[id].name); |
| 215 | return PTR_ERR(rdev[i]); | 212 | return PTR_ERR(rdev); |
| 216 | } | 213 | } |
| 217 | } | 214 | } |
| 218 | 215 | ||
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index ae001ccf26f4..ef1af2debbd2 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
| @@ -65,7 +65,6 @@ enum max77686_ramp_rate { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | struct max77686_data { | 67 | struct max77686_data { |
| 68 | struct regulator_dev *rdev[MAX77686_REGULATORS]; | ||
| 69 | unsigned int opmode[MAX77686_REGULATORS]; | 68 | unsigned int opmode[MAX77686_REGULATORS]; |
| 70 | }; | 69 | }; |
| 71 | 70 | ||
| @@ -400,7 +399,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 400 | unsigned int i; | 399 | unsigned int i; |
| 401 | 400 | ||
| 402 | pmic_np = iodev->dev->of_node; | 401 | pmic_np = iodev->dev->of_node; |
| 403 | regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); | 402 | regulators_np = of_get_child_by_name(pmic_np, "voltage-regulators"); |
| 404 | if (!regulators_np) { | 403 | if (!regulators_np) { |
| 405 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 404 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 406 | return -EINVAL; | 405 | return -EINVAL; |
| @@ -410,8 +409,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 410 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | 409 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
| 411 | pdata->num_regulators, GFP_KERNEL); | 410 | pdata->num_regulators, GFP_KERNEL); |
| 412 | if (!rdata) { | 411 | if (!rdata) { |
| 413 | dev_err(&pdev->dev, | 412 | of_node_put(regulators_np); |
| 414 | "could not allocate memory for regulator data\n"); | ||
| 415 | return -ENOMEM; | 413 | return -ENOMEM; |
| 416 | } | 414 | } |
| 417 | 415 | ||
| @@ -425,6 +423,7 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 425 | } | 423 | } |
| 426 | 424 | ||
| 427 | pdata->regulators = rdata; | 425 | pdata->regulators = rdata; |
| 426 | of_node_put(regulators_np); | ||
| 428 | 427 | ||
| 429 | return 0; | 428 | return 0; |
| 430 | } | 429 | } |
| @@ -474,16 +473,18 @@ static int max77686_pmic_probe(struct platform_device *pdev) | |||
| 474 | platform_set_drvdata(pdev, max77686); | 473 | platform_set_drvdata(pdev, max77686); |
| 475 | 474 | ||
| 476 | for (i = 0; i < MAX77686_REGULATORS; i++) { | 475 | for (i = 0; i < MAX77686_REGULATORS; i++) { |
| 476 | struct regulator_dev *rdev; | ||
| 477 | |||
| 477 | config.init_data = pdata->regulators[i].initdata; | 478 | config.init_data = pdata->regulators[i].initdata; |
| 478 | config.of_node = pdata->regulators[i].of_node; | 479 | config.of_node = pdata->regulators[i].of_node; |
| 479 | 480 | ||
| 480 | max77686->opmode[i] = regulators[i].enable_mask; | 481 | max77686->opmode[i] = regulators[i].enable_mask; |
| 481 | max77686->rdev[i] = devm_regulator_register(&pdev->dev, | 482 | rdev = devm_regulator_register(&pdev->dev, |
| 482 | ®ulators[i], &config); | 483 | ®ulators[i], &config); |
| 483 | if (IS_ERR(max77686->rdev[i])) { | 484 | if (IS_ERR(rdev)) { |
| 484 | dev_err(&pdev->dev, | 485 | dev_err(&pdev->dev, |
| 485 | "regulator init failed for %d\n", i); | 486 | "regulator init failed for %d\n", i); |
| 486 | return PTR_ERR(max77686->rdev[i]); | 487 | return PTR_ERR(rdev); |
| 487 | } | 488 | } |
| 488 | } | 489 | } |
| 489 | 490 | ||
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index 5fb899f461d0..653a58b49cdf 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c | |||
| @@ -34,13 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | #define CHGIN_ILIM_STEP_20mA 20000 | 35 | #define CHGIN_ILIM_STEP_20mA 20000 |
| 36 | 36 | ||
| 37 | struct max77693_pmic_dev { | ||
| 38 | struct device *dev; | ||
| 39 | struct max77693_dev *iodev; | ||
| 40 | int num_regulators; | ||
| 41 | struct regulator_dev **rdev; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* CHARGER regulator ops */ | 37 | /* CHARGER regulator ops */ |
| 45 | /* CHARGER regulator uses two bits for enabling */ | 38 | /* CHARGER regulator uses two bits for enabling */ |
| 46 | static int max77693_chg_is_enabled(struct regulator_dev *rdev) | 39 | static int max77693_chg_is_enabled(struct regulator_dev *rdev) |
| @@ -170,19 +163,22 @@ static int max77693_pmic_dt_parse_rdata(struct device *dev, | |||
| 170 | struct max77693_regulator_data *tmp; | 163 | struct max77693_regulator_data *tmp; |
| 171 | int i, matched = 0; | 164 | int i, matched = 0; |
| 172 | 165 | ||
| 173 | np = of_find_node_by_name(dev->parent->of_node, "regulators"); | 166 | np = of_get_child_by_name(dev->parent->of_node, "regulators"); |
| 174 | if (!np) | 167 | if (!np) |
| 175 | return -EINVAL; | 168 | return -EINVAL; |
| 176 | 169 | ||
| 177 | rmatch = devm_kzalloc(dev, | 170 | rmatch = devm_kzalloc(dev, |
| 178 | sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); | 171 | sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); |
| 179 | if (!rmatch) | 172 | if (!rmatch) { |
| 173 | of_node_put(np); | ||
| 180 | return -ENOMEM; | 174 | return -ENOMEM; |
| 175 | } | ||
| 181 | 176 | ||
| 182 | for (i = 0; i < ARRAY_SIZE(regulators); i++) | 177 | for (i = 0; i < ARRAY_SIZE(regulators); i++) |
| 183 | rmatch[i].name = regulators[i].name; | 178 | rmatch[i].name = regulators[i].name; |
| 184 | 179 | ||
| 185 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); | 180 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); |
| 181 | of_node_put(np); | ||
| 186 | if (matched <= 0) | 182 | if (matched <= 0) |
| 187 | return matched; | 183 | return matched; |
| 188 | *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); | 184 | *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); |
| @@ -229,7 +225,6 @@ static int max77693_pmic_init_rdata(struct device *dev, | |||
| 229 | static int max77693_pmic_probe(struct platform_device *pdev) | 225 | static int max77693_pmic_probe(struct platform_device *pdev) |
| 230 | { | 226 | { |
| 231 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 227 | struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 232 | struct max77693_pmic_dev *max77693_pmic; | ||
| 233 | struct max77693_regulator_data *rdata = NULL; | 228 | struct max77693_regulator_data *rdata = NULL; |
| 234 | int num_rdata, i; | 229 | int num_rdata, i; |
| 235 | struct regulator_config config; | 230 | struct regulator_config config; |
| @@ -240,39 +235,22 @@ static int max77693_pmic_probe(struct platform_device *pdev) | |||
| 240 | return -ENODEV; | 235 | return -ENODEV; |
| 241 | } | 236 | } |
| 242 | 237 | ||
| 243 | max77693_pmic = devm_kzalloc(&pdev->dev, | ||
| 244 | sizeof(struct max77693_pmic_dev), | ||
| 245 | GFP_KERNEL); | ||
| 246 | if (!max77693_pmic) | ||
| 247 | return -ENOMEM; | ||
| 248 | |||
| 249 | max77693_pmic->rdev = devm_kzalloc(&pdev->dev, | ||
| 250 | sizeof(struct regulator_dev *) * num_rdata, | ||
| 251 | GFP_KERNEL); | ||
| 252 | if (!max77693_pmic->rdev) | ||
| 253 | return -ENOMEM; | ||
| 254 | |||
| 255 | max77693_pmic->dev = &pdev->dev; | ||
| 256 | max77693_pmic->iodev = iodev; | ||
| 257 | max77693_pmic->num_regulators = num_rdata; | ||
| 258 | |||
| 259 | config.dev = &pdev->dev; | 238 | config.dev = &pdev->dev; |
| 260 | config.regmap = iodev->regmap; | 239 | config.regmap = iodev->regmap; |
| 261 | config.driver_data = max77693_pmic; | ||
| 262 | platform_set_drvdata(pdev, max77693_pmic); | ||
| 263 | 240 | ||
| 264 | for (i = 0; i < max77693_pmic->num_regulators; i++) { | 241 | for (i = 0; i < num_rdata; i++) { |
| 265 | int id = rdata[i].id; | 242 | int id = rdata[i].id; |
| 243 | struct regulator_dev *rdev; | ||
| 266 | 244 | ||
| 267 | config.init_data = rdata[i].initdata; | 245 | config.init_data = rdata[i].initdata; |
| 268 | config.of_node = rdata[i].of_node; | 246 | config.of_node = rdata[i].of_node; |
| 269 | 247 | ||
| 270 | max77693_pmic->rdev[i] = devm_regulator_register(&pdev->dev, | 248 | rdev = devm_regulator_register(&pdev->dev, |
| 271 | ®ulators[id], &config); | 249 | ®ulators[id], &config); |
| 272 | if (IS_ERR(max77693_pmic->rdev[i])) { | 250 | if (IS_ERR(rdev)) { |
| 273 | dev_err(max77693_pmic->dev, | 251 | dev_err(&pdev->dev, |
| 274 | "Failed to initialize regulator-%d\n", id); | 252 | "Failed to initialize regulator-%d\n", id); |
| 275 | return PTR_ERR(max77693_pmic->rdev[i]); | 253 | return PTR_ERR(rdev); |
| 276 | } | 254 | } |
| 277 | } | 255 | } |
| 278 | 256 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 7f049c92ee52..3172da847d24 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | #define MAX8649_RAMP_DOWN (1 << 1) | 49 | #define MAX8649_RAMP_DOWN (1 << 1) |
| 50 | 50 | ||
| 51 | struct max8649_regulator_info { | 51 | struct max8649_regulator_info { |
| 52 | struct regulator_dev *regulator; | ||
| 53 | struct device *dev; | 52 | struct device *dev; |
| 54 | struct regmap *regmap; | 53 | struct regmap *regmap; |
| 55 | 54 | ||
| @@ -154,6 +153,7 @@ static int max8649_regulator_probe(struct i2c_client *client, | |||
| 154 | { | 153 | { |
| 155 | struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); | 154 | struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); |
| 156 | struct max8649_regulator_info *info = NULL; | 155 | struct max8649_regulator_info *info = NULL; |
| 156 | struct regulator_dev *regulator; | ||
| 157 | struct regulator_config config = { }; | 157 | struct regulator_config config = { }; |
| 158 | unsigned int val; | 158 | unsigned int val; |
| 159 | unsigned char data; | 159 | unsigned char data; |
| @@ -234,12 +234,12 @@ static int max8649_regulator_probe(struct i2c_client *client, | |||
| 234 | config.driver_data = info; | 234 | config.driver_data = info; |
| 235 | config.regmap = info->regmap; | 235 | config.regmap = info->regmap; |
| 236 | 236 | ||
| 237 | info->regulator = devm_regulator_register(&client->dev, &dcdc_desc, | 237 | regulator = devm_regulator_register(&client->dev, &dcdc_desc, |
| 238 | &config); | 238 | &config); |
| 239 | if (IS_ERR(info->regulator)) { | 239 | if (IS_ERR(regulator)) { |
| 240 | dev_err(info->dev, "failed to register regulator %s\n", | 240 | dev_err(info->dev, "failed to register regulator %s\n", |
| 241 | dcdc_desc.name); | 241 | dcdc_desc.name); |
| 242 | return PTR_ERR(info->regulator); | 242 | return PTR_ERR(regulator); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | return 0; | 245 | return 0; |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 8d94d3d7f97f..2fc411188794 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
| @@ -81,16 +81,17 @@ enum { | |||
| 81 | struct max8660 { | 81 | struct max8660 { |
| 82 | struct i2c_client *client; | 82 | struct i2c_client *client; |
| 83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ | 83 | u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ |
| 84 | struct regulator_dev *rdev[]; | ||
| 85 | }; | 84 | }; |
| 86 | 85 | ||
| 87 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) | 86 | static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) |
| 88 | { | 87 | { |
| 89 | static const u8 max8660_addresses[MAX8660_N_REGS] = | 88 | static const u8 max8660_addresses[MAX8660_N_REGS] = { |
| 90 | { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 }; | 89 | 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 |
| 90 | }; | ||
| 91 | 91 | ||
| 92 | int ret; | 92 | int ret; |
| 93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; | 93 | u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; |
| 94 | |||
| 94 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", | 95 | dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", |
| 95 | max8660_addresses[reg], reg_val); | 96 | max8660_addresses[reg], reg_val); |
| 96 | 97 | ||
| @@ -112,6 +113,7 @@ static int max8660_dcdc_is_enabled(struct regulator_dev *rdev) | |||
| 112 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 113 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 113 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; | 114 | u8 val = max8660->shadow_regs[MAX8660_OVER1]; |
| 114 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 115 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
| 116 | |||
| 115 | return !!(val & mask); | 117 | return !!(val & mask); |
| 116 | } | 118 | } |
| 117 | 119 | ||
| @@ -119,6 +121,7 @@ static int max8660_dcdc_enable(struct regulator_dev *rdev) | |||
| 119 | { | 121 | { |
| 120 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 122 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 121 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; | 123 | u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; |
| 124 | |||
| 122 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); | 125 | return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); |
| 123 | } | 126 | } |
| 124 | 127 | ||
| @@ -126,15 +129,16 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev) | |||
| 126 | { | 129 | { |
| 127 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 130 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 128 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; | 131 | u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; |
| 132 | |||
| 129 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); | 133 | return max8660_write(max8660, MAX8660_OVER1, mask, 0); |
| 130 | } | 134 | } |
| 131 | 135 | ||
| 132 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) | 136 | static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) |
| 133 | { | 137 | { |
| 134 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 138 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 135 | |||
| 136 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; | 139 | u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; |
| 137 | u8 selector = max8660->shadow_regs[reg]; | 140 | u8 selector = max8660->shadow_regs[reg]; |
| 141 | |||
| 138 | return selector; | 142 | return selector; |
| 139 | } | 143 | } |
| 140 | 144 | ||
| @@ -207,6 +211,7 @@ static int max8660_ldo67_is_enabled(struct regulator_dev *rdev) | |||
| 207 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 211 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 208 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; | 212 | u8 val = max8660->shadow_regs[MAX8660_OVER2]; |
| 209 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 213 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
| 214 | |||
| 210 | return !!(val & mask); | 215 | return !!(val & mask); |
| 211 | } | 216 | } |
| 212 | 217 | ||
| @@ -214,6 +219,7 @@ static int max8660_ldo67_enable(struct regulator_dev *rdev) | |||
| 214 | { | 219 | { |
| 215 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 220 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 216 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; | 221 | u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; |
| 222 | |||
| 217 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); | 223 | return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); |
| 218 | } | 224 | } |
| 219 | 225 | ||
| @@ -221,15 +227,16 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev) | |||
| 221 | { | 227 | { |
| 222 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 228 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 223 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; | 229 | u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; |
| 230 | |||
| 224 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); | 231 | return max8660_write(max8660, MAX8660_OVER2, mask, 0); |
| 225 | } | 232 | } |
| 226 | 233 | ||
| 227 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) | 234 | static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) |
| 228 | { | 235 | { |
| 229 | struct max8660 *max8660 = rdev_get_drvdata(rdev); | 236 | struct max8660 *max8660 = rdev_get_drvdata(rdev); |
| 230 | |||
| 231 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; | 237 | u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; |
| 232 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; | 238 | u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; |
| 239 | |||
| 233 | return selector; | 240 | return selector; |
| 234 | } | 241 | } |
| 235 | 242 | ||
| @@ -330,7 +337,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
| 330 | struct max8660_subdev_data *sub; | 337 | struct max8660_subdev_data *sub; |
| 331 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; | 338 | struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)]; |
| 332 | 339 | ||
| 333 | np = of_find_node_by_name(dev->of_node, "regulators"); | 340 | np = of_get_child_by_name(dev->of_node, "regulators"); |
| 334 | if (!np) { | 341 | if (!np) { |
| 335 | dev_err(dev, "missing 'regulators' subnode in DT\n"); | 342 | dev_err(dev, "missing 'regulators' subnode in DT\n"); |
| 336 | return -EINVAL; | 343 | return -EINVAL; |
| @@ -340,6 +347,7 @@ static int max8660_pdata_from_dt(struct device *dev, | |||
| 340 | rmatch[i].name = max8660_reg[i].name; | 347 | rmatch[i].name = max8660_reg[i].name; |
| 341 | 348 | ||
| 342 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); | 349 | matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch)); |
| 350 | of_node_put(np); | ||
| 343 | if (matched <= 0) | 351 | if (matched <= 0) |
| 344 | return matched; | 352 | return matched; |
| 345 | 353 | ||
| @@ -373,7 +381,6 @@ static inline int max8660_pdata_from_dt(struct device *dev, | |||
| 373 | static int max8660_probe(struct i2c_client *client, | 381 | static int max8660_probe(struct i2c_client *client, |
| 374 | const struct i2c_device_id *i2c_id) | 382 | const struct i2c_device_id *i2c_id) |
| 375 | { | 383 | { |
| 376 | struct regulator_dev **rdev; | ||
| 377 | struct device *dev = &client->dev; | 384 | struct device *dev = &client->dev; |
| 378 | struct max8660_platform_data *pdata = dev_get_platdata(dev); | 385 | struct max8660_platform_data *pdata = dev_get_platdata(dev); |
| 379 | struct regulator_config config = { }; | 386 | struct regulator_config config = { }; |
| @@ -406,14 +413,11 @@ static int max8660_probe(struct i2c_client *client, | |||
| 406 | return -EINVAL; | 413 | return -EINVAL; |
| 407 | } | 414 | } |
| 408 | 415 | ||
| 409 | max8660 = devm_kzalloc(dev, sizeof(struct max8660) + | 416 | max8660 = devm_kzalloc(dev, sizeof(struct max8660), GFP_KERNEL); |
| 410 | sizeof(struct regulator_dev *) * MAX8660_V_END, | ||
| 411 | GFP_KERNEL); | ||
| 412 | if (!max8660) | 417 | if (!max8660) |
| 413 | return -ENOMEM; | 418 | return -ENOMEM; |
| 414 | 419 | ||
| 415 | max8660->client = client; | 420 | max8660->client = client; |
| 416 | rdev = max8660->rdev; | ||
| 417 | 421 | ||
| 418 | if (pdata->en34_is_high) { | 422 | if (pdata->en34_is_high) { |
| 419 | /* Simulate always on */ | 423 | /* Simulate always on */ |
| @@ -481,6 +485,7 @@ static int max8660_probe(struct i2c_client *client, | |||
| 481 | 485 | ||
| 482 | /* Finally register devices */ | 486 | /* Finally register devices */ |
| 483 | for (i = 0; i < pdata->num_subdevs; i++) { | 487 | for (i = 0; i < pdata->num_subdevs; i++) { |
| 488 | struct regulator_dev *rdev; | ||
| 484 | 489 | ||
| 485 | id = pdata->subdevs[i].id; | 490 | id = pdata->subdevs[i].id; |
| 486 | 491 | ||
| @@ -489,13 +494,13 @@ static int max8660_probe(struct i2c_client *client, | |||
| 489 | config.of_node = of_node[i]; | 494 | config.of_node = of_node[i]; |
| 490 | config.driver_data = max8660; | 495 | config.driver_data = max8660; |
| 491 | 496 | ||
| 492 | rdev[i] = devm_regulator_register(&client->dev, | 497 | rdev = devm_regulator_register(&client->dev, |
| 493 | &max8660_reg[id], &config); | 498 | &max8660_reg[id], &config); |
| 494 | if (IS_ERR(rdev[i])) { | 499 | if (IS_ERR(rdev)) { |
| 495 | ret = PTR_ERR(rdev[i]); | 500 | ret = PTR_ERR(rdev); |
| 496 | dev_err(&client->dev, "failed to register %s\n", | 501 | dev_err(&client->dev, "failed to register %s\n", |
| 497 | max8660_reg[id].name); | 502 | max8660_reg[id].name); |
| 498 | return PTR_ERR(rdev[i]); | 503 | return PTR_ERR(rdev); |
| 499 | } | 504 | } |
| 500 | } | 505 | } |
| 501 | 506 | ||
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 0c5fe6c6ac26..9623e9e290bf 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | struct max8907_regulator { | 35 | struct max8907_regulator { |
| 36 | struct regulator_desc desc[MAX8907_NUM_REGULATORS]; | 36 | struct regulator_desc desc[MAX8907_NUM_REGULATORS]; |
| 37 | struct regulator_dev *rdev[MAX8907_NUM_REGULATORS]; | ||
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | #define REG_MBATT() \ | 39 | #define REG_MBATT() \ |
| @@ -231,7 +230,7 @@ static int max8907_regulator_parse_dt(struct platform_device *pdev) | |||
| 231 | if (!np) | 230 | if (!np) |
| 232 | return 0; | 231 | return 0; |
| 233 | 232 | ||
| 234 | regulators = of_find_node_by_name(np, "regulators"); | 233 | regulators = of_get_child_by_name(np, "regulators"); |
| 235 | if (!regulators) { | 234 | if (!regulators) { |
| 236 | dev_err(&pdev->dev, "regulators node not found\n"); | 235 | dev_err(&pdev->dev, "regulators node not found\n"); |
| 237 | return -EINVAL; | 236 | return -EINVAL; |
| @@ -292,10 +291,9 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 292 | return ret; | 291 | return ret; |
| 293 | 292 | ||
| 294 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | 293 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); |
| 295 | if (!pmic) { | 294 | if (!pmic) |
| 296 | dev_err(&pdev->dev, "Failed to alloc pmic\n"); | ||
| 297 | return -ENOMEM; | 295 | return -ENOMEM; |
| 298 | } | 296 | |
| 299 | platform_set_drvdata(pdev, pmic); | 297 | platform_set_drvdata(pdev, pmic); |
| 300 | 298 | ||
| 301 | memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); | 299 | memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); |
| @@ -311,6 +309,8 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 311 | } | 309 | } |
| 312 | 310 | ||
| 313 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { | 311 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { |
| 312 | struct regulator_dev *rdev; | ||
| 313 | |||
| 314 | config.dev = pdev->dev.parent; | 314 | config.dev = pdev->dev.parent; |
| 315 | if (pdata) | 315 | if (pdata) |
| 316 | idata = pdata->init_data[i]; | 316 | idata = pdata->init_data[i]; |
| @@ -350,13 +350,13 @@ static int max8907_regulator_probe(struct platform_device *pdev) | |||
| 350 | pmic->desc[i].ops = &max8907_out5v_hwctl_ops; | 350 | pmic->desc[i].ops = &max8907_out5v_hwctl_ops; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | pmic->rdev[i] = devm_regulator_register(&pdev->dev, | 353 | rdev = devm_regulator_register(&pdev->dev, |
| 354 | &pmic->desc[i], &config); | 354 | &pmic->desc[i], &config); |
| 355 | if (IS_ERR(pmic->rdev[i])) { | 355 | if (IS_ERR(rdev)) { |
| 356 | dev_err(&pdev->dev, | 356 | dev_err(&pdev->dev, |
| 357 | "failed to register %s regulator\n", | 357 | "failed to register %s regulator\n", |
| 358 | pmic->desc[i].name); | 358 | pmic->desc[i].name); |
| 359 | return PTR_ERR(pmic->rdev[i]); | 359 | return PTR_ERR(rdev); |
| 360 | } | 360 | } |
| 361 | } | 361 | } |
| 362 | 362 | ||
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 759510789e71..dad2bcd14e96 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c | |||
| @@ -36,9 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | struct max8925_regulator_info { | 37 | struct max8925_regulator_info { |
| 38 | struct regulator_desc desc; | 38 | struct regulator_desc desc; |
| 39 | struct regulator_dev *regulator; | ||
| 40 | struct i2c_client *i2c; | 39 | struct i2c_client *i2c; |
| 41 | struct max8925_chip *chip; | ||
| 42 | 40 | ||
| 43 | int vol_reg; | 41 | int vol_reg; |
| 44 | int enable_reg; | 42 | int enable_reg; |
| @@ -251,10 +249,11 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, | |||
| 251 | { | 249 | { |
| 252 | struct device_node *nproot, *np; | 250 | struct device_node *nproot, *np; |
| 253 | int rcount; | 251 | int rcount; |
| 252 | |||
| 254 | nproot = of_node_get(pdev->dev.parent->of_node); | 253 | nproot = of_node_get(pdev->dev.parent->of_node); |
| 255 | if (!nproot) | 254 | if (!nproot) |
| 256 | return -ENODEV; | 255 | return -ENODEV; |
| 257 | np = of_find_node_by_name(nproot, "regulators"); | 256 | np = of_get_child_by_name(nproot, "regulators"); |
| 258 | if (!np) { | 257 | if (!np) { |
| 259 | dev_err(&pdev->dev, "failed to find regulators node\n"); | 258 | dev_err(&pdev->dev, "failed to find regulators node\n"); |
| 260 | return -ENODEV; | 259 | return -ENODEV; |
| @@ -264,7 +263,7 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, | |||
| 264 | &max8925_regulator_matches[ridx], 1); | 263 | &max8925_regulator_matches[ridx], 1); |
| 265 | of_node_put(np); | 264 | of_node_put(np); |
| 266 | if (rcount < 0) | 265 | if (rcount < 0) |
| 267 | return -ENODEV; | 266 | return rcount; |
| 268 | config->init_data = max8925_regulator_matches[ridx].init_data; | 267 | config->init_data = max8925_regulator_matches[ridx].init_data; |
| 269 | config->of_node = max8925_regulator_matches[ridx].of_node; | 268 | config->of_node = max8925_regulator_matches[ridx].of_node; |
| 270 | 269 | ||
| @@ -303,7 +302,6 @@ static int max8925_regulator_probe(struct platform_device *pdev) | |||
| 303 | return -EINVAL; | 302 | return -EINVAL; |
| 304 | } | 303 | } |
| 305 | ri->i2c = chip->i2c; | 304 | ri->i2c = chip->i2c; |
| 306 | ri->chip = chip; | ||
| 307 | 305 | ||
| 308 | config.dev = &pdev->dev; | 306 | config.dev = &pdev->dev; |
| 309 | config.driver_data = ri; | 307 | config.driver_data = ri; |
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 788e5ae2af1b..d920f5a32ec8 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
| @@ -48,9 +48,7 @@ enum { | |||
| 48 | 48 | ||
| 49 | struct max8952_data { | 49 | struct max8952_data { |
| 50 | struct i2c_client *client; | 50 | struct i2c_client *client; |
| 51 | struct device *dev; | ||
| 52 | struct max8952_platform_data *pdata; | 51 | struct max8952_platform_data *pdata; |
| 53 | struct regulator_dev *rdev; | ||
| 54 | 52 | ||
| 55 | bool vid0; | 53 | bool vid0; |
| 56 | bool vid1; | 54 | bool vid1; |
| @@ -59,6 +57,7 @@ struct max8952_data { | |||
| 59 | static int max8952_read_reg(struct max8952_data *max8952, u8 reg) | 57 | static int max8952_read_reg(struct max8952_data *max8952, u8 reg) |
| 60 | { | 58 | { |
| 61 | int ret = i2c_smbus_read_byte_data(max8952->client, reg); | 59 | int ret = i2c_smbus_read_byte_data(max8952->client, reg); |
| 60 | |||
| 62 | if (ret > 0) | 61 | if (ret > 0) |
| 63 | ret &= 0xff; | 62 | ret &= 0xff; |
| 64 | 63 | ||
| @@ -144,10 +143,8 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev) | |||
| 144 | int i; | 143 | int i; |
| 145 | 144 | ||
| 146 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | 145 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); |
| 147 | if (!pd) { | 146 | if (!pd) |
| 148 | dev_err(dev, "Failed to allocate platform data\n"); | ||
| 149 | return NULL; | 147 | return NULL; |
| 150 | } | ||
| 151 | 148 | ||
| 152 | pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0); | 149 | pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0); |
| 153 | pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1); | 150 | pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1); |
| @@ -199,6 +196,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 199 | struct max8952_platform_data *pdata = dev_get_platdata(&client->dev); | 196 | struct max8952_platform_data *pdata = dev_get_platdata(&client->dev); |
| 200 | struct regulator_config config = { }; | 197 | struct regulator_config config = { }; |
| 201 | struct max8952_data *max8952; | 198 | struct max8952_data *max8952; |
| 199 | struct regulator_dev *rdev; | ||
| 202 | 200 | ||
| 203 | int ret = 0, err = 0; | 201 | int ret = 0, err = 0; |
| 204 | 202 | ||
| @@ -219,10 +217,9 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 219 | return -ENOMEM; | 217 | return -ENOMEM; |
| 220 | 218 | ||
| 221 | max8952->client = client; | 219 | max8952->client = client; |
| 222 | max8952->dev = &client->dev; | ||
| 223 | max8952->pdata = pdata; | 220 | max8952->pdata = pdata; |
| 224 | 221 | ||
| 225 | config.dev = max8952->dev; | 222 | config.dev = &client->dev; |
| 226 | config.init_data = pdata->reg_data; | 223 | config.init_data = pdata->reg_data; |
| 227 | config.driver_data = max8952; | 224 | config.driver_data = max8952; |
| 228 | config.of_node = client->dev.of_node; | 225 | config.of_node = client->dev.of_node; |
| @@ -231,11 +228,11 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 231 | if (pdata->reg_data->constraints.boot_on) | 228 | if (pdata->reg_data->constraints.boot_on) |
| 232 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; | 229 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; |
| 233 | 230 | ||
| 234 | max8952->rdev = regulator_register(®ulator, &config); | 231 | rdev = devm_regulator_register(&client->dev, ®ulator, &config); |
| 235 | 232 | ||
| 236 | if (IS_ERR(max8952->rdev)) { | 233 | if (IS_ERR(rdev)) { |
| 237 | ret = PTR_ERR(max8952->rdev); | 234 | ret = PTR_ERR(rdev); |
| 238 | dev_err(max8952->dev, "regulator init failed (%d)\n", ret); | 235 | dev_err(&client->dev, "regulator init failed (%d)\n", ret); |
| 239 | return ret; | 236 | return ret; |
| 240 | } | 237 | } |
| 241 | 238 | ||
| @@ -263,7 +260,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 263 | err = 3; | 260 | err = 3; |
| 264 | 261 | ||
| 265 | if (err) { | 262 | if (err) { |
| 266 | dev_warn(max8952->dev, "VID0/1 gpio invalid: " | 263 | dev_warn(&client->dev, "VID0/1 gpio invalid: " |
| 267 | "DVS not available.\n"); | 264 | "DVS not available.\n"); |
| 268 | max8952->vid0 = 0; | 265 | max8952->vid0 = 0; |
| 269 | max8952->vid1 = 0; | 266 | max8952->vid1 = 0; |
| @@ -274,7 +271,7 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
| 274 | /* Disable Pulldown of EN only */ | 271 | /* Disable Pulldown of EN only */ |
| 275 | max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60); | 272 | max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60); |
| 276 | 273 | ||
| 277 | dev_err(max8952->dev, "DVS modes disabled because VID0 and VID1" | 274 | dev_err(&client->dev, "DVS modes disabled because VID0 and VID1" |
| 278 | " do not have proper controls.\n"); | 275 | " do not have proper controls.\n"); |
| 279 | } else { | 276 | } else { |
| 280 | /* | 277 | /* |
| @@ -321,9 +318,6 @@ static int max8952_pmic_remove(struct i2c_client *client) | |||
| 321 | { | 318 | { |
| 322 | struct max8952_data *max8952 = i2c_get_clientdata(client); | 319 | struct max8952_data *max8952 = i2c_get_clientdata(client); |
| 323 | struct max8952_platform_data *pdata = max8952->pdata; | 320 | struct max8952_platform_data *pdata = max8952->pdata; |
| 324 | struct regulator_dev *rdev = max8952->rdev; | ||
| 325 | |||
| 326 | regulator_unregister(rdev); | ||
| 327 | 321 | ||
| 328 | gpio_free(pdata->gpio_vid0); | 322 | gpio_free(pdata->gpio_vid0); |
| 329 | gpio_free(pdata->gpio_vid1); | 323 | gpio_free(pdata->gpio_vid1); |
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 892aa1e5b96c..dbedf1768db0 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c | |||
| @@ -93,7 +93,6 @@ | |||
| 93 | struct max8973_chip { | 93 | struct max8973_chip { |
| 94 | struct device *dev; | 94 | struct device *dev; |
| 95 | struct regulator_desc desc; | 95 | struct regulator_desc desc; |
| 96 | struct regulator_dev *rdev; | ||
| 97 | struct regmap *regmap; | 96 | struct regmap *regmap; |
| 98 | bool enable_external_control; | 97 | bool enable_external_control; |
| 99 | int dvs_gpio; | 98 | int dvs_gpio; |
| @@ -379,10 +378,8 @@ static int max8973_probe(struct i2c_client *client, | |||
| 379 | } | 378 | } |
| 380 | 379 | ||
| 381 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); | 380 | max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); |
| 382 | if (!max) { | 381 | if (!max) |
| 383 | dev_err(&client->dev, "Memory allocation for max failed\n"); | ||
| 384 | return -ENOMEM; | 382 | return -ENOMEM; |
| 385 | } | ||
| 386 | 383 | ||
| 387 | max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); | 384 | max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); |
| 388 | if (IS_ERR(max->regmap)) { | 385 | if (IS_ERR(max->regmap)) { |
| @@ -474,7 +471,6 @@ static int max8973_probe(struct i2c_client *client, | |||
| 474 | return ret; | 471 | return ret; |
| 475 | } | 472 | } |
| 476 | 473 | ||
| 477 | max->rdev = rdev; | ||
| 478 | return 0; | 474 | return 0; |
| 479 | } | 475 | } |
| 480 | 476 | ||
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 2d618fc9c1af..90b4c530dee5 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
| @@ -38,7 +38,6 @@ struct max8997_data { | |||
| 38 | struct device *dev; | 38 | struct device *dev; |
| 39 | struct max8997_dev *iodev; | 39 | struct max8997_dev *iodev; |
| 40 | int num_regulators; | 40 | int num_regulators; |
| 41 | struct regulator_dev **rdev; | ||
| 42 | int ramp_delay; /* in mV/us */ | 41 | int ramp_delay; /* in mV/us */ |
| 43 | 42 | ||
| 44 | bool buck1_gpiodvs; | 43 | bool buck1_gpiodvs; |
| @@ -924,7 +923,7 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 924 | return -ENODEV; | 923 | return -ENODEV; |
| 925 | } | 924 | } |
| 926 | 925 | ||
| 927 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 926 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); |
| 928 | if (!regulators_np) { | 927 | if (!regulators_np) { |
| 929 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 928 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 930 | return -EINVAL; | 929 | return -EINVAL; |
| @@ -937,7 +936,6 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 937 | pdata->num_regulators, GFP_KERNEL); | 936 | pdata->num_regulators, GFP_KERNEL); |
| 938 | if (!rdata) { | 937 | if (!rdata) { |
| 939 | of_node_put(regulators_np); | 938 | of_node_put(regulators_np); |
| 940 | dev_err(&pdev->dev, "could not allocate memory for regulator data\n"); | ||
| 941 | return -ENOMEM; | 939 | return -ENOMEM; |
| 942 | } | 940 | } |
| 943 | 941 | ||
| @@ -1030,10 +1028,10 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1030 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 1028 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 1031 | struct max8997_platform_data *pdata = iodev->pdata; | 1029 | struct max8997_platform_data *pdata = iodev->pdata; |
| 1032 | struct regulator_config config = { }; | 1030 | struct regulator_config config = { }; |
| 1033 | struct regulator_dev **rdev; | 1031 | struct regulator_dev *rdev; |
| 1034 | struct max8997_data *max8997; | 1032 | struct max8997_data *max8997; |
| 1035 | struct i2c_client *i2c; | 1033 | struct i2c_client *i2c; |
| 1036 | int i, ret, size, nr_dvs; | 1034 | int i, ret, nr_dvs; |
| 1037 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; | 1035 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; |
| 1038 | 1036 | ||
| 1039 | if (!pdata) { | 1037 | if (!pdata) { |
| @@ -1052,12 +1050,6 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1052 | if (!max8997) | 1050 | if (!max8997) |
| 1053 | return -ENOMEM; | 1051 | return -ENOMEM; |
| 1054 | 1052 | ||
| 1055 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; | ||
| 1056 | max8997->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
| 1057 | if (!max8997->rdev) | ||
| 1058 | return -ENOMEM; | ||
| 1059 | |||
| 1060 | rdev = max8997->rdev; | ||
| 1061 | max8997->dev = &pdev->dev; | 1053 | max8997->dev = &pdev->dev; |
| 1062 | max8997->iodev = iodev; | 1054 | max8997->iodev = iodev; |
| 1063 | max8997->num_regulators = pdata->num_regulators; | 1055 | max8997->num_regulators = pdata->num_regulators; |
| @@ -1205,12 +1197,12 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
| 1205 | config.driver_data = max8997; | 1197 | config.driver_data = max8997; |
| 1206 | config.of_node = pdata->regulators[i].reg_node; | 1198 | config.of_node = pdata->regulators[i].reg_node; |
| 1207 | 1199 | ||
| 1208 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], | 1200 | rdev = devm_regulator_register(&pdev->dev, ®ulators[id], |
| 1209 | &config); | 1201 | &config); |
| 1210 | if (IS_ERR(rdev[i])) { | 1202 | if (IS_ERR(rdev)) { |
| 1211 | dev_err(max8997->dev, "regulator init failed for %d\n", | 1203 | dev_err(max8997->dev, "regulator init failed for %d\n", |
| 1212 | id); | 1204 | id); |
| 1213 | return PTR_ERR(rdev[i]); | 1205 | return PTR_ERR(rdev); |
| 1214 | } | 1206 | } |
| 1215 | } | 1207 | } |
| 1216 | 1208 | ||
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index ae3f0656feb0..961091b46557 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
| @@ -40,7 +40,6 @@ struct max8998_data { | |||
| 40 | struct device *dev; | 40 | struct device *dev; |
| 41 | struct max8998_dev *iodev; | 41 | struct max8998_dev *iodev; |
| 42 | int num_regulators; | 42 | int num_regulators; |
| 43 | struct regulator_dev **rdev; | ||
| 44 | u8 buck1_vol[4]; /* voltages for selection */ | 43 | u8 buck1_vol[4]; /* voltages for selection */ |
| 45 | u8 buck2_vol[2]; | 44 | u8 buck2_vol[2]; |
| 46 | unsigned int buck1_idx; /* index to last changed voltage */ | 45 | unsigned int buck1_idx; /* index to last changed voltage */ |
| @@ -674,8 +673,10 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, | |||
| 674 | 673 | ||
| 675 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * | 674 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * |
| 676 | pdata->num_regulators, GFP_KERNEL); | 675 | pdata->num_regulators, GFP_KERNEL); |
| 677 | if (!rdata) | 676 | if (!rdata) { |
| 677 | of_node_put(regulators_np); | ||
| 678 | return -ENOMEM; | 678 | return -ENOMEM; |
| 679 | } | ||
| 679 | 680 | ||
| 680 | pdata->regulators = rdata; | 681 | pdata->regulators = rdata; |
| 681 | for (i = 0; i < ARRAY_SIZE(regulators); ++i) { | 682 | for (i = 0; i < ARRAY_SIZE(regulators); ++i) { |
| @@ -692,6 +693,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, | |||
| 692 | } | 693 | } |
| 693 | pdata->num_regulators = rdata - pdata->regulators; | 694 | pdata->num_regulators = rdata - pdata->regulators; |
| 694 | 695 | ||
| 696 | of_node_put(reg_np); | ||
| 697 | of_node_put(regulators_np); | ||
| 698 | |||
| 695 | ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); | 699 | ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); |
| 696 | if (ret) | 700 | if (ret) |
| 697 | return -EINVAL; | 701 | return -EINVAL; |
| @@ -741,10 +745,10 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 741 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 745 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 742 | struct max8998_platform_data *pdata = iodev->pdata; | 746 | struct max8998_platform_data *pdata = iodev->pdata; |
| 743 | struct regulator_config config = { }; | 747 | struct regulator_config config = { }; |
| 744 | struct regulator_dev **rdev; | 748 | struct regulator_dev *rdev; |
| 745 | struct max8998_data *max8998; | 749 | struct max8998_data *max8998; |
| 746 | struct i2c_client *i2c; | 750 | struct i2c_client *i2c; |
| 747 | int i, ret, size; | 751 | int i, ret; |
| 748 | unsigned int v; | 752 | unsigned int v; |
| 749 | 753 | ||
| 750 | if (!pdata) { | 754 | if (!pdata) { |
| @@ -763,12 +767,6 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 763 | if (!max8998) | 767 | if (!max8998) |
| 764 | return -ENOMEM; | 768 | return -ENOMEM; |
| 765 | 769 | ||
| 766 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; | ||
| 767 | max8998->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
| 768 | if (!max8998->rdev) | ||
| 769 | return -ENOMEM; | ||
| 770 | |||
| 771 | rdev = max8998->rdev; | ||
| 772 | max8998->dev = &pdev->dev; | 770 | max8998->dev = &pdev->dev; |
| 773 | max8998->iodev = iodev; | 771 | max8998->iodev = iodev; |
| 774 | max8998->num_regulators = pdata->num_regulators; | 772 | max8998->num_regulators = pdata->num_regulators; |
| @@ -872,13 +870,12 @@ static int max8998_pmic_probe(struct platform_device *pdev) | |||
| 872 | config.init_data = pdata->regulators[i].initdata; | 870 | config.init_data = pdata->regulators[i].initdata; |
| 873 | config.driver_data = max8998; | 871 | config.driver_data = max8998; |
| 874 | 872 | ||
| 875 | rdev[i] = devm_regulator_register(&pdev->dev, | 873 | rdev = devm_regulator_register(&pdev->dev, ®ulators[index], |
| 876 | ®ulators[index], &config); | 874 | &config); |
| 877 | if (IS_ERR(rdev[i])) { | 875 | if (IS_ERR(rdev)) { |
| 878 | ret = PTR_ERR(rdev[i]); | 876 | ret = PTR_ERR(rdev); |
| 879 | dev_err(max8998->dev, "regulator %s init failed (%d)\n", | 877 | dev_err(max8998->dev, "regulator %s init failed (%d)\n", |
| 880 | regulators[index].name, ret); | 878 | regulators[index].name, ret); |
| 881 | rdev[i] = NULL; | ||
| 882 | return ret; | 879 | return ret; |
| 883 | } | 880 | } |
| 884 | } | 881 | } |
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index da4859282302..05b971726ffa 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
| @@ -167,8 +167,10 @@ int mc13xxx_get_num_regulators_dt(struct platform_device *pdev) | |||
| 167 | struct device_node *parent; | 167 | struct device_node *parent; |
| 168 | int num; | 168 | int num; |
| 169 | 169 | ||
| 170 | of_node_get(pdev->dev.parent->of_node); | 170 | if (!pdev->dev.parent->of_node) |
| 171 | parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 171 | return -ENODEV; |
| 172 | |||
| 173 | parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
| 172 | if (!parent) | 174 | if (!parent) |
| 173 | return -ENODEV; | 175 | return -ENODEV; |
| 174 | 176 | ||
| @@ -187,8 +189,10 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( | |||
| 187 | struct device_node *parent, *child; | 189 | struct device_node *parent, *child; |
| 188 | int i, parsed = 0; | 190 | int i, parsed = 0; |
| 189 | 191 | ||
| 190 | of_node_get(pdev->dev.parent->of_node); | 192 | if (!pdev->dev.parent->of_node) |
| 191 | parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); | 193 | return NULL; |
| 194 | |||
| 195 | parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
| 192 | if (!parent) | 196 | if (!parent) |
| 193 | return NULL; | 197 | return NULL; |
| 194 | 198 | ||
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index ab174f20ca11..67e678c4301c 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c | |||
| @@ -56,6 +56,8 @@ | |||
| 56 | #define PFUZE100_VGEN5VOL 0x70 | 56 | #define PFUZE100_VGEN5VOL 0x70 |
| 57 | #define PFUZE100_VGEN6VOL 0x71 | 57 | #define PFUZE100_VGEN6VOL 0x71 |
| 58 | 58 | ||
| 59 | enum chips { PFUZE100, PFUZE200 }; | ||
| 60 | |||
| 59 | struct pfuze_regulator { | 61 | struct pfuze_regulator { |
| 60 | struct regulator_desc desc; | 62 | struct regulator_desc desc; |
| 61 | unsigned char stby_reg; | 63 | unsigned char stby_reg; |
| @@ -63,6 +65,7 @@ struct pfuze_regulator { | |||
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| 65 | struct pfuze_chip { | 67 | struct pfuze_chip { |
| 68 | int chip_id; | ||
| 66 | struct regmap *regmap; | 69 | struct regmap *regmap; |
| 67 | struct device *dev; | 70 | struct device *dev; |
| 68 | struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; | 71 | struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; |
| @@ -78,21 +81,23 @@ static const int pfuze100_vsnvs[] = { | |||
| 78 | }; | 81 | }; |
| 79 | 82 | ||
| 80 | static const struct i2c_device_id pfuze_device_id[] = { | 83 | static const struct i2c_device_id pfuze_device_id[] = { |
| 81 | {.name = "pfuze100"}, | 84 | {.name = "pfuze100", .driver_data = PFUZE100}, |
| 82 | {}, | 85 | {.name = "pfuze200", .driver_data = PFUZE200}, |
| 86 | { } | ||
| 83 | }; | 87 | }; |
| 84 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | 88 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); |
| 85 | 89 | ||
| 86 | static const struct of_device_id pfuze_dt_ids[] = { | 90 | static const struct of_device_id pfuze_dt_ids[] = { |
| 87 | { .compatible = "fsl,pfuze100" }, | 91 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, |
| 88 | {}, | 92 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, |
| 93 | { } | ||
| 89 | }; | 94 | }; |
| 90 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); | 95 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); |
| 91 | 96 | ||
| 92 | static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | 97 | static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) |
| 93 | { | 98 | { |
| 94 | struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); | 99 | struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); |
| 95 | int id = rdev->desc->id; | 100 | int id = rdev_get_id(rdev); |
| 96 | unsigned int ramp_bits; | 101 | unsigned int ramp_bits; |
| 97 | int ret; | 102 | int ret; |
| 98 | 103 | ||
| @@ -139,14 +144,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 139 | 144 | ||
| 140 | }; | 145 | }; |
| 141 | 146 | ||
| 142 | #define PFUZE100_FIXED_REG(_name, base, voltage) \ | 147 | #define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \ |
| 143 | [PFUZE100_ ## _name] = { \ | 148 | [_chip ## _ ## _name] = { \ |
| 144 | .desc = { \ | 149 | .desc = { \ |
| 145 | .name = #_name, \ | 150 | .name = #_name, \ |
| 146 | .n_voltages = 1, \ | 151 | .n_voltages = 1, \ |
| 147 | .ops = &pfuze100_fixed_regulator_ops, \ | 152 | .ops = &pfuze100_fixed_regulator_ops, \ |
| 148 | .type = REGULATOR_VOLTAGE, \ | 153 | .type = REGULATOR_VOLTAGE, \ |
| 149 | .id = PFUZE100_ ## _name, \ | 154 | .id = _chip ## _ ## _name, \ |
| 150 | .owner = THIS_MODULE, \ | 155 | .owner = THIS_MODULE, \ |
| 151 | .min_uV = (voltage), \ | 156 | .min_uV = (voltage), \ |
| 152 | .enable_reg = (base), \ | 157 | .enable_reg = (base), \ |
| @@ -154,14 +159,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 154 | }, \ | 159 | }, \ |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | #define PFUZE100_SW_REG(_name, base, min, max, step) \ | 162 | #define PFUZE100_SW_REG(_chip, _name, base, min, max, step) \ |
| 158 | [PFUZE100_ ## _name] = { \ | 163 | [_chip ## _ ## _name] = { \ |
| 159 | .desc = { \ | 164 | .desc = { \ |
| 160 | .name = #_name,\ | 165 | .name = #_name,\ |
| 161 | .n_voltages = ((max) - (min)) / (step) + 1, \ | 166 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
| 162 | .ops = &pfuze100_sw_regulator_ops, \ | 167 | .ops = &pfuze100_sw_regulator_ops, \ |
| 163 | .type = REGULATOR_VOLTAGE, \ | 168 | .type = REGULATOR_VOLTAGE, \ |
| 164 | .id = PFUZE100_ ## _name, \ | 169 | .id = _chip ## _ ## _name, \ |
| 165 | .owner = THIS_MODULE, \ | 170 | .owner = THIS_MODULE, \ |
| 166 | .min_uV = (min), \ | 171 | .min_uV = (min), \ |
| 167 | .uV_step = (step), \ | 172 | .uV_step = (step), \ |
| @@ -172,14 +177,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 172 | .stby_mask = 0x3f, \ | 177 | .stby_mask = 0x3f, \ |
| 173 | } | 178 | } |
| 174 | 179 | ||
| 175 | #define PFUZE100_SWB_REG(_name, base, mask, voltages) \ | 180 | #define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \ |
| 176 | [PFUZE100_ ## _name] = { \ | 181 | [_chip ## _ ## _name] = { \ |
| 177 | .desc = { \ | 182 | .desc = { \ |
| 178 | .name = #_name, \ | 183 | .name = #_name, \ |
| 179 | .n_voltages = ARRAY_SIZE(voltages), \ | 184 | .n_voltages = ARRAY_SIZE(voltages), \ |
| 180 | .ops = &pfuze100_swb_regulator_ops, \ | 185 | .ops = &pfuze100_swb_regulator_ops, \ |
| 181 | .type = REGULATOR_VOLTAGE, \ | 186 | .type = REGULATOR_VOLTAGE, \ |
| 182 | .id = PFUZE100_ ## _name, \ | 187 | .id = _chip ## _ ## _name, \ |
| 183 | .owner = THIS_MODULE, \ | 188 | .owner = THIS_MODULE, \ |
| 184 | .volt_table = voltages, \ | 189 | .volt_table = voltages, \ |
| 185 | .vsel_reg = (base), \ | 190 | .vsel_reg = (base), \ |
| @@ -187,14 +192,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 187 | }, \ | 192 | }, \ |
| 188 | } | 193 | } |
| 189 | 194 | ||
| 190 | #define PFUZE100_VGEN_REG(_name, base, min, max, step) \ | 195 | #define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step) \ |
| 191 | [PFUZE100_ ## _name] = { \ | 196 | [_chip ## _ ## _name] = { \ |
| 192 | .desc = { \ | 197 | .desc = { \ |
| 193 | .name = #_name, \ | 198 | .name = #_name, \ |
| 194 | .n_voltages = ((max) - (min)) / (step) + 1, \ | 199 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
| 195 | .ops = &pfuze100_ldo_regulator_ops, \ | 200 | .ops = &pfuze100_ldo_regulator_ops, \ |
| 196 | .type = REGULATOR_VOLTAGE, \ | 201 | .type = REGULATOR_VOLTAGE, \ |
| 197 | .id = PFUZE100_ ## _name, \ | 202 | .id = _chip ## _ ## _name, \ |
| 198 | .owner = THIS_MODULE, \ | 203 | .owner = THIS_MODULE, \ |
| 199 | .min_uV = (min), \ | 204 | .min_uV = (min), \ |
| 200 | .uV_step = (step), \ | 205 | .uV_step = (step), \ |
| @@ -207,25 +212,45 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
| 207 | .stby_mask = 0x20, \ | 212 | .stby_mask = 0x20, \ |
| 208 | } | 213 | } |
| 209 | 214 | ||
| 215 | /* PFUZE100 */ | ||
| 210 | static struct pfuze_regulator pfuze100_regulators[] = { | 216 | static struct pfuze_regulator pfuze100_regulators[] = { |
| 211 | PFUZE100_SW_REG(SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | 217 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), |
| 212 | PFUZE100_SW_REG(SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), | 218 | PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), |
| 213 | PFUZE100_SW_REG(SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), | 219 | PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), |
| 214 | PFUZE100_SW_REG(SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), | 220 | PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), |
| 215 | PFUZE100_SW_REG(SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), | 221 | PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), |
| 216 | PFUZE100_SW_REG(SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000), | 222 | PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000), |
| 217 | PFUZE100_SWB_REG(SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), | 223 | PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), |
| 218 | PFUZE100_SWB_REG(VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | 224 | PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), |
| 219 | PFUZE100_FIXED_REG(VREFDDR, PFUZE100_VREFDDRCON, 750000), | 225 | PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000), |
| 220 | PFUZE100_VGEN_REG(VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), | 226 | PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), |
| 221 | PFUZE100_VGEN_REG(VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | 227 | PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), |
| 222 | PFUZE100_VGEN_REG(VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), | 228 | PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), |
| 223 | PFUZE100_VGEN_REG(VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), | 229 | PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), |
| 224 | PFUZE100_VGEN_REG(VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | 230 | PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), |
| 225 | PFUZE100_VGEN_REG(VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | 231 | PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), |
| 232 | }; | ||
| 233 | |||
| 234 | static struct pfuze_regulator pfuze200_regulators[] = { | ||
| 235 | PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | ||
| 236 | PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), | ||
| 237 | PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), | ||
| 238 | PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), | ||
| 239 | PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), | ||
| 240 | PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | ||
| 241 | PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000), | ||
| 242 | PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), | ||
| 243 | PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | ||
| 244 | PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), | ||
| 245 | PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), | ||
| 246 | PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | ||
| 247 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | ||
| 226 | }; | 248 | }; |
| 227 | 249 | ||
| 250 | static struct pfuze_regulator *pfuze_regulators; | ||
| 251 | |||
| 228 | #ifdef CONFIG_OF | 252 | #ifdef CONFIG_OF |
| 253 | /* PFUZE100 */ | ||
| 229 | static struct of_regulator_match pfuze100_matches[] = { | 254 | static struct of_regulator_match pfuze100_matches[] = { |
| 230 | { .name = "sw1ab", }, | 255 | { .name = "sw1ab", }, |
| 231 | { .name = "sw1c", }, | 256 | { .name = "sw1c", }, |
| @@ -244,24 +269,56 @@ static struct of_regulator_match pfuze100_matches[] = { | |||
| 244 | { .name = "vgen6", }, | 269 | { .name = "vgen6", }, |
| 245 | }; | 270 | }; |
| 246 | 271 | ||
| 272 | /* PFUZE200 */ | ||
| 273 | static struct of_regulator_match pfuze200_matches[] = { | ||
| 274 | |||
| 275 | { .name = "sw1ab", }, | ||
| 276 | { .name = "sw2", }, | ||
| 277 | { .name = "sw3a", }, | ||
| 278 | { .name = "sw3b", }, | ||
| 279 | { .name = "swbst", }, | ||
| 280 | { .name = "vsnvs", }, | ||
| 281 | { .name = "vrefddr", }, | ||
| 282 | { .name = "vgen1", }, | ||
| 283 | { .name = "vgen2", }, | ||
| 284 | { .name = "vgen3", }, | ||
| 285 | { .name = "vgen4", }, | ||
| 286 | { .name = "vgen5", }, | ||
| 287 | { .name = "vgen6", }, | ||
| 288 | }; | ||
| 289 | |||
| 290 | static struct of_regulator_match *pfuze_matches; | ||
| 291 | |||
| 247 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 292 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
| 248 | { | 293 | { |
| 249 | struct device *dev = chip->dev; | 294 | struct device *dev = chip->dev; |
| 250 | struct device_node *np, *parent; | 295 | struct device_node *np, *parent; |
| 251 | int ret; | 296 | int ret; |
| 252 | 297 | ||
| 253 | np = of_node_get(dev->parent->of_node); | 298 | np = of_node_get(dev->of_node); |
| 254 | if (!np) | 299 | if (!np) |
| 255 | return 0; | 300 | return -EINVAL; |
| 256 | 301 | ||
| 257 | parent = of_find_node_by_name(np, "regulators"); | 302 | parent = of_get_child_by_name(np, "regulators"); |
| 258 | if (!parent) { | 303 | if (!parent) { |
| 259 | dev_err(dev, "regulators node not found\n"); | 304 | dev_err(dev, "regulators node not found\n"); |
| 260 | return -EINVAL; | 305 | return -EINVAL; |
| 261 | } | 306 | } |
| 262 | 307 | ||
| 263 | ret = of_regulator_match(dev, parent, pfuze100_matches, | 308 | switch (chip->chip_id) { |
| 264 | ARRAY_SIZE(pfuze100_matches)); | 309 | case PFUZE200: |
| 310 | pfuze_matches = pfuze200_matches; | ||
| 311 | ret = of_regulator_match(dev, parent, pfuze200_matches, | ||
| 312 | ARRAY_SIZE(pfuze200_matches)); | ||
| 313 | break; | ||
| 314 | |||
| 315 | case PFUZE100: | ||
| 316 | default: | ||
| 317 | pfuze_matches = pfuze100_matches; | ||
| 318 | ret = of_regulator_match(dev, parent, pfuze100_matches, | ||
| 319 | ARRAY_SIZE(pfuze100_matches)); | ||
| 320 | break; | ||
| 321 | } | ||
| 265 | 322 | ||
| 266 | of_node_put(parent); | 323 | of_node_put(parent); |
| 267 | if (ret < 0) { | 324 | if (ret < 0) { |
| @@ -275,12 +332,12 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | |||
| 275 | 332 | ||
| 276 | static inline struct regulator_init_data *match_init_data(int index) | 333 | static inline struct regulator_init_data *match_init_data(int index) |
| 277 | { | 334 | { |
| 278 | return pfuze100_matches[index].init_data; | 335 | return pfuze_matches[index].init_data; |
| 279 | } | 336 | } |
| 280 | 337 | ||
| 281 | static inline struct device_node *match_of_node(int index) | 338 | static inline struct device_node *match_of_node(int index) |
| 282 | { | 339 | { |
| 283 | return pfuze100_matches[index].of_node; | 340 | return pfuze_matches[index].of_node; |
| 284 | } | 341 | } |
| 285 | #else | 342 | #else |
| 286 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 343 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
| @@ -308,16 +365,14 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip) | |||
| 308 | if (ret) | 365 | if (ret) |
| 309 | return ret; | 366 | return ret; |
| 310 | 367 | ||
| 311 | switch (value & 0x0f) { | 368 | if (((value & 0x0f) == 0x8) && (pfuze_chip->chip_id == PFUZE100)) { |
| 312 | /* | 369 | /* |
| 313 | * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 | 370 | * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 |
| 314 | * as ID=8 | 371 | * as ID=8 in PFUZE100 |
| 315 | */ | 372 | */ |
| 316 | case 0x8: | ||
| 317 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); | 373 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); |
| 318 | case 0x0: | 374 | } else if ((value & 0x0f) != pfuze_chip->chip_id) { |
| 319 | break; | 375 | /* device id NOT match with your setting */ |
| 320 | default: | ||
| 321 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); | 376 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); |
| 322 | return -ENODEV; | 377 | return -ENODEV; |
| 323 | } | 378 | } |
| @@ -353,17 +408,31 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 353 | dev_get_platdata(&client->dev); | 408 | dev_get_platdata(&client->dev); |
| 354 | struct regulator_config config = { }; | 409 | struct regulator_config config = { }; |
| 355 | int i, ret; | 410 | int i, ret; |
| 411 | const struct of_device_id *match; | ||
| 412 | u32 regulator_num; | ||
| 413 | u32 sw_check_start, sw_check_end; | ||
| 356 | 414 | ||
| 357 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), | 415 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), |
| 358 | GFP_KERNEL); | 416 | GFP_KERNEL); |
| 359 | if (!pfuze_chip) | 417 | if (!pfuze_chip) |
| 360 | return -ENOMEM; | 418 | return -ENOMEM; |
| 361 | 419 | ||
| 362 | i2c_set_clientdata(client, pfuze_chip); | 420 | if (client->dev.of_node) { |
| 363 | 421 | match = of_match_device(of_match_ptr(pfuze_dt_ids), | |
| 364 | memcpy(pfuze_chip->regulator_descs, pfuze100_regulators, | 422 | &client->dev); |
| 365 | sizeof(pfuze_chip->regulator_descs)); | 423 | if (!match) { |
| 424 | dev_err(&client->dev, "Error: No device match found\n"); | ||
| 425 | return -ENODEV; | ||
| 426 | } | ||
| 427 | pfuze_chip->chip_id = (int)(long)match->data; | ||
| 428 | } else if (id) { | ||
| 429 | pfuze_chip->chip_id = id->driver_data; | ||
| 430 | } else { | ||
| 431 | dev_err(&client->dev, "No dts match or id table match found\n"); | ||
| 432 | return -ENODEV; | ||
| 433 | } | ||
| 366 | 434 | ||
| 435 | i2c_set_clientdata(client, pfuze_chip); | ||
| 367 | pfuze_chip->dev = &client->dev; | 436 | pfuze_chip->dev = &client->dev; |
| 368 | 437 | ||
| 369 | pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config); | 438 | pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config); |
| @@ -380,11 +449,34 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 380 | return ret; | 449 | return ret; |
| 381 | } | 450 | } |
| 382 | 451 | ||
| 452 | /* use the right regulators after identify the right device */ | ||
| 453 | switch (pfuze_chip->chip_id) { | ||
| 454 | case PFUZE200: | ||
| 455 | pfuze_regulators = pfuze200_regulators; | ||
| 456 | regulator_num = ARRAY_SIZE(pfuze200_regulators); | ||
| 457 | sw_check_start = PFUZE200_SW2; | ||
| 458 | sw_check_end = PFUZE200_SW3B; | ||
| 459 | break; | ||
| 460 | |||
| 461 | case PFUZE100: | ||
| 462 | default: | ||
| 463 | pfuze_regulators = pfuze100_regulators; | ||
| 464 | regulator_num = ARRAY_SIZE(pfuze100_regulators); | ||
| 465 | sw_check_start = PFUZE100_SW2; | ||
| 466 | sw_check_end = PFUZE100_SW4; | ||
| 467 | break; | ||
| 468 | } | ||
| 469 | dev_info(&client->dev, "pfuze%s found.\n", | ||
| 470 | (pfuze_chip->chip_id == PFUZE100) ? "100" : "200"); | ||
| 471 | |||
| 472 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, | ||
| 473 | sizeof(pfuze_chip->regulator_descs)); | ||
| 474 | |||
| 383 | ret = pfuze_parse_regulators_dt(pfuze_chip); | 475 | ret = pfuze_parse_regulators_dt(pfuze_chip); |
| 384 | if (ret) | 476 | if (ret) |
| 385 | return ret; | 477 | return ret; |
| 386 | 478 | ||
| 387 | for (i = 0; i < PFUZE100_MAX_REGULATOR; i++) { | 479 | for (i = 0; i < regulator_num; i++) { |
| 388 | struct regulator_init_data *init_data; | 480 | struct regulator_init_data *init_data; |
| 389 | struct regulator_desc *desc; | 481 | struct regulator_desc *desc; |
| 390 | int val; | 482 | int val; |
| @@ -397,7 +489,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 397 | init_data = match_init_data(i); | 489 | init_data = match_init_data(i); |
| 398 | 490 | ||
| 399 | /* SW2~SW4 high bit check and modify the voltage value table */ | 491 | /* SW2~SW4 high bit check and modify the voltage value table */ |
| 400 | if (i > PFUZE100_SW1C && i < PFUZE100_SWBST) { | 492 | if (i >= sw_check_start && i <= sw_check_end) { |
| 401 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); | 493 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); |
| 402 | if (val & 0x40) { | 494 | if (val & 0x40) { |
| 403 | desc->min_uV = 800000; | 495 | desc->min_uV = 800000; |
| @@ -415,7 +507,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
| 415 | devm_regulator_register(&client->dev, desc, &config); | 507 | devm_regulator_register(&client->dev, desc, &config); |
| 416 | if (IS_ERR(pfuze_chip->regulators[i])) { | 508 | if (IS_ERR(pfuze_chip->regulators[i])) { |
| 417 | dev_err(&client->dev, "register regulator%s failed\n", | 509 | dev_err(&client->dev, "register regulator%s failed\n", |
| 418 | pfuze100_regulators[i].desc.name); | 510 | pfuze_regulators[i].desc.name); |
| 419 | return PTR_ERR(pfuze_chip->regulators[i]); | 511 | return PTR_ERR(pfuze_chip->regulators[i]); |
| 420 | } | 512 | } |
| 421 | } | 513 | } |
| @@ -435,6 +527,6 @@ static struct i2c_driver pfuze_driver = { | |||
| 435 | module_i2c_driver(pfuze_driver); | 527 | module_i2c_driver(pfuze_driver); |
| 436 | 528 | ||
| 437 | MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); | 529 | MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); |
| 438 | MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100 PMIC"); | 530 | MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/PFUZE200 PMIC"); |
| 439 | MODULE_LICENSE("GPL v2"); | 531 | MODULE_LICENSE("GPL v2"); |
| 440 | MODULE_ALIAS("i2c:pfuze100-regulator"); | 532 | MODULE_ALIAS("i2c:pfuze100-regulator"); |
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index b58affb33143..4c414ae109ae 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c | |||
| @@ -119,7 +119,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 119 | { | 119 | { |
| 120 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | 120 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); |
| 121 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); | 121 | struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); |
| 122 | struct regulator_init_data *reg_data; | ||
| 123 | struct regulator_config config = { }; | 122 | struct regulator_config config = { }; |
| 124 | struct rc5t583_regulator *reg = NULL; | 123 | struct rc5t583_regulator *reg = NULL; |
| 125 | struct rc5t583_regulator *regs; | 124 | struct rc5t583_regulator *regs; |
| @@ -135,19 +134,11 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 135 | 134 | ||
| 136 | regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * | 135 | regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * |
| 137 | sizeof(struct rc5t583_regulator), GFP_KERNEL); | 136 | sizeof(struct rc5t583_regulator), GFP_KERNEL); |
| 138 | if (!regs) { | 137 | if (!regs) |
| 139 | dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); | ||
| 140 | return -ENOMEM; | 138 | return -ENOMEM; |
| 141 | } | ||
| 142 | 139 | ||
| 143 | 140 | ||
| 144 | for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { | 141 | for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { |
| 145 | reg_data = pdata->reg_init_data[id]; | ||
| 146 | |||
| 147 | /* No need to register if there is no regulator data */ | ||
| 148 | if (!reg_data) | ||
| 149 | continue; | ||
| 150 | |||
| 151 | reg = ®s[id]; | 142 | reg = ®s[id]; |
| 152 | ri = &rc5t583_reg_info[id]; | 143 | ri = &rc5t583_reg_info[id]; |
| 153 | reg->reg_info = ri; | 144 | reg->reg_info = ri; |
| @@ -169,7 +160,7 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) | |||
| 169 | 160 | ||
| 170 | skip_ext_pwr_config: | 161 | skip_ext_pwr_config: |
| 171 | config.dev = &pdev->dev; | 162 | config.dev = &pdev->dev; |
| 172 | config.init_data = reg_data; | 163 | config.init_data = pdata->reg_init_data[id]; |
| 173 | config.driver_data = reg; | 164 | config.driver_data = reg; |
| 174 | config.regmap = rc5t583->regmap; | 165 | config.regmap = rc5t583->regmap; |
| 175 | 166 | ||
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c new file mode 100644 index 000000000000..808b3aa7a42c --- /dev/null +++ b/drivers/regulator/s2mpa01.c | |||
| @@ -0,0 +1,481 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Samsung Electronics Co., Ltd | ||
| 3 | * http://www.samsung.com | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/bug.h> | ||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/regmap.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/regulator/driver.h> | ||
| 21 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/regulator/of_regulator.h> | ||
| 23 | #include <linux/mfd/samsung/core.h> | ||
| 24 | #include <linux/mfd/samsung/s2mpa01.h> | ||
| 25 | |||
| 26 | #define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators) | ||
| 27 | |||
| 28 | struct s2mpa01_info { | ||
| 29 | int ramp_delay24; | ||
| 30 | int ramp_delay3; | ||
| 31 | int ramp_delay5; | ||
| 32 | int ramp_delay16; | ||
| 33 | int ramp_delay7; | ||
| 34 | int ramp_delay8910; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static int get_ramp_delay(int ramp_delay) | ||
| 38 | { | ||
| 39 | unsigned char cnt = 0; | ||
| 40 | |||
| 41 | ramp_delay /= 6250; | ||
| 42 | |||
| 43 | while (true) { | ||
| 44 | ramp_delay = ramp_delay >> 1; | ||
| 45 | if (ramp_delay == 0) | ||
| 46 | break; | ||
| 47 | cnt++; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (cnt > 3) | ||
| 51 | cnt = 3; | ||
| 52 | |||
| 53 | return cnt; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 57 | unsigned int old_selector, | ||
| 58 | unsigned int new_selector) | ||
| 59 | { | ||
| 60 | struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); | ||
| 61 | unsigned int ramp_delay = 0; | ||
| 62 | int old_volt, new_volt; | ||
| 63 | |||
| 64 | switch (rdev->desc->id) { | ||
| 65 | case S2MPA01_BUCK2: | ||
| 66 | case S2MPA01_BUCK4: | ||
| 67 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 68 | break; | ||
| 69 | case S2MPA01_BUCK3: | ||
| 70 | ramp_delay = s2mpa01->ramp_delay3; | ||
| 71 | break; | ||
| 72 | case S2MPA01_BUCK5: | ||
| 73 | ramp_delay = s2mpa01->ramp_delay5; | ||
| 74 | break; | ||
| 75 | case S2MPA01_BUCK1: | ||
| 76 | case S2MPA01_BUCK6: | ||
| 77 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 78 | break; | ||
| 79 | case S2MPA01_BUCK7: | ||
| 80 | ramp_delay = s2mpa01->ramp_delay7; | ||
| 81 | break; | ||
| 82 | case S2MPA01_BUCK8: | ||
| 83 | case S2MPA01_BUCK9: | ||
| 84 | case S2MPA01_BUCK10: | ||
| 85 | ramp_delay = s2mpa01->ramp_delay8910; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (ramp_delay == 0) | ||
| 90 | ramp_delay = rdev->desc->ramp_delay; | ||
| 91 | |||
| 92 | old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector); | ||
| 93 | new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector); | ||
| 94 | |||
| 95 | return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
| 99 | { | ||
| 100 | struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev); | ||
| 101 | unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2; | ||
| 102 | unsigned int ramp_enable = 1, enable_shift = 0; | ||
| 103 | int ret; | ||
| 104 | |||
| 105 | switch (rdev->desc->id) { | ||
| 106 | case S2MPA01_BUCK1: | ||
| 107 | enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT; | ||
| 108 | if (!ramp_delay) { | ||
| 109 | ramp_enable = 0; | ||
| 110 | break; | ||
| 111 | } | ||
| 112 | |||
| 113 | if (ramp_delay > s2mpa01->ramp_delay16) | ||
| 114 | s2mpa01->ramp_delay16 = ramp_delay; | ||
| 115 | else | ||
| 116 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 117 | |||
| 118 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; | ||
| 119 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 120 | break; | ||
| 121 | case S2MPA01_BUCK2: | ||
| 122 | enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT; | ||
| 123 | if (!ramp_delay) { | ||
| 124 | ramp_enable = 0; | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (ramp_delay > s2mpa01->ramp_delay24) | ||
| 129 | s2mpa01->ramp_delay24 = ramp_delay; | ||
| 130 | else | ||
| 131 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 132 | |||
| 133 | ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; | ||
| 134 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 135 | break; | ||
| 136 | case S2MPA01_BUCK3: | ||
| 137 | enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT; | ||
| 138 | if (!ramp_delay) { | ||
| 139 | ramp_enable = 0; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | |||
| 143 | s2mpa01->ramp_delay3 = ramp_delay; | ||
| 144 | ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT; | ||
| 145 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 146 | break; | ||
| 147 | case S2MPA01_BUCK4: | ||
| 148 | enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT; | ||
| 149 | if (!ramp_delay) { | ||
| 150 | ramp_enable = 0; | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | |||
| 154 | if (ramp_delay > s2mpa01->ramp_delay24) | ||
| 155 | s2mpa01->ramp_delay24 = ramp_delay; | ||
| 156 | else | ||
| 157 | ramp_delay = s2mpa01->ramp_delay24; | ||
| 158 | |||
| 159 | ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT; | ||
| 160 | ramp_reg = S2MPA01_REG_RAMP1; | ||
| 161 | break; | ||
| 162 | case S2MPA01_BUCK5: | ||
| 163 | s2mpa01->ramp_delay5 = ramp_delay; | ||
| 164 | ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT; | ||
| 165 | break; | ||
| 166 | case S2MPA01_BUCK6: | ||
| 167 | if (ramp_delay > s2mpa01->ramp_delay16) | ||
| 168 | s2mpa01->ramp_delay16 = ramp_delay; | ||
| 169 | else | ||
| 170 | ramp_delay = s2mpa01->ramp_delay16; | ||
| 171 | |||
| 172 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; | ||
| 173 | break; | ||
| 174 | case S2MPA01_BUCK7: | ||
| 175 | s2mpa01->ramp_delay7 = ramp_delay; | ||
| 176 | ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT; | ||
| 177 | break; | ||
| 178 | case S2MPA01_BUCK8: | ||
| 179 | case S2MPA01_BUCK9: | ||
| 180 | case S2MPA01_BUCK10: | ||
| 181 | if (ramp_delay > s2mpa01->ramp_delay8910) | ||
| 182 | s2mpa01->ramp_delay8910 = ramp_delay; | ||
| 183 | else | ||
| 184 | ramp_delay = s2mpa01->ramp_delay8910; | ||
| 185 | |||
| 186 | ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT; | ||
| 187 | break; | ||
| 188 | default: | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | if (!ramp_enable) | ||
| 193 | goto ramp_disable; | ||
| 194 | |||
| 195 | if (enable_shift) { | ||
| 196 | ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, | ||
| 197 | 1 << enable_shift, 1 << enable_shift); | ||
| 198 | if (ret) { | ||
| 199 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | ramp_val = get_ramp_delay(ramp_delay); | ||
| 205 | |||
| 206 | return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift, | ||
| 207 | ramp_val << ramp_shift); | ||
| 208 | |||
| 209 | ramp_disable: | ||
| 210 | return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, | ||
| 211 | 1 << enable_shift, 0); | ||
| 212 | } | ||
| 213 | |||
| 214 | static struct regulator_ops s2mpa01_ldo_ops = { | ||
| 215 | .list_voltage = regulator_list_voltage_linear, | ||
| 216 | .map_voltage = regulator_map_voltage_linear, | ||
| 217 | .is_enabled = regulator_is_enabled_regmap, | ||
| 218 | .enable = regulator_enable_regmap, | ||
| 219 | .disable = regulator_disable_regmap, | ||
| 220 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 221 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 222 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 223 | }; | ||
| 224 | |||
| 225 | static struct regulator_ops s2mpa01_buck_ops = { | ||
| 226 | .list_voltage = regulator_list_voltage_linear, | ||
| 227 | .map_voltage = regulator_map_voltage_linear, | ||
| 228 | .is_enabled = regulator_is_enabled_regmap, | ||
| 229 | .enable = regulator_enable_regmap, | ||
| 230 | .disable = regulator_disable_regmap, | ||
| 231 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 232 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 233 | .set_voltage_time_sel = s2mpa01_regulator_set_voltage_time_sel, | ||
| 234 | .set_ramp_delay = s2mpa01_set_ramp_delay, | ||
| 235 | }; | ||
| 236 | |||
| 237 | #define regulator_desc_ldo1(num) { \ | ||
| 238 | .name = "LDO"#num, \ | ||
| 239 | .id = S2MPA01_LDO##num, \ | ||
| 240 | .ops = &s2mpa01_ldo_ops, \ | ||
| 241 | .type = REGULATOR_VOLTAGE, \ | ||
| 242 | .owner = THIS_MODULE, \ | ||
| 243 | .min_uV = S2MPA01_LDO_MIN, \ | ||
| 244 | .uV_step = S2MPA01_LDO_STEP1, \ | ||
| 245 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | ||
| 246 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 247 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | ||
| 248 | .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 249 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 250 | } | ||
| 251 | #define regulator_desc_ldo2(num) { \ | ||
| 252 | .name = "LDO"#num, \ | ||
| 253 | .id = S2MPA01_LDO##num, \ | ||
| 254 | .ops = &s2mpa01_ldo_ops, \ | ||
| 255 | .type = REGULATOR_VOLTAGE, \ | ||
| 256 | .owner = THIS_MODULE, \ | ||
| 257 | .min_uV = S2MPA01_LDO_MIN, \ | ||
| 258 | .uV_step = S2MPA01_LDO_STEP2, \ | ||
| 259 | .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ | ||
| 260 | .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 261 | .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ | ||
| 262 | .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ | ||
| 263 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 264 | } | ||
| 265 | |||
| 266 | #define regulator_desc_buck1_4(num) { \ | ||
| 267 | .name = "BUCK"#num, \ | ||
| 268 | .id = S2MPA01_BUCK##num, \ | ||
| 269 | .ops = &s2mpa01_buck_ops, \ | ||
| 270 | .type = REGULATOR_VOLTAGE, \ | ||
| 271 | .owner = THIS_MODULE, \ | ||
| 272 | .min_uV = S2MPA01_BUCK_MIN1, \ | ||
| 273 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 274 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 275 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 276 | .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 277 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 278 | .enable_reg = S2MPA01_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 279 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 280 | } | ||
| 281 | |||
| 282 | #define regulator_desc_buck5 { \ | ||
| 283 | .name = "BUCK5", \ | ||
| 284 | .id = S2MPA01_BUCK5, \ | ||
| 285 | .ops = &s2mpa01_buck_ops, \ | ||
| 286 | .type = REGULATOR_VOLTAGE, \ | ||
| 287 | .owner = THIS_MODULE, \ | ||
| 288 | .min_uV = S2MPA01_BUCK_MIN2, \ | ||
| 289 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 290 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 291 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 292 | .vsel_reg = S2MPA01_REG_B5CTRL2, \ | ||
| 293 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 294 | .enable_reg = S2MPA01_REG_B5CTRL1, \ | ||
| 295 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 296 | } | ||
| 297 | |||
| 298 | #define regulator_desc_buck6_7(num) { \ | ||
| 299 | .name = "BUCK"#num, \ | ||
| 300 | .id = S2MPA01_BUCK##num, \ | ||
| 301 | .ops = &s2mpa01_buck_ops, \ | ||
| 302 | .type = REGULATOR_VOLTAGE, \ | ||
| 303 | .owner = THIS_MODULE, \ | ||
| 304 | .min_uV = S2MPA01_BUCK_MIN1, \ | ||
| 305 | .uV_step = S2MPA01_BUCK_STEP1, \ | ||
| 306 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 307 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 308 | .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ | ||
| 309 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 310 | .enable_reg = S2MPA01_REG_B6CTRL1 + (num - 6) * 2, \ | ||
| 311 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 312 | } | ||
| 313 | |||
| 314 | #define regulator_desc_buck8 { \ | ||
| 315 | .name = "BUCK8", \ | ||
| 316 | .id = S2MPA01_BUCK8, \ | ||
| 317 | .ops = &s2mpa01_buck_ops, \ | ||
| 318 | .type = REGULATOR_VOLTAGE, \ | ||
| 319 | .owner = THIS_MODULE, \ | ||
| 320 | .min_uV = S2MPA01_BUCK_MIN2, \ | ||
| 321 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 322 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 323 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 324 | .vsel_reg = S2MPA01_REG_B8CTRL2, \ | ||
| 325 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 326 | .enable_reg = S2MPA01_REG_B8CTRL1, \ | ||
| 327 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 328 | } | ||
| 329 | |||
| 330 | #define regulator_desc_buck9 { \ | ||
| 331 | .name = "BUCK9", \ | ||
| 332 | .id = S2MPA01_BUCK9, \ | ||
| 333 | .ops = &s2mpa01_buck_ops, \ | ||
| 334 | .type = REGULATOR_VOLTAGE, \ | ||
| 335 | .owner = THIS_MODULE, \ | ||
| 336 | .min_uV = S2MPA01_BUCK_MIN4, \ | ||
| 337 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 338 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 339 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 340 | .vsel_reg = S2MPA01_REG_B9CTRL2, \ | ||
| 341 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 342 | .enable_reg = S2MPA01_REG_B9CTRL1, \ | ||
| 343 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 344 | } | ||
| 345 | |||
| 346 | #define regulator_desc_buck10 { \ | ||
| 347 | .name = "BUCK10", \ | ||
| 348 | .id = S2MPA01_BUCK10, \ | ||
| 349 | .ops = &s2mpa01_buck_ops, \ | ||
| 350 | .type = REGULATOR_VOLTAGE, \ | ||
| 351 | .owner = THIS_MODULE, \ | ||
| 352 | .min_uV = S2MPA01_BUCK_MIN3, \ | ||
| 353 | .uV_step = S2MPA01_BUCK_STEP2, \ | ||
| 354 | .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ | ||
| 355 | .ramp_delay = S2MPA01_RAMP_DELAY, \ | ||
| 356 | .vsel_reg = S2MPA01_REG_B10CTRL2, \ | ||
| 357 | .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ | ||
| 358 | .enable_reg = S2MPA01_REG_B10CTRL1, \ | ||
| 359 | .enable_mask = S2MPA01_ENABLE_MASK \ | ||
| 360 | } | ||
| 361 | |||
| 362 | static struct regulator_desc regulators[] = { | ||
| 363 | regulator_desc_ldo2(1), | ||
| 364 | regulator_desc_ldo1(2), | ||
| 365 | regulator_desc_ldo1(3), | ||
| 366 | regulator_desc_ldo1(4), | ||
| 367 | regulator_desc_ldo1(5), | ||
| 368 | regulator_desc_ldo2(6), | ||
| 369 | regulator_desc_ldo1(7), | ||
| 370 | regulator_desc_ldo1(8), | ||
| 371 | regulator_desc_ldo1(9), | ||
| 372 | regulator_desc_ldo1(10), | ||
| 373 | regulator_desc_ldo2(11), | ||
| 374 | regulator_desc_ldo1(12), | ||
| 375 | regulator_desc_ldo1(13), | ||
| 376 | regulator_desc_ldo1(14), | ||
| 377 | regulator_desc_ldo1(15), | ||
| 378 | regulator_desc_ldo1(16), | ||
| 379 | regulator_desc_ldo1(17), | ||
| 380 | regulator_desc_ldo1(18), | ||
| 381 | regulator_desc_ldo1(19), | ||
| 382 | regulator_desc_ldo1(20), | ||
| 383 | regulator_desc_ldo1(21), | ||
| 384 | regulator_desc_ldo2(22), | ||
| 385 | regulator_desc_ldo2(23), | ||
| 386 | regulator_desc_ldo1(24), | ||
| 387 | regulator_desc_ldo1(25), | ||
| 388 | regulator_desc_ldo1(26), | ||
| 389 | regulator_desc_buck1_4(1), | ||
| 390 | regulator_desc_buck1_4(2), | ||
| 391 | regulator_desc_buck1_4(3), | ||
| 392 | regulator_desc_buck1_4(4), | ||
| 393 | regulator_desc_buck5, | ||
| 394 | regulator_desc_buck6_7(6), | ||
| 395 | regulator_desc_buck6_7(7), | ||
| 396 | regulator_desc_buck8, | ||
| 397 | regulator_desc_buck9, | ||
| 398 | regulator_desc_buck10, | ||
| 399 | }; | ||
| 400 | |||
| 401 | static int s2mpa01_pmic_probe(struct platform_device *pdev) | ||
| 402 | { | ||
| 403 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
| 404 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
| 405 | struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX]; | ||
| 406 | struct device_node *reg_np = NULL; | ||
| 407 | struct regulator_config config = { }; | ||
| 408 | struct s2mpa01_info *s2mpa01; | ||
| 409 | int i; | ||
| 410 | |||
| 411 | s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL); | ||
| 412 | if (!s2mpa01) | ||
| 413 | return -ENOMEM; | ||
| 414 | |||
| 415 | for (i = 0; i < S2MPA01_REGULATOR_CNT; i++) | ||
| 416 | rdata[i].name = regulators[i].name; | ||
| 417 | |||
| 418 | if (iodev->dev->of_node) { | ||
| 419 | reg_np = of_get_child_by_name(iodev->dev->of_node, | ||
| 420 | "regulators"); | ||
| 421 | if (!reg_np) { | ||
| 422 | dev_err(&pdev->dev, | ||
| 423 | "could not find regulators sub-node\n"); | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | |||
| 427 | of_regulator_match(&pdev->dev, reg_np, rdata, | ||
| 428 | S2MPA01_REGULATOR_MAX); | ||
| 429 | of_node_put(reg_np); | ||
| 430 | } | ||
| 431 | |||
| 432 | platform_set_drvdata(pdev, s2mpa01); | ||
| 433 | |||
| 434 | config.dev = &pdev->dev; | ||
| 435 | config.regmap = iodev->regmap_pmic; | ||
| 436 | config.driver_data = s2mpa01; | ||
| 437 | |||
| 438 | for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) { | ||
| 439 | struct regulator_dev *rdev; | ||
| 440 | if (pdata) | ||
| 441 | config.init_data = pdata->regulators[i].initdata; | ||
| 442 | else | ||
| 443 | config.init_data = rdata[i].init_data; | ||
| 444 | |||
| 445 | if (reg_np) | ||
| 446 | config.of_node = rdata[i].of_node; | ||
| 447 | |||
| 448 | rdev = devm_regulator_register(&pdev->dev, | ||
| 449 | ®ulators[i], &config); | ||
| 450 | if (IS_ERR(rdev)) { | ||
| 451 | dev_err(&pdev->dev, "regulator init failed for %d\n", | ||
| 452 | i); | ||
| 453 | return PTR_ERR(rdev); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static const struct platform_device_id s2mpa01_pmic_id[] = { | ||
| 461 | { "s2mpa01-pmic", 0}, | ||
| 462 | { }, | ||
| 463 | }; | ||
| 464 | MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id); | ||
| 465 | |||
| 466 | static struct platform_driver s2mpa01_pmic_driver = { | ||
| 467 | .driver = { | ||
| 468 | .name = "s2mpa01-pmic", | ||
| 469 | .owner = THIS_MODULE, | ||
| 470 | }, | ||
| 471 | .probe = s2mpa01_pmic_probe, | ||
| 472 | .id_table = s2mpa01_pmic_id, | ||
| 473 | }; | ||
| 474 | |||
| 475 | module_platform_driver(s2mpa01_pmic_driver); | ||
| 476 | |||
| 477 | /* Module information */ | ||
| 478 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | ||
| 479 | MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>"); | ||
| 480 | MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver"); | ||
| 481 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d9e557990577..68fd54702edb 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
| @@ -1,13 +1,18 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * s2mps11.c | 2 | * s2mps11.c |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2012 Samsung Electronics Co., Ltd | 4 | * Copyright (c) 2012-2014 Samsung Electronics Co., Ltd |
| 5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| 8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
| 10 | * option) any later version. | 10 | * option) any later version. |
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 11 | * | 16 | * |
| 12 | */ | 17 | */ |
| 13 | 18 | ||
| @@ -24,18 +29,21 @@ | |||
| 24 | #include <linux/regulator/of_regulator.h> | 29 | #include <linux/regulator/of_regulator.h> |
| 25 | #include <linux/mfd/samsung/core.h> | 30 | #include <linux/mfd/samsung/core.h> |
| 26 | #include <linux/mfd/samsung/s2mps11.h> | 31 | #include <linux/mfd/samsung/s2mps11.h> |
| 27 | 32 | #include <linux/mfd/samsung/s2mps14.h> | |
| 28 | #define S2MPS11_REGULATOR_CNT ARRAY_SIZE(regulators) | ||
| 29 | 33 | ||
| 30 | struct s2mps11_info { | 34 | struct s2mps11_info { |
| 31 | struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX]; | 35 | unsigned int rdev_num; |
| 32 | |||
| 33 | int ramp_delay2; | 36 | int ramp_delay2; |
| 34 | int ramp_delay34; | 37 | int ramp_delay34; |
| 35 | int ramp_delay5; | 38 | int ramp_delay5; |
| 36 | int ramp_delay16; | 39 | int ramp_delay16; |
| 37 | int ramp_delay7810; | 40 | int ramp_delay7810; |
| 38 | int ramp_delay9; | 41 | int ramp_delay9; |
| 42 | /* | ||
| 43 | * One bit for each S2MPS14 regulator whether the suspend mode | ||
| 44 | * was enabled. | ||
| 45 | */ | ||
| 46 | unsigned int s2mps14_suspend_state:30; | ||
| 39 | }; | 47 | }; |
| 40 | 48 | ||
| 41 | static int get_ramp_delay(int ramp_delay) | 49 | static int get_ramp_delay(int ramp_delay) |
| @@ -65,7 +73,7 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | |||
| 65 | unsigned int ramp_delay = 0; | 73 | unsigned int ramp_delay = 0; |
| 66 | int old_volt, new_volt; | 74 | int old_volt, new_volt; |
| 67 | 75 | ||
| 68 | switch (rdev->desc->id) { | 76 | switch (rdev_get_id(rdev)) { |
| 69 | case S2MPS11_BUCK2: | 77 | case S2MPS11_BUCK2: |
| 70 | ramp_delay = s2mps11->ramp_delay2; | 78 | ramp_delay = s2mps11->ramp_delay2; |
| 71 | break; | 79 | break; |
| @@ -105,7 +113,7 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
| 105 | unsigned int ramp_enable = 1, enable_shift = 0; | 113 | unsigned int ramp_enable = 1, enable_shift = 0; |
| 106 | int ret; | 114 | int ret; |
| 107 | 115 | ||
| 108 | switch (rdev->desc->id) { | 116 | switch (rdev_get_id(rdev)) { |
| 109 | case S2MPS11_BUCK1: | 117 | case S2MPS11_BUCK1: |
| 110 | if (ramp_delay > s2mps11->ramp_delay16) | 118 | if (ramp_delay > s2mps11->ramp_delay16) |
| 111 | s2mps11->ramp_delay16 = ramp_delay; | 119 | s2mps11->ramp_delay16 = ramp_delay; |
| @@ -236,7 +244,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 236 | .set_ramp_delay = s2mps11_set_ramp_delay, | 244 | .set_ramp_delay = s2mps11_set_ramp_delay, |
| 237 | }; | 245 | }; |
| 238 | 246 | ||
| 239 | #define regulator_desc_ldo1(num) { \ | 247 | #define regulator_desc_s2mps11_ldo1(num) { \ |
| 240 | .name = "LDO"#num, \ | 248 | .name = "LDO"#num, \ |
| 241 | .id = S2MPS11_LDO##num, \ | 249 | .id = S2MPS11_LDO##num, \ |
| 242 | .ops = &s2mps11_ldo_ops, \ | 250 | .ops = &s2mps11_ldo_ops, \ |
| @@ -250,7 +258,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 250 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ | 258 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ |
| 251 | .enable_mask = S2MPS11_ENABLE_MASK \ | 259 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 252 | } | 260 | } |
| 253 | #define regulator_desc_ldo2(num) { \ | 261 | #define regulator_desc_s2mps11_ldo2(num) { \ |
| 254 | .name = "LDO"#num, \ | 262 | .name = "LDO"#num, \ |
| 255 | .id = S2MPS11_LDO##num, \ | 263 | .id = S2MPS11_LDO##num, \ |
| 256 | .ops = &s2mps11_ldo_ops, \ | 264 | .ops = &s2mps11_ldo_ops, \ |
| @@ -265,7 +273,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 265 | .enable_mask = S2MPS11_ENABLE_MASK \ | 273 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 266 | } | 274 | } |
| 267 | 275 | ||
| 268 | #define regulator_desc_buck1_4(num) { \ | 276 | #define regulator_desc_s2mps11_buck1_4(num) { \ |
| 269 | .name = "BUCK"#num, \ | 277 | .name = "BUCK"#num, \ |
| 270 | .id = S2MPS11_BUCK##num, \ | 278 | .id = S2MPS11_BUCK##num, \ |
| 271 | .ops = &s2mps11_buck_ops, \ | 279 | .ops = &s2mps11_buck_ops, \ |
| @@ -281,7 +289,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 281 | .enable_mask = S2MPS11_ENABLE_MASK \ | 289 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 282 | } | 290 | } |
| 283 | 291 | ||
| 284 | #define regulator_desc_buck5 { \ | 292 | #define regulator_desc_s2mps11_buck5 { \ |
| 285 | .name = "BUCK5", \ | 293 | .name = "BUCK5", \ |
| 286 | .id = S2MPS11_BUCK5, \ | 294 | .id = S2MPS11_BUCK5, \ |
| 287 | .ops = &s2mps11_buck_ops, \ | 295 | .ops = &s2mps11_buck_ops, \ |
| @@ -297,7 +305,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 297 | .enable_mask = S2MPS11_ENABLE_MASK \ | 305 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | #define regulator_desc_buck6_8(num) { \ | 308 | #define regulator_desc_s2mps11_buck6_8(num) { \ |
| 301 | .name = "BUCK"#num, \ | 309 | .name = "BUCK"#num, \ |
| 302 | .id = S2MPS11_BUCK##num, \ | 310 | .id = S2MPS11_BUCK##num, \ |
| 303 | .ops = &s2mps11_buck_ops, \ | 311 | .ops = &s2mps11_buck_ops, \ |
| @@ -313,7 +321,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 313 | .enable_mask = S2MPS11_ENABLE_MASK \ | 321 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 314 | } | 322 | } |
| 315 | 323 | ||
| 316 | #define regulator_desc_buck9 { \ | 324 | #define regulator_desc_s2mps11_buck9 { \ |
| 317 | .name = "BUCK9", \ | 325 | .name = "BUCK9", \ |
| 318 | .id = S2MPS11_BUCK9, \ | 326 | .id = S2MPS11_BUCK9, \ |
| 319 | .ops = &s2mps11_buck_ops, \ | 327 | .ops = &s2mps11_buck_ops, \ |
| @@ -329,7 +337,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 329 | .enable_mask = S2MPS11_ENABLE_MASK \ | 337 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 330 | } | 338 | } |
| 331 | 339 | ||
| 332 | #define regulator_desc_buck10 { \ | 340 | #define regulator_desc_s2mps11_buck10 { \ |
| 333 | .name = "BUCK10", \ | 341 | .name = "BUCK10", \ |
| 334 | .id = S2MPS11_BUCK10, \ | 342 | .id = S2MPS11_BUCK10, \ |
| 335 | .ops = &s2mps11_buck_ops, \ | 343 | .ops = &s2mps11_buck_ops, \ |
| @@ -345,72 +353,252 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
| 345 | .enable_mask = S2MPS11_ENABLE_MASK \ | 353 | .enable_mask = S2MPS11_ENABLE_MASK \ |
| 346 | } | 354 | } |
| 347 | 355 | ||
| 348 | static struct regulator_desc regulators[] = { | 356 | static const struct regulator_desc s2mps11_regulators[] = { |
| 349 | regulator_desc_ldo2(1), | 357 | regulator_desc_s2mps11_ldo2(1), |
| 350 | regulator_desc_ldo1(2), | 358 | regulator_desc_s2mps11_ldo1(2), |
| 351 | regulator_desc_ldo1(3), | 359 | regulator_desc_s2mps11_ldo1(3), |
| 352 | regulator_desc_ldo1(4), | 360 | regulator_desc_s2mps11_ldo1(4), |
| 353 | regulator_desc_ldo1(5), | 361 | regulator_desc_s2mps11_ldo1(5), |
| 354 | regulator_desc_ldo2(6), | 362 | regulator_desc_s2mps11_ldo2(6), |
| 355 | regulator_desc_ldo1(7), | 363 | regulator_desc_s2mps11_ldo1(7), |
| 356 | regulator_desc_ldo1(8), | 364 | regulator_desc_s2mps11_ldo1(8), |
| 357 | regulator_desc_ldo1(9), | 365 | regulator_desc_s2mps11_ldo1(9), |
| 358 | regulator_desc_ldo1(10), | 366 | regulator_desc_s2mps11_ldo1(10), |
| 359 | regulator_desc_ldo2(11), | 367 | regulator_desc_s2mps11_ldo2(11), |
| 360 | regulator_desc_ldo1(12), | 368 | regulator_desc_s2mps11_ldo1(12), |
| 361 | regulator_desc_ldo1(13), | 369 | regulator_desc_s2mps11_ldo1(13), |
| 362 | regulator_desc_ldo1(14), | 370 | regulator_desc_s2mps11_ldo1(14), |
| 363 | regulator_desc_ldo1(15), | 371 | regulator_desc_s2mps11_ldo1(15), |
| 364 | regulator_desc_ldo1(16), | 372 | regulator_desc_s2mps11_ldo1(16), |
| 365 | regulator_desc_ldo1(17), | 373 | regulator_desc_s2mps11_ldo1(17), |
| 366 | regulator_desc_ldo1(18), | 374 | regulator_desc_s2mps11_ldo1(18), |
| 367 | regulator_desc_ldo1(19), | 375 | regulator_desc_s2mps11_ldo1(19), |
| 368 | regulator_desc_ldo1(20), | 376 | regulator_desc_s2mps11_ldo1(20), |
| 369 | regulator_desc_ldo1(21), | 377 | regulator_desc_s2mps11_ldo1(21), |
| 370 | regulator_desc_ldo2(22), | 378 | regulator_desc_s2mps11_ldo2(22), |
| 371 | regulator_desc_ldo2(23), | 379 | regulator_desc_s2mps11_ldo2(23), |
| 372 | regulator_desc_ldo1(24), | 380 | regulator_desc_s2mps11_ldo1(24), |
| 373 | regulator_desc_ldo1(25), | 381 | regulator_desc_s2mps11_ldo1(25), |
| 374 | regulator_desc_ldo1(26), | 382 | regulator_desc_s2mps11_ldo1(26), |
| 375 | regulator_desc_ldo2(27), | 383 | regulator_desc_s2mps11_ldo2(27), |
| 376 | regulator_desc_ldo1(28), | 384 | regulator_desc_s2mps11_ldo1(28), |
| 377 | regulator_desc_ldo1(29), | 385 | regulator_desc_s2mps11_ldo1(29), |
| 378 | regulator_desc_ldo1(30), | 386 | regulator_desc_s2mps11_ldo1(30), |
| 379 | regulator_desc_ldo1(31), | 387 | regulator_desc_s2mps11_ldo1(31), |
| 380 | regulator_desc_ldo1(32), | 388 | regulator_desc_s2mps11_ldo1(32), |
| 381 | regulator_desc_ldo1(33), | 389 | regulator_desc_s2mps11_ldo1(33), |
| 382 | regulator_desc_ldo1(34), | 390 | regulator_desc_s2mps11_ldo1(34), |
| 383 | regulator_desc_ldo1(35), | 391 | regulator_desc_s2mps11_ldo1(35), |
| 384 | regulator_desc_ldo1(36), | 392 | regulator_desc_s2mps11_ldo1(36), |
| 385 | regulator_desc_ldo1(37), | 393 | regulator_desc_s2mps11_ldo1(37), |
| 386 | regulator_desc_ldo1(38), | 394 | regulator_desc_s2mps11_ldo1(38), |
| 387 | regulator_desc_buck1_4(1), | 395 | regulator_desc_s2mps11_buck1_4(1), |
| 388 | regulator_desc_buck1_4(2), | 396 | regulator_desc_s2mps11_buck1_4(2), |
| 389 | regulator_desc_buck1_4(3), | 397 | regulator_desc_s2mps11_buck1_4(3), |
| 390 | regulator_desc_buck1_4(4), | 398 | regulator_desc_s2mps11_buck1_4(4), |
| 391 | regulator_desc_buck5, | 399 | regulator_desc_s2mps11_buck5, |
| 392 | regulator_desc_buck6_8(6), | 400 | regulator_desc_s2mps11_buck6_8(6), |
| 393 | regulator_desc_buck6_8(7), | 401 | regulator_desc_s2mps11_buck6_8(7), |
| 394 | regulator_desc_buck6_8(8), | 402 | regulator_desc_s2mps11_buck6_8(8), |
| 395 | regulator_desc_buck9, | 403 | regulator_desc_s2mps11_buck9, |
| 396 | regulator_desc_buck10, | 404 | regulator_desc_s2mps11_buck10, |
| 405 | }; | ||
| 406 | |||
| 407 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | ||
| 408 | { | ||
| 409 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 410 | unsigned int val; | ||
| 411 | |||
| 412 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | ||
| 413 | val = S2MPS14_ENABLE_SUSPEND; | ||
| 414 | else | ||
| 415 | val = rdev->desc->enable_mask; | ||
| 416 | |||
| 417 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 418 | rdev->desc->enable_mask, val); | ||
| 419 | } | ||
| 420 | |||
| 421 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | ||
| 422 | { | ||
| 423 | int ret; | ||
| 424 | unsigned int val; | ||
| 425 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 426 | |||
| 427 | /* LDO3 should be always on and does not support suspend mode */ | ||
| 428 | if (rdev_get_id(rdev) == S2MPS14_LDO3) | ||
| 429 | return 0; | ||
| 430 | |||
| 431 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | ||
| 432 | if (ret < 0) | ||
| 433 | return ret; | ||
| 434 | |||
| 435 | s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev)); | ||
| 436 | /* | ||
| 437 | * Don't enable suspend mode if regulator is already disabled because | ||
| 438 | * this would effectively for a short time turn on the regulator after | ||
| 439 | * resuming. | ||
| 440 | * However we still want to toggle the suspend_state bit for regulator | ||
| 441 | * in case if it got enabled before suspending the system. | ||
| 442 | */ | ||
| 443 | if (!(val & rdev->desc->enable_mask)) | ||
| 444 | return 0; | ||
| 445 | |||
| 446 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 447 | rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); | ||
| 448 | } | ||
| 449 | |||
| 450 | static struct regulator_ops s2mps14_reg_ops = { | ||
| 451 | .list_voltage = regulator_list_voltage_linear, | ||
| 452 | .map_voltage = regulator_map_voltage_linear, | ||
| 453 | .is_enabled = regulator_is_enabled_regmap, | ||
| 454 | .enable = s2mps14_regulator_enable, | ||
| 455 | .disable = regulator_disable_regmap, | ||
| 456 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 457 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 458 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 459 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
| 460 | }; | ||
| 461 | |||
| 462 | #define regulator_desc_s2mps14_ldo1(num) { \ | ||
| 463 | .name = "LDO"#num, \ | ||
| 464 | .id = S2MPS14_LDO##num, \ | ||
| 465 | .ops = &s2mps14_reg_ops, \ | ||
| 466 | .type = REGULATOR_VOLTAGE, \ | ||
| 467 | .owner = THIS_MODULE, \ | ||
| 468 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
| 469 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
| 470 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 471 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 472 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 473 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 474 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 475 | } | ||
| 476 | #define regulator_desc_s2mps14_ldo2(num) { \ | ||
| 477 | .name = "LDO"#num, \ | ||
| 478 | .id = S2MPS14_LDO##num, \ | ||
| 479 | .ops = &s2mps14_reg_ops, \ | ||
| 480 | .type = REGULATOR_VOLTAGE, \ | ||
| 481 | .owner = THIS_MODULE, \ | ||
| 482 | .min_uV = S2MPS14_LDO_MIN_1800MV, \ | ||
| 483 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
| 484 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 485 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 486 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 487 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 488 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 489 | } | ||
| 490 | #define regulator_desc_s2mps14_ldo3(num) { \ | ||
| 491 | .name = "LDO"#num, \ | ||
| 492 | .id = S2MPS14_LDO##num, \ | ||
| 493 | .ops = &s2mps14_reg_ops, \ | ||
| 494 | .type = REGULATOR_VOLTAGE, \ | ||
| 495 | .owner = THIS_MODULE, \ | ||
| 496 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
| 497 | .uV_step = S2MPS14_LDO_STEP_12_5MV, \ | ||
| 498 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
| 499 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 500 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
| 501 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
| 502 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 503 | } | ||
| 504 | #define regulator_desc_s2mps14_buck1235(num) { \ | ||
| 505 | .name = "BUCK"#num, \ | ||
| 506 | .id = S2MPS14_BUCK##num, \ | ||
| 507 | .ops = &s2mps14_reg_ops, \ | ||
| 508 | .type = REGULATOR_VOLTAGE, \ | ||
| 509 | .owner = THIS_MODULE, \ | ||
| 510 | .min_uV = S2MPS14_BUCK1235_MIN_600MV, \ | ||
| 511 | .uV_step = S2MPS14_BUCK1235_STEP_6_25MV, \ | ||
| 512 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
| 513 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ | ||
| 514 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
| 515 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 516 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
| 517 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 518 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 519 | } | ||
| 520 | #define regulator_desc_s2mps14_buck4(num) { \ | ||
| 521 | .name = "BUCK"#num, \ | ||
| 522 | .id = S2MPS14_BUCK##num, \ | ||
| 523 | .ops = &s2mps14_reg_ops, \ | ||
| 524 | .type = REGULATOR_VOLTAGE, \ | ||
| 525 | .owner = THIS_MODULE, \ | ||
| 526 | .min_uV = S2MPS14_BUCK4_MIN_1400MV, \ | ||
| 527 | .uV_step = S2MPS14_BUCK4_STEP_12_5MV, \ | ||
| 528 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
| 529 | .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ | ||
| 530 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
| 531 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
| 532 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
| 533 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
| 534 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
| 535 | } | ||
| 536 | |||
| 537 | static const struct regulator_desc s2mps14_regulators[] = { | ||
| 538 | regulator_desc_s2mps14_ldo3(1), | ||
| 539 | regulator_desc_s2mps14_ldo3(2), | ||
| 540 | regulator_desc_s2mps14_ldo1(3), | ||
| 541 | regulator_desc_s2mps14_ldo1(4), | ||
| 542 | regulator_desc_s2mps14_ldo3(5), | ||
| 543 | regulator_desc_s2mps14_ldo3(6), | ||
| 544 | regulator_desc_s2mps14_ldo1(7), | ||
| 545 | regulator_desc_s2mps14_ldo2(8), | ||
| 546 | regulator_desc_s2mps14_ldo3(9), | ||
| 547 | regulator_desc_s2mps14_ldo3(10), | ||
| 548 | regulator_desc_s2mps14_ldo1(11), | ||
| 549 | regulator_desc_s2mps14_ldo2(12), | ||
| 550 | regulator_desc_s2mps14_ldo2(13), | ||
| 551 | regulator_desc_s2mps14_ldo2(14), | ||
| 552 | regulator_desc_s2mps14_ldo2(15), | ||
| 553 | regulator_desc_s2mps14_ldo2(16), | ||
| 554 | regulator_desc_s2mps14_ldo2(17), | ||
| 555 | regulator_desc_s2mps14_ldo2(18), | ||
| 556 | regulator_desc_s2mps14_ldo1(19), | ||
| 557 | regulator_desc_s2mps14_ldo1(20), | ||
| 558 | regulator_desc_s2mps14_ldo1(21), | ||
| 559 | regulator_desc_s2mps14_ldo3(22), | ||
| 560 | regulator_desc_s2mps14_ldo1(23), | ||
| 561 | regulator_desc_s2mps14_ldo2(24), | ||
| 562 | regulator_desc_s2mps14_ldo2(25), | ||
| 563 | regulator_desc_s2mps14_buck1235(1), | ||
| 564 | regulator_desc_s2mps14_buck1235(2), | ||
| 565 | regulator_desc_s2mps14_buck1235(3), | ||
| 566 | regulator_desc_s2mps14_buck4(4), | ||
| 567 | regulator_desc_s2mps14_buck1235(5), | ||
| 397 | }; | 568 | }; |
| 398 | 569 | ||
| 399 | static int s2mps11_pmic_probe(struct platform_device *pdev) | 570 | static int s2mps11_pmic_probe(struct platform_device *pdev) |
| 400 | { | 571 | { |
| 401 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 572 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 402 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | 573 | struct sec_platform_data *pdata = iodev->pdata; |
| 403 | struct of_regulator_match rdata[S2MPS11_REGULATOR_MAX]; | 574 | struct of_regulator_match *rdata = NULL; |
| 404 | struct device_node *reg_np = NULL; | 575 | struct device_node *reg_np = NULL; |
| 405 | struct regulator_config config = { }; | 576 | struct regulator_config config = { }; |
| 406 | struct s2mps11_info *s2mps11; | 577 | struct s2mps11_info *s2mps11; |
| 407 | int i, ret; | 578 | int i, ret = 0; |
| 579 | const struct regulator_desc *regulators; | ||
| 580 | enum sec_device_type dev_type; | ||
| 408 | 581 | ||
| 409 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), | 582 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), |
| 410 | GFP_KERNEL); | 583 | GFP_KERNEL); |
| 411 | if (!s2mps11) | 584 | if (!s2mps11) |
| 412 | return -ENOMEM; | 585 | return -ENOMEM; |
| 413 | 586 | ||
| 587 | dev_type = platform_get_device_id(pdev)->driver_data; | ||
| 588 | switch (dev_type) { | ||
| 589 | case S2MPS11X: | ||
| 590 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); | ||
| 591 | regulators = s2mps11_regulators; | ||
| 592 | break; | ||
| 593 | case S2MPS14X: | ||
| 594 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); | ||
| 595 | regulators = s2mps14_regulators; | ||
| 596 | break; | ||
| 597 | default: | ||
| 598 | dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); | ||
| 599 | return -EINVAL; | ||
| 600 | }; | ||
| 601 | |||
| 414 | if (!iodev->dev->of_node) { | 602 | if (!iodev->dev->of_node) { |
| 415 | if (pdata) { | 603 | if (pdata) { |
| 416 | goto common_reg; | 604 | goto common_reg; |
| @@ -421,16 +609,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
| 421 | } | 609 | } |
| 422 | } | 610 | } |
| 423 | 611 | ||
| 424 | for (i = 0; i < S2MPS11_REGULATOR_CNT; i++) | 612 | rdata = kzalloc(sizeof(*rdata) * s2mps11->rdev_num, GFP_KERNEL); |
| 613 | if (!rdata) | ||
| 614 | return -ENOMEM; | ||
| 615 | |||
| 616 | for (i = 0; i < s2mps11->rdev_num; i++) | ||
| 425 | rdata[i].name = regulators[i].name; | 617 | rdata[i].name = regulators[i].name; |
| 426 | 618 | ||
| 427 | reg_np = of_find_node_by_name(iodev->dev->of_node, "regulators"); | 619 | reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); |
| 428 | if (!reg_np) { | 620 | if (!reg_np) { |
| 429 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 621 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
| 430 | return -EINVAL; | 622 | ret = -EINVAL; |
| 623 | goto out; | ||
| 431 | } | 624 | } |
| 432 | 625 | ||
| 433 | of_regulator_match(&pdev->dev, reg_np, rdata, S2MPS11_REGULATOR_MAX); | 626 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); |
| 627 | of_node_put(reg_np); | ||
| 434 | 628 | ||
| 435 | common_reg: | 629 | common_reg: |
| 436 | platform_set_drvdata(pdev, s2mps11); | 630 | platform_set_drvdata(pdev, s2mps11); |
| @@ -438,29 +632,36 @@ common_reg: | |||
| 438 | config.dev = &pdev->dev; | 632 | config.dev = &pdev->dev; |
| 439 | config.regmap = iodev->regmap_pmic; | 633 | config.regmap = iodev->regmap_pmic; |
| 440 | config.driver_data = s2mps11; | 634 | config.driver_data = s2mps11; |
| 441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { | 635 | for (i = 0; i < s2mps11->rdev_num; i++) { |
| 636 | struct regulator_dev *regulator; | ||
| 637 | |||
| 442 | if (!reg_np) { | 638 | if (!reg_np) { |
| 443 | config.init_data = pdata->regulators[i].initdata; | 639 | config.init_data = pdata->regulators[i].initdata; |
| 640 | config.of_node = pdata->regulators[i].reg_node; | ||
| 444 | } else { | 641 | } else { |
| 445 | config.init_data = rdata[i].init_data; | 642 | config.init_data = rdata[i].init_data; |
| 446 | config.of_node = rdata[i].of_node; | 643 | config.of_node = rdata[i].of_node; |
| 447 | } | 644 | } |
| 448 | 645 | ||
| 449 | s2mps11->rdev[i] = devm_regulator_register(&pdev->dev, | 646 | regulator = devm_regulator_register(&pdev->dev, |
| 450 | ®ulators[i], &config); | 647 | ®ulators[i], &config); |
| 451 | if (IS_ERR(s2mps11->rdev[i])) { | 648 | if (IS_ERR(regulator)) { |
| 452 | ret = PTR_ERR(s2mps11->rdev[i]); | 649 | ret = PTR_ERR(regulator); |
| 453 | dev_err(&pdev->dev, "regulator init failed for %d\n", | 650 | dev_err(&pdev->dev, "regulator init failed for %d\n", |
| 454 | i); | 651 | i); |
| 455 | return ret; | 652 | goto out; |
| 456 | } | 653 | } |
| 457 | } | 654 | } |
| 458 | 655 | ||
| 459 | return 0; | 656 | out: |
| 657 | kfree(rdata); | ||
| 658 | |||
| 659 | return ret; | ||
| 460 | } | 660 | } |
| 461 | 661 | ||
| 462 | static const struct platform_device_id s2mps11_pmic_id[] = { | 662 | static const struct platform_device_id s2mps11_pmic_id[] = { |
| 463 | { "s2mps11-pmic", 0}, | 663 | { "s2mps11-pmic", S2MPS11X}, |
| 664 | { "s2mps14-pmic", S2MPS14X}, | ||
| 464 | { }, | 665 | { }, |
| 465 | }; | 666 | }; |
| 466 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); | 667 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); |
| @@ -488,5 +689,5 @@ module_exit(s2mps11_pmic_exit); | |||
| 488 | 689 | ||
| 489 | /* Module information */ | 690 | /* Module information */ |
| 490 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | 691 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); |
| 491 | MODULE_DESCRIPTION("SAMSUNG S2MPS11 Regulator Driver"); | 692 | MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver"); |
| 492 | MODULE_LICENSE("GPL"); | 693 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index d7164bb75d3e..f05badabd69e 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
| @@ -11,11 +11,8 @@ | |||
| 11 | * | 11 | * |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/bug.h> | ||
| 15 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 16 | #include <linux/gpio.h> | ||
| 17 | #include <linux/of_gpio.h> | 15 | #include <linux/of_gpio.h> |
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 20 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 21 | #include <linux/regulator/driver.h> | 18 | #include <linux/regulator/driver.h> |
| @@ -170,12 +167,11 @@ static unsigned int s5m8767_opmode_reg[][4] = { | |||
| 170 | {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ | 167 | {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ |
| 171 | }; | 168 | }; |
| 172 | 169 | ||
| 173 | static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, | 170 | static int s5m8767_get_register(struct s5m8767_info *s5m8767, int reg_id, |
| 174 | int *enable_ctrl) | 171 | int *reg, int *enable_ctrl) |
| 175 | { | 172 | { |
| 176 | int i, reg_id = rdev_get_id(rdev); | 173 | int i; |
| 177 | unsigned int mode; | 174 | unsigned int mode; |
| 178 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 179 | 175 | ||
| 180 | switch (reg_id) { | 176 | switch (reg_id) { |
| 181 | case S5M8767_LDO1 ... S5M8767_LDO2: | 177 | case S5M8767_LDO1 ... S5M8767_LDO2: |
| @@ -214,53 +210,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, | |||
| 214 | return 0; | 210 | return 0; |
| 215 | } | 211 | } |
| 216 | 212 | ||
| 217 | static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) | ||
| 218 | { | ||
| 219 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 220 | int ret, reg; | ||
| 221 | int enable_ctrl; | ||
| 222 | unsigned int val; | ||
| 223 | |||
| 224 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 225 | if (ret == -EINVAL) | ||
| 226 | return 1; | ||
| 227 | else if (ret) | ||
| 228 | return ret; | ||
| 229 | |||
| 230 | ret = regmap_read(s5m8767->iodev->regmap_pmic, reg, &val); | ||
| 231 | if (ret) | ||
| 232 | return ret; | ||
| 233 | |||
| 234 | return (val & S5M8767_ENCTRL_MASK) == enable_ctrl; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int s5m8767_reg_enable(struct regulator_dev *rdev) | ||
| 238 | { | ||
| 239 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 240 | int ret, reg; | ||
| 241 | int enable_ctrl; | ||
| 242 | |||
| 243 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 244 | if (ret) | ||
| 245 | return ret; | ||
| 246 | |||
| 247 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg, | ||
| 248 | S5M8767_ENCTRL_MASK, enable_ctrl); | ||
| 249 | } | ||
| 250 | |||
| 251 | static int s5m8767_reg_disable(struct regulator_dev *rdev) | ||
| 252 | { | ||
| 253 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
| 254 | int ret, reg, enable_ctrl; | ||
| 255 | |||
| 256 | ret = s5m8767_get_register(rdev, ®, &enable_ctrl); | ||
| 257 | if (ret) | ||
| 258 | return ret; | ||
| 259 | |||
| 260 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg, | ||
| 261 | S5M8767_ENCTRL_MASK, ~S5M8767_ENCTRL_MASK); | ||
| 262 | } | ||
| 263 | |||
| 264 | static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) | 213 | static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) |
| 265 | { | 214 | { |
| 266 | int reg; | 215 | int reg; |
| @@ -410,9 +359,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, | |||
| 410 | 359 | ||
| 411 | static struct regulator_ops s5m8767_ops = { | 360 | static struct regulator_ops s5m8767_ops = { |
| 412 | .list_voltage = regulator_list_voltage_linear, | 361 | .list_voltage = regulator_list_voltage_linear, |
| 413 | .is_enabled = s5m8767_reg_is_enabled, | 362 | .is_enabled = regulator_is_enabled_regmap, |
| 414 | .enable = s5m8767_reg_enable, | 363 | .enable = regulator_enable_regmap, |
| 415 | .disable = s5m8767_reg_disable, | 364 | .disable = regulator_disable_regmap, |
| 416 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 365 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 417 | .set_voltage_sel = s5m8767_set_voltage_sel, | 366 | .set_voltage_sel = s5m8767_set_voltage_sel, |
| 418 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, | 367 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, |
| @@ -420,9 +369,9 @@ static struct regulator_ops s5m8767_ops = { | |||
| 420 | 369 | ||
| 421 | static struct regulator_ops s5m8767_buck78_ops = { | 370 | static struct regulator_ops s5m8767_buck78_ops = { |
| 422 | .list_voltage = regulator_list_voltage_linear, | 371 | .list_voltage = regulator_list_voltage_linear, |
| 423 | .is_enabled = s5m8767_reg_is_enabled, | 372 | .is_enabled = regulator_is_enabled_regmap, |
| 424 | .enable = s5m8767_reg_enable, | 373 | .enable = regulator_enable_regmap, |
| 425 | .disable = s5m8767_reg_disable, | 374 | .disable = regulator_disable_regmap, |
| 426 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 375 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 427 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 376 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 428 | }; | 377 | }; |
| @@ -483,6 +432,66 @@ static struct regulator_desc regulators[] = { | |||
| 483 | s5m8767_regulator_desc(BUCK9), | 432 | s5m8767_regulator_desc(BUCK9), |
| 484 | }; | 433 | }; |
| 485 | 434 | ||
| 435 | /* | ||
| 436 | * Enable GPIO control over BUCK9 in regulator_config for that regulator. | ||
| 437 | */ | ||
| 438 | static void s5m8767_regulator_config_ext_control(struct s5m8767_info *s5m8767, | ||
| 439 | struct sec_regulator_data *rdata, | ||
| 440 | struct regulator_config *config) | ||
| 441 | { | ||
| 442 | int i, mode = 0; | ||
| 443 | |||
| 444 | if (rdata->id != S5M8767_BUCK9) | ||
| 445 | return; | ||
| 446 | |||
| 447 | /* Check if opmode for regulator matches S5M8767_ENCTRL_USE_GPIO */ | ||
| 448 | for (i = 0; i < s5m8767->num_regulators; i++) { | ||
| 449 | const struct sec_opmode_data *opmode = &s5m8767->opmode[i]; | ||
| 450 | if (opmode->id == rdata->id) { | ||
| 451 | mode = s5m8767_opmode_reg[rdata->id][opmode->mode]; | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | } | ||
| 455 | if (mode != S5M8767_ENCTRL_USE_GPIO) { | ||
| 456 | dev_warn(s5m8767->dev, | ||
| 457 | "ext-control for %s: mismatched op_mode (%x), ignoring\n", | ||
| 458 | rdata->reg_node->name, mode); | ||
| 459 | return; | ||
| 460 | } | ||
| 461 | |||
| 462 | if (!gpio_is_valid(rdata->ext_control_gpio)) { | ||
| 463 | dev_warn(s5m8767->dev, | ||
| 464 | "ext-control for %s: GPIO not valid, ignoring\n", | ||
| 465 | rdata->reg_node->name); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | |||
| 469 | config->ena_gpio = rdata->ext_control_gpio; | ||
| 470 | config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
| 471 | } | ||
| 472 | |||
| 473 | /* | ||
| 474 | * Turn on GPIO control over BUCK9. | ||
| 475 | */ | ||
| 476 | static int s5m8767_enable_ext_control(struct s5m8767_info *s5m8767, | ||
| 477 | struct regulator_dev *rdev) | ||
| 478 | { | ||
| 479 | int id = rdev_get_id(rdev); | ||
| 480 | int ret, reg, enable_ctrl; | ||
| 481 | |||
| 482 | if (id != S5M8767_BUCK9) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 485 | ret = s5m8767_get_register(s5m8767, id, ®, &enable_ctrl); | ||
| 486 | if (ret) | ||
| 487 | return ret; | ||
| 488 | |||
| 489 | return regmap_update_bits(s5m8767->iodev->regmap_pmic, | ||
| 490 | reg, S5M8767_ENCTRL_MASK, | ||
| 491 | S5M8767_ENCTRL_USE_GPIO << S5M8767_ENCTRL_SHIFT); | ||
| 492 | } | ||
| 493 | |||
| 494 | |||
| 486 | #ifdef CONFIG_OF | 495 | #ifdef CONFIG_OF |
| 487 | static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, | 496 | static int s5m8767_pmic_dt_parse_dvs_gpio(struct sec_pmic_dev *iodev, |
| 488 | struct sec_platform_data *pdata, | 497 | struct sec_platform_data *pdata, |
| @@ -520,6 +529,16 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, | |||
| 520 | return 0; | 529 | return 0; |
| 521 | } | 530 | } |
| 522 | 531 | ||
| 532 | static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev, | ||
| 533 | struct sec_regulator_data *rdata, | ||
| 534 | struct device_node *reg_np) | ||
| 535 | { | ||
| 536 | rdata->ext_control_gpio = of_get_named_gpio(reg_np, | ||
| 537 | "s5m8767,pmic-ext-control-gpios", 0); | ||
| 538 | if (!gpio_is_valid(rdata->ext_control_gpio)) | ||
| 539 | rdata->ext_control_gpio = 0; | ||
| 540 | } | ||
| 541 | |||
| 523 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | 542 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, |
| 524 | struct sec_platform_data *pdata) | 543 | struct sec_platform_data *pdata) |
| 525 | { | 544 | { |
| @@ -535,7 +554,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 535 | return -ENODEV; | 554 | return -ENODEV; |
| 536 | } | 555 | } |
| 537 | 556 | ||
| 538 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 557 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); |
| 539 | if (!regulators_np) { | 558 | if (!regulators_np) { |
| 540 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | 559 | dev_err(iodev->dev, "could not find regulators sub-node\n"); |
| 541 | return -EINVAL; | 560 | return -EINVAL; |
| @@ -546,19 +565,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 546 | 565 | ||
| 547 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | 566 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
| 548 | pdata->num_regulators, GFP_KERNEL); | 567 | pdata->num_regulators, GFP_KERNEL); |
| 549 | if (!rdata) { | 568 | if (!rdata) |
| 550 | dev_err(iodev->dev, | ||
| 551 | "could not allocate memory for regulator data\n"); | ||
| 552 | return -ENOMEM; | 569 | return -ENOMEM; |
| 553 | } | ||
| 554 | 570 | ||
| 555 | rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * | 571 | rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * |
| 556 | pdata->num_regulators, GFP_KERNEL); | 572 | pdata->num_regulators, GFP_KERNEL); |
| 557 | if (!rmode) { | 573 | if (!rmode) |
| 558 | dev_err(iodev->dev, | ||
| 559 | "could not allocate memory for regulator mode\n"); | ||
| 560 | return -ENOMEM; | 574 | return -ENOMEM; |
| 561 | } | ||
| 562 | 575 | ||
| 563 | pdata->regulators = rdata; | 576 | pdata->regulators = rdata; |
| 564 | pdata->opmode = rmode; | 577 | pdata->opmode = rmode; |
| @@ -574,6 +587,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 574 | continue; | 587 | continue; |
| 575 | } | 588 | } |
| 576 | 589 | ||
| 590 | s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); | ||
| 591 | |||
| 577 | rdata->id = i; | 592 | rdata->id = i; |
| 578 | rdata->initdata = of_get_regulator_init_data( | 593 | rdata->initdata = of_get_regulator_init_data( |
| 579 | &pdev->dev, reg_np); | 594 | &pdev->dev, reg_np); |
| @@ -591,6 +606,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
| 591 | rmode++; | 606 | rmode++; |
| 592 | } | 607 | } |
| 593 | 608 | ||
| 609 | of_node_put(regulators_np); | ||
| 610 | |||
| 594 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { | 611 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { |
| 595 | pdata->buck2_gpiodvs = true; | 612 | pdata->buck2_gpiodvs = true; |
| 596 | 613 | ||
| @@ -920,6 +937,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 920 | for (i = 0; i < pdata->num_regulators; i++) { | 937 | for (i = 0; i < pdata->num_regulators; i++) { |
| 921 | const struct sec_voltage_desc *desc; | 938 | const struct sec_voltage_desc *desc; |
| 922 | int id = pdata->regulators[i].id; | 939 | int id = pdata->regulators[i].id; |
| 940 | int enable_reg, enable_val; | ||
| 923 | 941 | ||
| 924 | desc = reg_voltage_map[id]; | 942 | desc = reg_voltage_map[id]; |
| 925 | if (desc) { | 943 | if (desc) { |
| @@ -933,6 +951,12 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 933 | regulators[id].vsel_mask = 0x3f; | 951 | regulators[id].vsel_mask = 0x3f; |
| 934 | else | 952 | else |
| 935 | regulators[id].vsel_mask = 0xff; | 953 | regulators[id].vsel_mask = 0xff; |
| 954 | |||
| 955 | s5m8767_get_register(s5m8767, id, &enable_reg, | ||
| 956 | &enable_val); | ||
| 957 | regulators[id].enable_reg = enable_reg; | ||
| 958 | regulators[id].enable_mask = S5M8767_ENCTRL_MASK; | ||
| 959 | regulators[id].enable_val = enable_val; | ||
| 936 | } | 960 | } |
| 937 | 961 | ||
| 938 | config.dev = s5m8767->dev; | 962 | config.dev = s5m8767->dev; |
| @@ -940,6 +964,9 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 940 | config.driver_data = s5m8767; | 964 | config.driver_data = s5m8767; |
| 941 | config.regmap = iodev->regmap_pmic; | 965 | config.regmap = iodev->regmap_pmic; |
| 942 | config.of_node = pdata->regulators[i].reg_node; | 966 | config.of_node = pdata->regulators[i].reg_node; |
| 967 | if (pdata->regulators[i].ext_control_gpio) | ||
| 968 | s5m8767_regulator_config_ext_control(s5m8767, | ||
| 969 | &pdata->regulators[i], &config); | ||
| 943 | 970 | ||
| 944 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], | 971 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], |
| 945 | &config); | 972 | &config); |
| @@ -949,6 +976,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
| 949 | id); | 976 | id); |
| 950 | return ret; | 977 | return ret; |
| 951 | } | 978 | } |
| 979 | |||
| 980 | if (pdata->regulators[i].ext_control_gpio) { | ||
| 981 | ret = s5m8767_enable_ext_control(s5m8767, rdev[i]); | ||
| 982 | if (ret < 0) { | ||
| 983 | dev_err(s5m8767->dev, | ||
| 984 | "failed to enable gpio control over %s: %d\n", | ||
| 985 | rdev[i]->desc->name, ret); | ||
| 986 | return ret; | ||
| 987 | } | ||
| 988 | } | ||
| 952 | } | 989 | } |
| 953 | 990 | ||
| 954 | return 0; | 991 | return 0; |
diff --git a/drivers/regulator/st-pwm.c b/drivers/regulator/st-pwm.c new file mode 100644 index 000000000000..e367af1c5f9d --- /dev/null +++ b/drivers/regulator/st-pwm.c | |||
| @@ -0,0 +1,190 @@ | |||
| 1 | /* | ||
| 2 | * Regulator driver for ST's PWM Regulators | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 - STMicroelectronics Inc. | ||
| 5 | * | ||
| 6 | * Author: Lee Jones <lee.jones@linaro.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/regulator/driver.h> | ||
| 17 | #include <linux/regulator/machine.h> | ||
| 18 | #include <linux/regulator/of_regulator.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/of_device.h> | ||
| 21 | #include <linux/pwm.h> | ||
| 22 | |||
| 23 | #define ST_PWM_REG_PERIOD 8448 | ||
| 24 | |||
| 25 | struct st_pwm_regulator_pdata { | ||
| 26 | const struct regulator_desc *desc; | ||
| 27 | struct st_pwm_voltages *duty_cycle_table; | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct st_pwm_regulator_data { | ||
| 31 | const struct st_pwm_regulator_pdata *pdata; | ||
| 32 | struct pwm_device *pwm; | ||
| 33 | bool enabled; | ||
| 34 | int state; | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct st_pwm_voltages { | ||
| 38 | unsigned int uV; | ||
| 39 | unsigned int dutycycle; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static int st_pwm_regulator_get_voltage_sel(struct regulator_dev *dev) | ||
| 43 | { | ||
| 44 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 45 | |||
| 46 | return drvdata->state; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int st_pwm_regulator_set_voltage_sel(struct regulator_dev *dev, | ||
| 50 | unsigned selector) | ||
| 51 | { | ||
| 52 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 53 | int dutycycle; | ||
| 54 | int ret; | ||
| 55 | |||
| 56 | dutycycle = (ST_PWM_REG_PERIOD / 100) * | ||
| 57 | drvdata->pdata->duty_cycle_table[selector].dutycycle; | ||
| 58 | |||
| 59 | ret = pwm_config(drvdata->pwm, dutycycle, ST_PWM_REG_PERIOD); | ||
| 60 | if (ret) { | ||
| 61 | dev_err(&dev->dev, "Failed to configure PWM\n"); | ||
| 62 | return ret; | ||
| 63 | } | ||
| 64 | |||
| 65 | drvdata->state = selector; | ||
| 66 | |||
| 67 | if (!drvdata->enabled) { | ||
| 68 | ret = pwm_enable(drvdata->pwm); | ||
| 69 | if (ret) { | ||
| 70 | dev_err(&dev->dev, "Failed to enable PWM\n"); | ||
| 71 | return ret; | ||
| 72 | } | ||
| 73 | drvdata->enabled = true; | ||
| 74 | } | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int st_pwm_regulator_list_voltage(struct regulator_dev *dev, | ||
| 80 | unsigned selector) | ||
| 81 | { | ||
| 82 | struct st_pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
| 83 | |||
| 84 | if (selector >= dev->desc->n_voltages) | ||
| 85 | return -EINVAL; | ||
| 86 | |||
| 87 | return drvdata->pdata->duty_cycle_table[selector].uV; | ||
| 88 | } | ||
| 89 | |||
| 90 | static struct regulator_ops st_pwm_regulator_voltage_ops = { | ||
| 91 | .set_voltage_sel = st_pwm_regulator_set_voltage_sel, | ||
| 92 | .get_voltage_sel = st_pwm_regulator_get_voltage_sel, | ||
| 93 | .list_voltage = st_pwm_regulator_list_voltage, | ||
| 94 | .map_voltage = regulator_map_voltage_iterate, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static struct st_pwm_voltages b2105_duty_cycle_table[] = { | ||
| 98 | { .uV = 1114000, .dutycycle = 0, }, | ||
| 99 | { .uV = 1095000, .dutycycle = 10, }, | ||
| 100 | { .uV = 1076000, .dutycycle = 20, }, | ||
| 101 | { .uV = 1056000, .dutycycle = 30, }, | ||
| 102 | { .uV = 1036000, .dutycycle = 40, }, | ||
| 103 | { .uV = 1016000, .dutycycle = 50, }, | ||
| 104 | /* WARNING: Values above 50% duty-cycle cause boot failures. */ | ||
| 105 | }; | ||
| 106 | |||
| 107 | static const struct regulator_desc b2105_desc = { | ||
| 108 | .name = "b2105-pwm-regulator", | ||
| 109 | .ops = &st_pwm_regulator_voltage_ops, | ||
| 110 | .type = REGULATOR_VOLTAGE, | ||
| 111 | .owner = THIS_MODULE, | ||
| 112 | .n_voltages = ARRAY_SIZE(b2105_duty_cycle_table), | ||
| 113 | .supply_name = "pwm", | ||
| 114 | }; | ||
| 115 | |||
| 116 | static const struct st_pwm_regulator_pdata b2105_info = { | ||
| 117 | .desc = &b2105_desc, | ||
| 118 | .duty_cycle_table = b2105_duty_cycle_table, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct of_device_id st_pwm_of_match[] = { | ||
| 122 | { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, | ||
| 123 | { }, | ||
| 124 | }; | ||
| 125 | MODULE_DEVICE_TABLE(of, st_pwm_of_match); | ||
| 126 | |||
| 127 | static int st_pwm_regulator_probe(struct platform_device *pdev) | ||
| 128 | { | ||
| 129 | struct st_pwm_regulator_data *drvdata; | ||
| 130 | struct regulator_dev *regulator; | ||
| 131 | struct regulator_config config = { }; | ||
| 132 | struct device_node *np = pdev->dev.of_node; | ||
| 133 | const struct of_device_id *of_match; | ||
| 134 | |||
| 135 | if (!np) { | ||
| 136 | dev_err(&pdev->dev, "Device Tree node missing\n"); | ||
| 137 | return -EINVAL; | ||
| 138 | } | ||
| 139 | |||
| 140 | drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
| 141 | if (!drvdata) | ||
| 142 | return -ENOMEM; | ||
| 143 | |||
| 144 | of_match = of_match_device(st_pwm_of_match, &pdev->dev); | ||
| 145 | if (!of_match) { | ||
| 146 | dev_err(&pdev->dev, "failed to match of device\n"); | ||
| 147 | return -ENODEV; | ||
| 148 | } | ||
| 149 | drvdata->pdata = of_match->data; | ||
| 150 | |||
| 151 | config.init_data = of_get_regulator_init_data(&pdev->dev, np); | ||
| 152 | if (!config.init_data) | ||
| 153 | return -ENOMEM; | ||
| 154 | |||
| 155 | config.of_node = np; | ||
| 156 | config.dev = &pdev->dev; | ||
| 157 | config.driver_data = drvdata; | ||
| 158 | |||
| 159 | drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); | ||
| 160 | if (IS_ERR(drvdata->pwm)) { | ||
| 161 | dev_err(&pdev->dev, "Failed to get PWM\n"); | ||
| 162 | return PTR_ERR(drvdata->pwm); | ||
| 163 | } | ||
| 164 | |||
| 165 | regulator = devm_regulator_register(&pdev->dev, | ||
| 166 | drvdata->pdata->desc, &config); | ||
| 167 | if (IS_ERR(regulator)) { | ||
| 168 | dev_err(&pdev->dev, "Failed to register regulator %s\n", | ||
| 169 | drvdata->pdata->desc->name); | ||
| 170 | return PTR_ERR(regulator); | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | static struct platform_driver st_pwm_regulator_driver = { | ||
| 177 | .driver = { | ||
| 178 | .name = "st-pwm-regulator", | ||
| 179 | .owner = THIS_MODULE, | ||
| 180 | .of_match_table = of_match_ptr(st_pwm_of_match), | ||
| 181 | }, | ||
| 182 | .probe = st_pwm_regulator_probe, | ||
| 183 | }; | ||
| 184 | |||
| 185 | module_platform_driver(st_pwm_regulator_driver); | ||
| 186 | |||
| 187 | MODULE_LICENSE("GPL"); | ||
| 188 | MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>"); | ||
| 189 | MODULE_DESCRIPTION("ST PWM Regulator Driver"); | ||
| 190 | MODULE_ALIAS("platform:st_pwm-regulator"); | ||
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index b187b6bba7ad..a2dabb575b97 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c | |||
| @@ -54,8 +54,8 @@ struct ti_abb_info { | |||
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * struct ti_abb_reg - Register description for ABB block | 56 | * struct ti_abb_reg - Register description for ABB block |
| 57 | * @setup_reg: setup register offset from base | 57 | * @setup_off: setup register offset from base |
| 58 | * @control_reg: control register offset from base | 58 | * @control_off: control register offset from base |
| 59 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask | 59 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask |
| 60 | * @fbb_sel_mask: setup register- FBB sel mask | 60 | * @fbb_sel_mask: setup register- FBB sel mask |
| 61 | * @rbb_sel_mask: setup register- RBB sel mask | 61 | * @rbb_sel_mask: setup register- RBB sel mask |
| @@ -64,8 +64,8 @@ struct ti_abb_info { | |||
| 64 | * @opp_sel_mask: control register - mask for mode to operate | 64 | * @opp_sel_mask: control register - mask for mode to operate |
| 65 | */ | 65 | */ |
| 66 | struct ti_abb_reg { | 66 | struct ti_abb_reg { |
| 67 | u32 setup_reg; | 67 | u32 setup_off; |
| 68 | u32 control_reg; | 68 | u32 control_off; |
| 69 | 69 | ||
| 70 | /* Setup register fields */ | 70 | /* Setup register fields */ |
| 71 | u32 sr2_wtcnt_value_mask; | 71 | u32 sr2_wtcnt_value_mask; |
| @@ -83,6 +83,8 @@ struct ti_abb_reg { | |||
| 83 | * @rdesc: regulator descriptor | 83 | * @rdesc: regulator descriptor |
| 84 | * @clk: clock(usually sysclk) supplying ABB block | 84 | * @clk: clock(usually sysclk) supplying ABB block |
| 85 | * @base: base address of ABB block | 85 | * @base: base address of ABB block |
| 86 | * @setup_reg: setup register of ABB block | ||
| 87 | * @control_reg: control register of ABB block | ||
| 86 | * @int_base: interrupt register base address | 88 | * @int_base: interrupt register base address |
| 87 | * @efuse_base: (optional) efuse base address for ABB modes | 89 | * @efuse_base: (optional) efuse base address for ABB modes |
| 88 | * @ldo_base: (optional) LDOVBB vset override base address | 90 | * @ldo_base: (optional) LDOVBB vset override base address |
| @@ -99,6 +101,8 @@ struct ti_abb { | |||
| 99 | struct regulator_desc rdesc; | 101 | struct regulator_desc rdesc; |
| 100 | struct clk *clk; | 102 | struct clk *clk; |
| 101 | void __iomem *base; | 103 | void __iomem *base; |
| 104 | void __iomem *setup_reg; | ||
| 105 | void __iomem *control_reg; | ||
| 102 | void __iomem *int_base; | 106 | void __iomem *int_base; |
| 103 | void __iomem *efuse_base; | 107 | void __iomem *efuse_base; |
| 104 | void __iomem *ldo_base; | 108 | void __iomem *ldo_base; |
| @@ -118,20 +122,18 @@ struct ti_abb { | |||
| 118 | * ti_abb_rmw() - handy wrapper to set specific register bits | 122 | * ti_abb_rmw() - handy wrapper to set specific register bits |
| 119 | * @mask: mask for register field | 123 | * @mask: mask for register field |
| 120 | * @value: value shifted to mask location and written | 124 | * @value: value shifted to mask location and written |
| 121 | * @offset: offset of register | 125 | * @reg: register address |
| 122 | * @base: base address | ||
| 123 | * | 126 | * |
| 124 | * Return: final register value (may be unused) | 127 | * Return: final register value (may be unused) |
| 125 | */ | 128 | */ |
| 126 | static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset, | 129 | static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg) |
| 127 | void __iomem *base) | ||
| 128 | { | 130 | { |
| 129 | u32 val; | 131 | u32 val; |
| 130 | 132 | ||
| 131 | val = readl(base + offset); | 133 | val = readl(reg); |
| 132 | val &= ~mask; | 134 | val &= ~mask; |
| 133 | val |= (value << __ffs(mask)) & mask; | 135 | val |= (value << __ffs(mask)) & mask; |
| 134 | writel(val, base + offset); | 136 | writel(val, reg); |
| 135 | 137 | ||
| 136 | return val; | 138 | return val; |
| 137 | } | 139 | } |
| @@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, | |||
| 263 | if (ret) | 265 | if (ret) |
| 264 | goto out; | 266 | goto out; |
| 265 | 267 | ||
| 266 | ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg, | 268 | ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg); |
| 267 | abb->base); | ||
| 268 | 269 | ||
| 269 | switch (info->opp_sel) { | 270 | switch (info->opp_sel) { |
| 270 | case TI_ABB_SLOW_OPP: | 271 | case TI_ABB_SLOW_OPP: |
| 271 | ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base); | 272 | ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg); |
| 272 | break; | 273 | break; |
| 273 | case TI_ABB_FAST_OPP: | 274 | case TI_ABB_FAST_OPP: |
| 274 | ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base); | 275 | ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg); |
| 275 | break; | 276 | break; |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | /* program next state of ABB ldo */ | 279 | /* program next state of ABB ldo */ |
| 279 | ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, | 280 | ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg); |
| 280 | abb->base); | ||
| 281 | 281 | ||
| 282 | /* | 282 | /* |
| 283 | * program LDO VBB vset override if needed for !bypass mode | 283 | * program LDO VBB vset override if needed for !bypass mode |
| @@ -288,7 +288,7 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, | |||
| 288 | ti_abb_program_ldovbb(dev, abb, info); | 288 | ti_abb_program_ldovbb(dev, abb, info); |
| 289 | 289 | ||
| 290 | /* Initiate ABB ldo change */ | 290 | /* Initiate ABB ldo change */ |
| 291 | ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base); | 291 | ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg); |
| 292 | 292 | ||
| 293 | /* Wait for ABB LDO to complete transition to new Bias setting */ | 293 | /* Wait for ABB LDO to complete transition to new Bias setting */ |
| 294 | ret = ti_abb_wait_txdone(dev, abb); | 294 | ret = ti_abb_wait_txdone(dev, abb); |
| @@ -490,8 +490,7 @@ static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb) | |||
| 490 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, | 490 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, |
| 491 | clk_get_rate(abb->clk), sr2_wt_cnt_val); | 491 | clk_get_rate(abb->clk), sr2_wt_cnt_val); |
| 492 | 492 | ||
| 493 | ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg, | 493 | ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg); |
| 494 | abb->base); | ||
| 495 | 494 | ||
| 496 | return 0; | 495 | return 0; |
| 497 | } | 496 | } |
| @@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, | |||
| 508 | struct regulator_init_data *rinit_data) | 507 | struct regulator_init_data *rinit_data) |
| 509 | { | 508 | { |
| 510 | struct ti_abb_info *info; | 509 | struct ti_abb_info *info; |
| 511 | const struct property *prop; | ||
| 512 | const __be32 *abb_info; | ||
| 513 | const u32 num_values = 6; | 510 | const u32 num_values = 6; |
| 514 | char *pname = "ti,abb_info"; | 511 | char *pname = "ti,abb_info"; |
| 515 | u32 num_entries, i; | 512 | u32 i; |
| 516 | unsigned int *volt_table; | 513 | unsigned int *volt_table; |
| 517 | int min_uV = INT_MAX, max_uV = 0; | 514 | int num_entries, min_uV = INT_MAX, max_uV = 0; |
| 518 | struct regulation_constraints *c = &rinit_data->constraints; | 515 | struct regulation_constraints *c = &rinit_data->constraints; |
| 519 | 516 | ||
| 520 | prop = of_find_property(dev->of_node, pname, NULL); | ||
| 521 | if (!prop) { | ||
| 522 | dev_err(dev, "No '%s' property?\n", pname); | ||
| 523 | return -ENODEV; | ||
| 524 | } | ||
| 525 | |||
| 526 | if (!prop->value) { | ||
| 527 | dev_err(dev, "Empty '%s' property?\n", pname); | ||
| 528 | return -ENODATA; | ||
| 529 | } | ||
| 530 | |||
| 531 | /* | 517 | /* |
| 532 | * Each abb_info is a set of n-tuple, where n is num_values, consisting | 518 | * Each abb_info is a set of n-tuple, where n is num_values, consisting |
| 533 | * of voltage and a set of detection logic for ABB information for that | 519 | * of voltage and a set of detection logic for ABB information for that |
| 534 | * voltage to apply. | 520 | * voltage to apply. |
| 535 | */ | 521 | */ |
| 536 | num_entries = prop->length / sizeof(u32); | 522 | num_entries = of_property_count_u32_elems(dev->of_node, pname); |
| 523 | if (num_entries < 0) { | ||
| 524 | dev_err(dev, "No '%s' property?\n", pname); | ||
| 525 | return num_entries; | ||
| 526 | } | ||
| 527 | |||
| 537 | if (!num_entries || (num_entries % num_values)) { | 528 | if (!num_entries || (num_entries % num_values)) { |
| 538 | dev_err(dev, "All '%s' list entries need %d vals\n", pname, | 529 | dev_err(dev, "All '%s' list entries need %d vals\n", pname, |
| 539 | num_values); | 530 | num_values); |
| @@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, | |||
| 542 | num_entries /= num_values; | 533 | num_entries /= num_values; |
| 543 | 534 | ||
| 544 | info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); | 535 | info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); |
| 545 | if (!info) { | 536 | if (!info) |
| 546 | dev_err(dev, "Can't allocate info table for '%s' property\n", | ||
| 547 | pname); | ||
| 548 | return -ENOMEM; | 537 | return -ENOMEM; |
| 549 | } | 538 | |
| 550 | abb->info = info; | 539 | abb->info = info; |
| 551 | 540 | ||
| 552 | volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, | 541 | volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, |
| 553 | GFP_KERNEL); | 542 | GFP_KERNEL); |
| 554 | if (!volt_table) { | 543 | if (!volt_table) |
| 555 | dev_err(dev, "Can't allocate voltage table for '%s' property\n", | ||
| 556 | pname); | ||
| 557 | return -ENOMEM; | 544 | return -ENOMEM; |
| 558 | } | ||
| 559 | 545 | ||
| 560 | abb->rdesc.n_voltages = num_entries; | 546 | abb->rdesc.n_voltages = num_entries; |
| 561 | abb->rdesc.volt_table = volt_table; | 547 | abb->rdesc.volt_table = volt_table; |
| 562 | /* We do not know where the OPP voltage is at the moment */ | 548 | /* We do not know where the OPP voltage is at the moment */ |
| 563 | abb->current_info_idx = -EINVAL; | 549 | abb->current_info_idx = -EINVAL; |
| 564 | 550 | ||
| 565 | abb_info = prop->value; | ||
| 566 | for (i = 0; i < num_entries; i++, info++, volt_table++) { | 551 | for (i = 0; i < num_entries; i++, info++, volt_table++) { |
| 567 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; | 552 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; |
| 568 | u32 efuse_val; | 553 | u32 efuse_val; |
| 569 | 554 | ||
| 570 | /* NOTE: num_values should equal to entries picked up here */ | 555 | /* NOTE: num_values should equal to entries picked up here */ |
| 571 | *volt_table = be32_to_cpup(abb_info++); | 556 | of_property_read_u32_index(dev->of_node, pname, i * num_values, |
| 572 | info->opp_sel = be32_to_cpup(abb_info++); | 557 | volt_table); |
| 573 | efuse_offset = be32_to_cpup(abb_info++); | 558 | of_property_read_u32_index(dev->of_node, pname, |
| 574 | rbb_mask = be32_to_cpup(abb_info++); | 559 | i * num_values + 1, &info->opp_sel); |
| 575 | fbb_mask = be32_to_cpup(abb_info++); | 560 | of_property_read_u32_index(dev->of_node, pname, |
| 576 | vset_mask = be32_to_cpup(abb_info++); | 561 | i * num_values + 2, &efuse_offset); |
| 562 | of_property_read_u32_index(dev->of_node, pname, | ||
| 563 | i * num_values + 3, &rbb_mask); | ||
| 564 | of_property_read_u32_index(dev->of_node, pname, | ||
| 565 | i * num_values + 4, &fbb_mask); | ||
| 566 | of_property_read_u32_index(dev->of_node, pname, | ||
| 567 | i * num_values + 5, &vset_mask); | ||
| 577 | 568 | ||
| 578 | dev_dbg(dev, | 569 | dev_dbg(dev, |
| 579 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", | 570 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", |
| @@ -648,8 +639,8 @@ static struct regulator_ops ti_abb_reg_ops = { | |||
| 648 | /* Default ABB block offsets, IF this changes in future, create new one */ | 639 | /* Default ABB block offsets, IF this changes in future, create new one */ |
| 649 | static const struct ti_abb_reg abb_regs_v1 = { | 640 | static const struct ti_abb_reg abb_regs_v1 = { |
| 650 | /* WARNING: registers are wrongly documented in TRM */ | 641 | /* WARNING: registers are wrongly documented in TRM */ |
| 651 | .setup_reg = 0x04, | 642 | .setup_off = 0x04, |
| 652 | .control_reg = 0x00, | 643 | .control_off = 0x00, |
| 653 | 644 | ||
| 654 | .sr2_wtcnt_value_mask = (0xff << 8), | 645 | .sr2_wtcnt_value_mask = (0xff << 8), |
| 655 | .fbb_sel_mask = (0x01 << 2), | 646 | .fbb_sel_mask = (0x01 << 2), |
| @@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = { | |||
| 661 | }; | 652 | }; |
| 662 | 653 | ||
| 663 | static const struct ti_abb_reg abb_regs_v2 = { | 654 | static const struct ti_abb_reg abb_regs_v2 = { |
| 664 | .setup_reg = 0x00, | 655 | .setup_off = 0x00, |
| 665 | .control_reg = 0x04, | 656 | .control_off = 0x04, |
| 666 | 657 | ||
| 667 | .sr2_wtcnt_value_mask = (0xff << 8), | 658 | .sr2_wtcnt_value_mask = (0xff << 8), |
| 668 | .fbb_sel_mask = (0x01 << 2), | 659 | .fbb_sel_mask = (0x01 << 2), |
| @@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = { | |||
| 673 | .opp_sel_mask = (0x03 << 0), | 664 | .opp_sel_mask = (0x03 << 0), |
| 674 | }; | 665 | }; |
| 675 | 666 | ||
| 667 | static const struct ti_abb_reg abb_regs_generic = { | ||
| 668 | .sr2_wtcnt_value_mask = (0xff << 8), | ||
| 669 | .fbb_sel_mask = (0x01 << 2), | ||
| 670 | .rbb_sel_mask = (0x01 << 1), | ||
| 671 | .sr2_en_mask = (0x01 << 0), | ||
| 672 | |||
| 673 | .opp_change_mask = (0x01 << 2), | ||
| 674 | .opp_sel_mask = (0x03 << 0), | ||
| 675 | }; | ||
| 676 | |||
| 676 | static const struct of_device_id ti_abb_of_match[] = { | 677 | static const struct of_device_id ti_abb_of_match[] = { |
| 677 | {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, | 678 | {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, |
| 678 | {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, | 679 | {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, |
| 680 | {.compatible = "ti,abb-v3", .data = &abb_regs_generic}, | ||
| 679 | { }, | 681 | { }, |
| 680 | }; | 682 | }; |
| 681 | 683 | ||
| @@ -722,11 +724,29 @@ static int ti_abb_probe(struct platform_device *pdev) | |||
| 722 | abb->regs = match->data; | 724 | abb->regs = match->data; |
| 723 | 725 | ||
| 724 | /* Map ABB resources */ | 726 | /* Map ABB resources */ |
| 725 | pname = "base-address"; | 727 | if (abb->regs->setup_off || abb->regs->control_off) { |
| 726 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | 728 | pname = "base-address"; |
| 727 | abb->base = devm_ioremap_resource(dev, res); | 729 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
| 728 | if (IS_ERR(abb->base)) | 730 | abb->base = devm_ioremap_resource(dev, res); |
| 729 | return PTR_ERR(abb->base); | 731 | if (IS_ERR(abb->base)) |
| 732 | return PTR_ERR(abb->base); | ||
| 733 | |||
| 734 | abb->setup_reg = abb->base + abb->regs->setup_off; | ||
| 735 | abb->control_reg = abb->base + abb->regs->control_off; | ||
| 736 | |||
| 737 | } else { | ||
| 738 | pname = "control-address"; | ||
| 739 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | ||
| 740 | abb->control_reg = devm_ioremap_resource(dev, res); | ||
| 741 | if (IS_ERR(abb->control_reg)) | ||
| 742 | return PTR_ERR(abb->control_reg); | ||
| 743 | |||
| 744 | pname = "setup-address"; | ||
| 745 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | ||
| 746 | abb->setup_reg = devm_ioremap_resource(dev, res); | ||
| 747 | if (IS_ERR(abb->setup_reg)) | ||
| 748 | return PTR_ERR(abb->setup_reg); | ||
| 749 | } | ||
| 730 | 750 | ||
| 731 | pname = "int-address"; | 751 | pname = "int-address"; |
| 732 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); | 752 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
| @@ -860,7 +880,7 @@ skip_opt: | |||
| 860 | platform_set_drvdata(pdev, rdev); | 880 | platform_set_drvdata(pdev, rdev); |
| 861 | 881 | ||
| 862 | /* Enable the ldo if not already done by bootloader */ | 882 | /* Enable the ldo if not already done by bootloader */ |
| 863 | ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base); | 883 | ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg); |
| 864 | 884 | ||
| 865 | return 0; | 885 | return 0; |
| 866 | } | 886 | } |
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index b3764f594ee9..f31f22e3e1bd 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c | |||
| @@ -227,10 +227,8 @@ static struct tps51632_regulator_platform_data * | |||
| 227 | struct device_node *np = dev->of_node; | 227 | struct device_node *np = dev->of_node; |
| 228 | 228 | ||
| 229 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 229 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| 230 | if (!pdata) { | 230 | if (!pdata) |
| 231 | dev_err(dev, "Memory alloc failed for platform data\n"); | ||
| 232 | return NULL; | 231 | return NULL; |
| 233 | } | ||
| 234 | 232 | ||
| 235 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 233 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
| 236 | if (!pdata->reg_init_data) { | 234 | if (!pdata->reg_init_data) { |
| @@ -299,10 +297,8 @@ static int tps51632_probe(struct i2c_client *client, | |||
| 299 | } | 297 | } |
| 300 | 298 | ||
| 301 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 299 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
| 302 | if (!tps) { | 300 | if (!tps) |
| 303 | dev_err(&client->dev, "Memory allocation failed\n"); | ||
| 304 | return -ENOMEM; | 301 | return -ENOMEM; |
| 305 | } | ||
| 306 | 302 | ||
| 307 | tps->dev = &client->dev; | 303 | tps->dev = &client->dev; |
| 308 | tps->desc.name = client->name; | 304 | tps->desc.name = client->name; |
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index c3fa15a299b1..a1672044e519 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c | |||
| @@ -299,10 +299,8 @@ static struct tps62360_regulator_platform_data * | |||
| 299 | struct device_node *np = dev->of_node; | 299 | struct device_node *np = dev->of_node; |
| 300 | 300 | ||
| 301 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 301 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| 302 | if (!pdata) { | 302 | if (!pdata) |
| 303 | dev_err(dev, "Memory alloc failed for platform data\n"); | ||
| 304 | return NULL; | 303 | return NULL; |
| 305 | } | ||
| 306 | 304 | ||
| 307 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 305 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); |
| 308 | if (!pdata->reg_init_data) { | 306 | if (!pdata->reg_init_data) { |
| @@ -377,11 +375,8 @@ static int tps62360_probe(struct i2c_client *client, | |||
| 377 | } | 375 | } |
| 378 | 376 | ||
| 379 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 377 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
| 380 | if (!tps) { | 378 | if (!tps) |
| 381 | dev_err(&client->dev, "%s(): Memory allocation failed\n", | ||
| 382 | __func__); | ||
| 383 | return -ENOMEM; | 379 | return -ENOMEM; |
| 384 | } | ||
| 385 | 380 | ||
| 386 | tps->en_discharge = pdata->en_discharge; | 381 | tps->en_discharge = pdata->en_discharge; |
| 387 | tps->en_internal_pulldn = pdata->en_internal_pulldn; | 382 | tps->en_internal_pulldn = pdata->en_internal_pulldn; |
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 162a0fae20b3..98e66ce26723 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
| @@ -359,7 +359,6 @@ static struct regulator_ops tps6507x_pmic_ops = { | |||
| 359 | .map_voltage = regulator_map_voltage_ascend, | 359 | .map_voltage = regulator_map_voltage_ascend, |
| 360 | }; | 360 | }; |
| 361 | 361 | ||
| 362 | #ifdef CONFIG_OF | ||
| 363 | static struct of_regulator_match tps6507x_matches[] = { | 362 | static struct of_regulator_match tps6507x_matches[] = { |
| 364 | { .name = "VDCDC1"}, | 363 | { .name = "VDCDC1"}, |
| 365 | { .name = "VDCDC2"}, | 364 | { .name = "VDCDC2"}, |
| @@ -381,12 +380,10 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 381 | 380 | ||
| 382 | tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), | 381 | tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), |
| 383 | GFP_KERNEL); | 382 | GFP_KERNEL); |
| 384 | if (!tps_board) { | 383 | if (!tps_board) |
| 385 | dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); | ||
| 386 | return NULL; | 384 | return NULL; |
| 387 | } | ||
| 388 | 385 | ||
| 389 | regulators = of_find_node_by_name(np, "regulators"); | 386 | regulators = of_get_child_by_name(np, "regulators"); |
| 390 | if (!regulators) { | 387 | if (!regulators) { |
| 391 | dev_err(&pdev->dev, "regulator node not found\n"); | 388 | dev_err(&pdev->dev, "regulator node not found\n"); |
| 392 | return NULL; | 389 | return NULL; |
| @@ -396,6 +393,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 396 | matches = tps6507x_matches; | 393 | matches = tps6507x_matches; |
| 397 | 394 | ||
| 398 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); | 395 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); |
| 396 | of_node_put(regulators); | ||
| 399 | if (ret < 0) { | 397 | if (ret < 0) { |
| 400 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | 398 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
| 401 | ret); | 399 | ret); |
| @@ -406,10 +404,8 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 406 | 404 | ||
| 407 | reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) | 405 | reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) |
| 408 | * TPS6507X_NUM_REGULATOR), GFP_KERNEL); | 406 | * TPS6507X_NUM_REGULATOR), GFP_KERNEL); |
| 409 | if (!reg_data) { | 407 | if (!reg_data) |
| 410 | dev_err(&pdev->dev, "Failure to alloc init data for regulators.\n"); | ||
| 411 | return NULL; | 408 | return NULL; |
| 412 | } | ||
| 413 | 409 | ||
| 414 | tps_board->tps6507x_pmic_init_data = reg_data; | 410 | tps_board->tps6507x_pmic_init_data = reg_data; |
| 415 | 411 | ||
| @@ -424,15 +420,7 @@ static struct tps6507x_board *tps6507x_parse_dt_reg_data( | |||
| 424 | 420 | ||
| 425 | return tps_board; | 421 | return tps_board; |
| 426 | } | 422 | } |
| 427 | #else | 423 | |
| 428 | static inline struct tps6507x_board *tps6507x_parse_dt_reg_data( | ||
| 429 | struct platform_device *pdev, | ||
| 430 | struct of_regulator_match **tps6507x_reg_matches) | ||
| 431 | { | ||
| 432 | *tps6507x_reg_matches = NULL; | ||
| 433 | return NULL; | ||
| 434 | } | ||
| 435 | #endif | ||
| 436 | static int tps6507x_pmic_probe(struct platform_device *pdev) | 424 | static int tps6507x_pmic_probe(struct platform_device *pdev) |
| 437 | { | 425 | { |
| 438 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 426 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
| @@ -453,9 +441,10 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) | |||
| 453 | */ | 441 | */ |
| 454 | 442 | ||
| 455 | tps_board = dev_get_platdata(tps6507x_dev->dev); | 443 | tps_board = dev_get_platdata(tps6507x_dev->dev); |
| 456 | if (!tps_board && tps6507x_dev->dev->of_node) | 444 | if (IS_ENABLED(CONFIG_OF) && !tps_board && |
| 445 | tps6507x_dev->dev->of_node) | ||
| 457 | tps_board = tps6507x_parse_dt_reg_data(pdev, | 446 | tps_board = tps6507x_parse_dt_reg_data(pdev, |
| 458 | &tps6507x_reg_matches); | 447 | &tps6507x_reg_matches); |
| 459 | if (!tps_board) | 448 | if (!tps_board) |
| 460 | return -EINVAL; | 449 | return -EINVAL; |
| 461 | 450 | ||
| @@ -481,7 +470,7 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) | |||
| 481 | tps->info[i] = info; | 470 | tps->info[i] = info; |
| 482 | if (init_data->driver_data) { | 471 | if (init_data->driver_data) { |
| 483 | struct tps6507x_reg_platform_data *data = | 472 | struct tps6507x_reg_platform_data *data = |
| 484 | init_data->driver_data; | 473 | init_data->driver_data; |
| 485 | tps->info[i]->defdcdc_default = data->defdcdc_default; | 474 | tps->info[i]->defdcdc_default = data->defdcdc_default; |
| 486 | } | 475 | } |
| 487 | 476 | ||
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 9ea1bf26bd13..10b78d2b766a 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
| @@ -187,7 +187,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | |||
| 187 | struct device_node *regs; | 187 | struct device_node *regs; |
| 188 | int i, count; | 188 | int i, count; |
| 189 | 189 | ||
| 190 | regs = of_find_node_by_name(node, "regulators"); | 190 | regs = of_get_child_by_name(node, "regulators"); |
| 191 | if (!regs) | 191 | if (!regs) |
| 192 | return NULL; | 192 | return NULL; |
| 193 | 193 | ||
| @@ -202,7 +202,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | |||
| 202 | return NULL; | 202 | return NULL; |
| 203 | 203 | ||
| 204 | for (i = 0; i < count; i++) { | 204 | for (i = 0; i < count; i++) { |
| 205 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | 205 | if (!reg_matches[i].of_node) |
| 206 | continue; | 206 | continue; |
| 207 | 207 | ||
| 208 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | 208 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; |
| @@ -222,7 +222,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
| 222 | { | 222 | { |
| 223 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | 223 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); |
| 224 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | 224 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); |
| 225 | struct regulator_init_data *reg_data; | ||
| 226 | struct regulator_dev *rdev; | 225 | struct regulator_dev *rdev; |
| 227 | struct regulator_config config = { }; | 226 | struct regulator_config config = { }; |
| 228 | int i; | 227 | int i; |
| @@ -243,19 +242,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
| 243 | platform_set_drvdata(pdev, tps); | 242 | platform_set_drvdata(pdev, tps); |
| 244 | 243 | ||
| 245 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | 244 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { |
| 246 | |||
| 247 | reg_data = pdata->tps65217_init_data[i]; | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Regulator API handles empty constraints but not NULL | ||
| 251 | * constraints | ||
| 252 | */ | ||
| 253 | if (!reg_data) | ||
| 254 | continue; | ||
| 255 | |||
| 256 | /* Register the regulators */ | 245 | /* Register the regulators */ |
| 257 | config.dev = tps->dev; | 246 | config.dev = tps->dev; |
| 258 | config.init_data = reg_data; | 247 | config.init_data = pdata->tps65217_init_data[i]; |
| 259 | config.driver_data = tps; | 248 | config.driver_data = tps; |
| 260 | config.regmap = tps->regmap; | 249 | config.regmap = tps->regmap; |
| 261 | if (tps->dev->of_node) | 250 | if (tps->dev->of_node) |
