diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/88pm8607.c | 30 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 6 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
-rw-r--r-- | drivers/regulator/ab3100.c | 3 | ||||
-rw-r--r-- | drivers/regulator/core.c | 93 | ||||
-rw-r--r-- | drivers/regulator/db8500-prcmu.c | 4 | ||||
-rw-r--r-- | drivers/regulator/max8925-regulator.c | 11 | ||||
-rw-r--r-- | drivers/regulator/max8997.c | 13 | ||||
-rw-r--r-- | drivers/regulator/max8998.c | 22 | ||||
-rw-r--r-- | drivers/regulator/mc13783-regulator.c | 7 | ||||
-rw-r--r-- | drivers/regulator/mc13892-regulator.c | 25 | ||||
-rw-r--r-- | drivers/regulator/mc13xxx-regulator-core.c | 2 | ||||
-rw-r--r-- | drivers/regulator/tps6105x-regulator.c | 5 | ||||
-rw-r--r-- | drivers/regulator/tps65023-regulator.c | 3 | ||||
-rw-r--r-- | drivers/regulator/tps6507x-regulator.c | 3 | ||||
-rw-r--r-- | drivers/regulator/tps65910-regulator.c | 993 | ||||
-rw-r--r-- | drivers/regulator/twl-regulator.c | 564 | ||||
-rw-r--r-- | drivers/regulator/wm831x-dcdc.c | 2 | ||||
-rw-r--r-- | drivers/regulator/wm8400-regulator.c | 12 |
19 files changed, 1627 insertions, 172 deletions
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 859251250b55..d63fddb0fbb0 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/regulator/driver.h> | 16 | #include <linux/regulator/driver.h> |
17 | #include <linux/regulator/machine.h> | 17 | #include <linux/regulator/machine.h> |
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/mfd/88pm860x.h> | 18 | #include <linux/mfd/88pm860x.h> |
20 | 19 | ||
21 | struct pm8607_regulator_info { | 20 | struct pm8607_regulator_info { |
@@ -399,36 +398,33 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | |||
399 | { | 398 | { |
400 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 399 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
401 | struct pm8607_regulator_info *info = NULL; | 400 | struct pm8607_regulator_info *info = NULL; |
402 | struct regulator_init_data *pdata; | 401 | struct regulator_init_data *pdata = pdev->dev.platform_data; |
403 | struct mfd_cell *cell; | 402 | struct resource *res; |
404 | int i; | 403 | int i; |
405 | 404 | ||
406 | cell = pdev->dev.platform_data; | 405 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
407 | if (cell == NULL) | 406 | if (res == NULL) { |
408 | return -ENODEV; | 407 | dev_err(&pdev->dev, "No I/O resource!\n"); |
409 | pdata = cell->mfd_data; | ||
410 | if (pdata == NULL) | ||
411 | return -EINVAL; | 408 | return -EINVAL; |
412 | 409 | } | |
413 | for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { | 410 | for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { |
414 | info = &pm8607_regulator_info[i]; | 411 | info = &pm8607_regulator_info[i]; |
415 | if (!strcmp(info->desc.name, pdata->constraints.name)) | 412 | if (info->desc.id == res->start) |
416 | break; | 413 | break; |
417 | } | 414 | } |
418 | if (i > ARRAY_SIZE(pm8607_regulator_info)) { | 415 | if ((i < 0) || (i > PM8607_ID_RG_MAX)) { |
419 | dev_err(&pdev->dev, "Failed to find regulator %s\n", | 416 | dev_err(&pdev->dev, "Failed to find regulator %llu\n", |
420 | pdata->constraints.name); | 417 | (unsigned long long)res->start); |
421 | return -EINVAL; | 418 | return -EINVAL; |
422 | } | 419 | } |
423 | |||
424 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | 420 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; |
425 | info->chip = chip; | 421 | info->chip = chip; |
426 | 422 | ||
427 | /* check DVC ramp slope double */ | 423 | /* check DVC ramp slope double */ |
428 | if (!strcmp(info->desc.name, "BUCK3")) | 424 | if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double) |
429 | if (info->chip->buck3_double) | 425 | info->slope_double = 1; |
430 | info->slope_double = 1; | ||
431 | 426 | ||
427 | /* replace driver_data with info */ | ||
432 | info->regulator = regulator_register(&info->desc, &pdev->dev, | 428 | info->regulator = regulator_register(&info->desc, &pdev->dev, |
433 | pdata, info); | 429 | pdata, info); |
434 | if (IS_ERR(info->regulator)) { | 430 | if (IS_ERR(info->regulator)) { |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f0b13a0d1851..d7ed20f293d7 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -297,5 +297,11 @@ config REGULATOR_TPS6524X | |||
297 | serial interface currently supported on the sequencer serial | 297 | serial interface currently supported on the sequencer serial |
298 | port controller. | 298 | port controller. |
299 | 299 | ||
300 | config REGULATOR_TPS65910 | ||
301 | tristate "TI TPS65910 Power Regulator" | ||
302 | depends on MFD_TPS65910 | ||
303 | help | ||
304 | This driver supports TPS65910 voltage regulator chips. | ||
305 | |||
300 | endif | 306 | endif |
301 | 307 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 165ff5371e9e..3932d2ec38f3 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -42,5 +42,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o | |||
42 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | 42 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
43 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | 43 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o |
44 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | 44 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o |
45 | obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o | ||
45 | 46 | ||
46 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG | 47 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index b1d77946e9c6..585e4946fe0a 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/regulator/driver.h> | 18 | #include <linux/regulator/driver.h> |
19 | #include <linux/mfd/abx500.h> | 19 | #include <linux/mfd/abx500.h> |
20 | #include <linux/mfd/core.h> | ||
21 | 20 | ||
22 | /* LDO registers and some handy masking definitions for AB3100 */ | 21 | /* LDO registers and some handy masking definitions for AB3100 */ |
23 | #define AB3100_LDO_A 0x40 | 22 | #define AB3100_LDO_A 0x40 |
@@ -582,7 +581,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { | |||
582 | 581 | ||
583 | static int __devinit ab3100_regulators_probe(struct platform_device *pdev) | 582 | static int __devinit ab3100_regulators_probe(struct platform_device *pdev) |
584 | { | 583 | { |
585 | struct ab3100_platform_data *plfdata = mfd_get_data(pdev); | 584 | struct ab3100_platform_data *plfdata = pdev->dev.platform_data; |
586 | int err = 0; | 585 | int err = 0; |
587 | u8 data; | 586 | u8 data; |
588 | int i; | 587 | int i; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0fae51c4845a..d3e38790906e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -158,6 +158,13 @@ static int regulator_check_consumers(struct regulator_dev *rdev, | |||
158 | struct regulator *regulator; | 158 | struct regulator *regulator; |
159 | 159 | ||
160 | list_for_each_entry(regulator, &rdev->consumer_list, list) { | 160 | list_for_each_entry(regulator, &rdev->consumer_list, list) { |
161 | /* | ||
162 | * Assume consumers that didn't say anything are OK | ||
163 | * with anything in the constraint range. | ||
164 | */ | ||
165 | if (!regulator->min_uV && !regulator->max_uV) | ||
166 | continue; | ||
167 | |||
161 | if (*max_uV > regulator->max_uV) | 168 | if (*max_uV > regulator->max_uV) |
162 | *max_uV = regulator->max_uV; | 169 | *max_uV = regulator->max_uV; |
163 | if (*min_uV < regulator->min_uV) | 170 | if (*min_uV < regulator->min_uV) |
@@ -197,9 +204,9 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, | |||
197 | } | 204 | } |
198 | 205 | ||
199 | /* operating mode constraint check */ | 206 | /* operating mode constraint check */ |
200 | static int regulator_check_mode(struct regulator_dev *rdev, int mode) | 207 | static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode) |
201 | { | 208 | { |
202 | switch (mode) { | 209 | switch (*mode) { |
203 | case REGULATOR_MODE_FAST: | 210 | case REGULATOR_MODE_FAST: |
204 | case REGULATOR_MODE_NORMAL: | 211 | case REGULATOR_MODE_NORMAL: |
205 | case REGULATOR_MODE_IDLE: | 212 | case REGULATOR_MODE_IDLE: |
@@ -217,11 +224,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) | |||
217 | rdev_err(rdev, "operation not allowed\n"); | 224 | rdev_err(rdev, "operation not allowed\n"); |
218 | return -EPERM; | 225 | return -EPERM; |
219 | } | 226 | } |
220 | if (!(rdev->constraints->valid_modes_mask & mode)) { | 227 | |
221 | rdev_err(rdev, "invalid mode %x\n", mode); | 228 | /* The modes are bitmasks, the most power hungry modes having |
222 | return -EINVAL; | 229 | * the lowest values. If the requested mode isn't supported |
230 | * try higher modes. */ | ||
231 | while (*mode) { | ||
232 | if (rdev->constraints->valid_modes_mask & *mode) | ||
233 | return 0; | ||
234 | *mode /= 2; | ||
223 | } | 235 | } |
224 | return 0; | 236 | |
237 | return -EINVAL; | ||
225 | } | 238 | } |
226 | 239 | ||
227 | /* dynamic regulator mode switching constraint check */ | 240 | /* dynamic regulator mode switching constraint check */ |
@@ -612,7 +625,7 @@ static void drms_uA_update(struct regulator_dev *rdev) | |||
612 | output_uV, current_uA); | 625 | output_uV, current_uA); |
613 | 626 | ||
614 | /* check the new mode is allowed */ | 627 | /* check the new mode is allowed */ |
615 | err = regulator_check_mode(rdev, mode); | 628 | err = regulator_mode_constrain(rdev, &mode); |
616 | if (err == 0) | 629 | if (err == 0) |
617 | rdev->desc->ops->set_mode(rdev, mode); | 630 | rdev->desc->ops->set_mode(rdev, mode); |
618 | } | 631 | } |
@@ -718,6 +731,10 @@ static void print_constraints(struct regulator_dev *rdev) | |||
718 | count += sprintf(buf + count, "at %d mV ", ret / 1000); | 731 | count += sprintf(buf + count, "at %d mV ", ret / 1000); |
719 | } | 732 | } |
720 | 733 | ||
734 | if (constraints->uV_offset) | ||
735 | count += sprintf(buf, "%dmV offset ", | ||
736 | constraints->uV_offset / 1000); | ||
737 | |||
721 | if (constraints->min_uA && constraints->max_uA) { | 738 | if (constraints->min_uA && constraints->max_uA) { |
722 | if (constraints->min_uA == constraints->max_uA) | 739 | if (constraints->min_uA == constraints->max_uA) |
723 | count += sprintf(buf + count, "%d mA ", | 740 | count += sprintf(buf + count, "%d mA ", |
@@ -1498,13 +1515,14 @@ static int _regulator_force_disable(struct regulator_dev *rdev, | |||
1498 | */ | 1515 | */ |
1499 | int regulator_force_disable(struct regulator *regulator) | 1516 | int regulator_force_disable(struct regulator *regulator) |
1500 | { | 1517 | { |
1518 | struct regulator_dev *rdev = regulator->rdev; | ||
1501 | struct regulator_dev *supply_rdev = NULL; | 1519 | struct regulator_dev *supply_rdev = NULL; |
1502 | int ret; | 1520 | int ret; |
1503 | 1521 | ||
1504 | mutex_lock(®ulator->rdev->mutex); | 1522 | mutex_lock(&rdev->mutex); |
1505 | regulator->uA_load = 0; | 1523 | regulator->uA_load = 0; |
1506 | ret = _regulator_force_disable(regulator->rdev, &supply_rdev); | 1524 | ret = _regulator_force_disable(rdev, &supply_rdev); |
1507 | mutex_unlock(®ulator->rdev->mutex); | 1525 | mutex_unlock(&rdev->mutex); |
1508 | 1526 | ||
1509 | if (supply_rdev) | 1527 | if (supply_rdev) |
1510 | regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); | 1528 | regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); |
@@ -1634,6 +1652,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
1634 | 1652 | ||
1635 | trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); | 1653 | trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); |
1636 | 1654 | ||
1655 | min_uV += rdev->constraints->uV_offset; | ||
1656 | max_uV += rdev->constraints->uV_offset; | ||
1657 | |||
1637 | if (rdev->desc->ops->set_voltage) { | 1658 | if (rdev->desc->ops->set_voltage) { |
1638 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, | 1659 | ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, |
1639 | &selector); | 1660 | &selector); |
@@ -1858,18 +1879,22 @@ EXPORT_SYMBOL_GPL(regulator_sync_voltage); | |||
1858 | 1879 | ||
1859 | static int _regulator_get_voltage(struct regulator_dev *rdev) | 1880 | static int _regulator_get_voltage(struct regulator_dev *rdev) |
1860 | { | 1881 | { |
1861 | int sel; | 1882 | int sel, ret; |
1862 | 1883 | ||
1863 | if (rdev->desc->ops->get_voltage_sel) { | 1884 | if (rdev->desc->ops->get_voltage_sel) { |
1864 | sel = rdev->desc->ops->get_voltage_sel(rdev); | 1885 | sel = rdev->desc->ops->get_voltage_sel(rdev); |
1865 | if (sel < 0) | 1886 | if (sel < 0) |
1866 | return sel; | 1887 | return sel; |
1867 | return rdev->desc->ops->list_voltage(rdev, sel); | 1888 | ret = rdev->desc->ops->list_voltage(rdev, sel); |
1868 | } | 1889 | } else if (rdev->desc->ops->get_voltage) { |
1869 | if (rdev->desc->ops->get_voltage) | 1890 | ret = rdev->desc->ops->get_voltage(rdev); |
1870 | return rdev->desc->ops->get_voltage(rdev); | 1891 | } else { |
1871 | else | ||
1872 | return -EINVAL; | 1892 | return -EINVAL; |
1893 | } | ||
1894 | |||
1895 | if (ret < 0) | ||
1896 | return ret; | ||
1897 | return ret - rdev->constraints->uV_offset; | ||
1873 | } | 1898 | } |
1874 | 1899 | ||
1875 | /** | 1900 | /** |
@@ -2005,7 +2030,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) | |||
2005 | } | 2030 | } |
2006 | 2031 | ||
2007 | /* constraints check */ | 2032 | /* constraints check */ |
2008 | ret = regulator_check_mode(rdev, mode); | 2033 | ret = regulator_mode_constrain(rdev, &mode); |
2009 | if (ret < 0) | 2034 | if (ret < 0) |
2010 | goto out; | 2035 | goto out; |
2011 | 2036 | ||
@@ -2081,16 +2106,26 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2081 | 2106 | ||
2082 | mutex_lock(&rdev->mutex); | 2107 | mutex_lock(&rdev->mutex); |
2083 | 2108 | ||
2109 | /* | ||
2110 | * first check to see if we can set modes at all, otherwise just | ||
2111 | * tell the consumer everything is OK. | ||
2112 | */ | ||
2084 | regulator->uA_load = uA_load; | 2113 | regulator->uA_load = uA_load; |
2085 | ret = regulator_check_drms(rdev); | 2114 | ret = regulator_check_drms(rdev); |
2086 | if (ret < 0) | 2115 | if (ret < 0) { |
2116 | ret = 0; | ||
2087 | goto out; | 2117 | goto out; |
2088 | ret = -EINVAL; | 2118 | } |
2089 | 2119 | ||
2090 | /* sanity check */ | ||
2091 | if (!rdev->desc->ops->get_optimum_mode) | 2120 | if (!rdev->desc->ops->get_optimum_mode) |
2092 | goto out; | 2121 | goto out; |
2093 | 2122 | ||
2123 | /* | ||
2124 | * we can actually do this so any errors are indicators of | ||
2125 | * potential real failure. | ||
2126 | */ | ||
2127 | ret = -EINVAL; | ||
2128 | |||
2094 | /* get output voltage */ | 2129 | /* get output voltage */ |
2095 | output_uV = _regulator_get_voltage(rdev); | 2130 | output_uV = _regulator_get_voltage(rdev); |
2096 | if (output_uV <= 0) { | 2131 | if (output_uV <= 0) { |
@@ -2116,7 +2151,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | |||
2116 | mode = rdev->desc->ops->get_optimum_mode(rdev, | 2151 | mode = rdev->desc->ops->get_optimum_mode(rdev, |
2117 | input_uV, output_uV, | 2152 | input_uV, output_uV, |
2118 | total_uA_load); | 2153 | total_uA_load); |
2119 | ret = regulator_check_mode(rdev, mode); | 2154 | ret = regulator_mode_constrain(rdev, &mode); |
2120 | if (ret < 0) { | 2155 | if (ret < 0) { |
2121 | rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", | 2156 | rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", |
2122 | total_uA_load, input_uV, output_uV); | 2157 | total_uA_load, input_uV, output_uV); |
@@ -2589,14 +2624,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2589 | if (ret < 0) | 2624 | if (ret < 0) |
2590 | goto scrub; | 2625 | goto scrub; |
2591 | 2626 | ||
2592 | /* set supply regulator if it exists */ | ||
2593 | if (init_data->supply_regulator && init_data->supply_regulator_dev) { | ||
2594 | dev_err(dev, | ||
2595 | "Supply regulator specified by both name and dev\n"); | ||
2596 | ret = -EINVAL; | ||
2597 | goto scrub; | ||
2598 | } | ||
2599 | |||
2600 | if (init_data->supply_regulator) { | 2627 | if (init_data->supply_regulator) { |
2601 | struct regulator_dev *r; | 2628 | struct regulator_dev *r; |
2602 | int found = 0; | 2629 | int found = 0; |
@@ -2621,14 +2648,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2621 | goto scrub; | 2648 | goto scrub; |
2622 | } | 2649 | } |
2623 | 2650 | ||
2624 | if (init_data->supply_regulator_dev) { | ||
2625 | dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n"); | ||
2626 | ret = set_supply(rdev, | ||
2627 | dev_get_drvdata(init_data->supply_regulator_dev)); | ||
2628 | if (ret < 0) | ||
2629 | goto scrub; | ||
2630 | } | ||
2631 | |||
2632 | /* add consumers devices */ | 2651 | /* add consumers devices */ |
2633 | for (i = 0; i < init_data->num_consumer_supplies; i++) { | 2652 | for (i = 0; i < init_data->num_consumer_supplies; i++) { |
2634 | ret = set_consumer_device_supply(rdev, | 2653 | ret = set_consumer_device_supply(rdev, |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 1089a961616e..e5f7b8fe51f4 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/mfd/core.h> | ||
17 | #include <linux/mfd/db8500-prcmu.h> | 16 | #include <linux/mfd/db8500-prcmu.h> |
18 | #include <linux/regulator/driver.h> | 17 | #include <linux/regulator/driver.h> |
19 | #include <linux/regulator/machine.h> | 18 | #include <linux/regulator/machine.h> |
@@ -471,7 +470,8 @@ static struct db8500_regulator_info | |||
471 | 470 | ||
472 | static int __devinit db8500_regulator_probe(struct platform_device *pdev) | 471 | static int __devinit db8500_regulator_probe(struct platform_device *pdev) |
473 | { | 472 | { |
474 | struct regulator_init_data *db8500_init_data = mfd_get_data(pdev); | 473 | struct regulator_init_data *db8500_init_data = |
474 | dev_get_platdata(&pdev->dev); | ||
475 | int i, err; | 475 | int i, err; |
476 | 476 | ||
477 | /* register all regulators */ | 477 | /* register all regulators */ |
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 8ae147549c6a..e4dbd667c043 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c | |||
@@ -23,6 +23,10 @@ | |||
23 | #define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */ | 23 | #define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */ |
24 | #define SD1_DVM_EN 6 /* SDV1 bit 6 */ | 24 | #define SD1_DVM_EN 6 /* SDV1 bit 6 */ |
25 | 25 | ||
26 | /* bit definitions in SD & LDO control registers */ | ||
27 | #define OUT_ENABLE 0x1f /* Power U/D sequence as I2C */ | ||
28 | #define OUT_DISABLE 0x1e /* Power U/D sequence as I2C */ | ||
29 | |||
26 | struct max8925_regulator_info { | 30 | struct max8925_regulator_info { |
27 | struct regulator_desc desc; | 31 | struct regulator_desc desc; |
28 | struct regulator_dev *regulator; | 32 | struct regulator_dev *regulator; |
@@ -93,8 +97,8 @@ static int max8925_enable(struct regulator_dev *rdev) | |||
93 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); | 97 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); |
94 | 98 | ||
95 | return max8925_set_bits(info->i2c, info->enable_reg, | 99 | return max8925_set_bits(info->i2c, info->enable_reg, |
96 | 1 << info->enable_bit, | 100 | OUT_ENABLE << info->enable_bit, |
97 | 1 << info->enable_bit); | 101 | OUT_ENABLE << info->enable_bit); |
98 | } | 102 | } |
99 | 103 | ||
100 | static int max8925_disable(struct regulator_dev *rdev) | 104 | static int max8925_disable(struct regulator_dev *rdev) |
@@ -102,7 +106,8 @@ static int max8925_disable(struct regulator_dev *rdev) | |||
102 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); | 106 | struct max8925_regulator_info *info = rdev_get_drvdata(rdev); |
103 | 107 | ||
104 | return max8925_set_bits(info->i2c, info->enable_reg, | 108 | return max8925_set_bits(info->i2c, info->enable_reg, |
105 | 1 << info->enable_bit, 0); | 109 | OUT_ENABLE << info->enable_bit, |
110 | OUT_DISABLE << info->enable_bit); | ||
106 | } | 111 | } |
107 | 112 | ||
108 | static int max8925_is_enabled(struct regulator_dev *rdev) | 113 | static int max8925_is_enabled(struct regulator_dev *rdev) |
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 77e0cfb30b23..10d5a1d9768e 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -267,7 +267,6 @@ static int max8997_get_enable_register(struct regulator_dev *rdev, | |||
267 | default: | 267 | default: |
268 | /* Not controllable or not exists */ | 268 | /* Not controllable or not exists */ |
269 | return -EINVAL; | 269 | return -EINVAL; |
270 | break; | ||
271 | } | 270 | } |
272 | 271 | ||
273 | return 0; | 272 | return 0; |
@@ -1033,11 +1032,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) | |||
1033 | 1032 | ||
1034 | /* For the safety, set max voltage before setting up */ | 1033 | /* For the safety, set max voltage before setting up */ |
1035 | for (i = 0; i < 8; i++) { | 1034 | for (i = 0; i < 8; i++) { |
1036 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), | 1035 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, |
1037 | max_buck1, 0x3f); | 1036 | max_buck1, 0x3f); |
1038 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), | 1037 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, |
1039 | max_buck2, 0x3f); | 1038 | max_buck2, 0x3f); |
1040 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), | 1039 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, |
1041 | max_buck5, 0x3f); | 1040 | max_buck5, 0x3f); |
1042 | } | 1041 | } |
1043 | 1042 | ||
@@ -1114,13 +1113,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) | |||
1114 | 1113 | ||
1115 | /* Initialize all the DVS related BUCK registers */ | 1114 | /* Initialize all the DVS related BUCK registers */ |
1116 | for (i = 0; i < 8; i++) { | 1115 | for (i = 0; i < 8; i++) { |
1117 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), | 1116 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, |
1118 | max8997->buck1_vol[i], | 1117 | max8997->buck1_vol[i], |
1119 | 0x3f); | 1118 | 0x3f); |
1120 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), | 1119 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, |
1121 | max8997->buck2_vol[i], | 1120 | max8997->buck2_vol[i], |
1122 | 0x3f); | 1121 | 0x3f); |
1123 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), | 1122 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, |
1124 | max8997->buck5_vol[i], | 1123 | max8997->buck5_vol[i], |
1125 | 0x3f); | 1124 | 0x3f); |
1126 | } | 1125 | } |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index f57e9c42fdb4..41a1495eec2b 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -732,13 +732,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
732 | if (!pdata->buck1_set1) { | 732 | if (!pdata->buck1_set1) { |
733 | printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); | 733 | printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); |
734 | WARN_ON(!pdata->buck1_set1); | 734 | WARN_ON(!pdata->buck1_set1); |
735 | return -EIO; | 735 | ret = -EIO; |
736 | goto err_free_mem; | ||
736 | } | 737 | } |
737 | /* Check if SET2 is not equal to 0 */ | 738 | /* Check if SET2 is not equal to 0 */ |
738 | if (!pdata->buck1_set2) { | 739 | if (!pdata->buck1_set2) { |
739 | printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); | 740 | printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); |
740 | WARN_ON(!pdata->buck1_set2); | 741 | WARN_ON(!pdata->buck1_set2); |
741 | return -EIO; | 742 | ret = -EIO; |
743 | goto err_free_mem; | ||
742 | } | 744 | } |
743 | 745 | ||
744 | gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); | 746 | gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); |
@@ -758,7 +760,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
758 | max8998->buck1_vol[0] = i; | 760 | max8998->buck1_vol[0] = i; |
759 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); | 761 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); |
760 | if (ret) | 762 | if (ret) |
761 | return ret; | 763 | goto err_free_mem; |
762 | 764 | ||
763 | /* Set predefined value for BUCK1 register 2 */ | 765 | /* Set predefined value for BUCK1 register 2 */ |
764 | i = 0; | 766 | i = 0; |
@@ -770,7 +772,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
770 | max8998->buck1_vol[1] = i; | 772 | max8998->buck1_vol[1] = i; |
771 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); | 773 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); |
772 | if (ret) | 774 | if (ret) |
773 | return ret; | 775 | goto err_free_mem; |
774 | 776 | ||
775 | /* Set predefined value for BUCK1 register 3 */ | 777 | /* Set predefined value for BUCK1 register 3 */ |
776 | i = 0; | 778 | i = 0; |
@@ -782,7 +784,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
782 | max8998->buck1_vol[2] = i; | 784 | max8998->buck1_vol[2] = i; |
783 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); | 785 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); |
784 | if (ret) | 786 | if (ret) |
785 | return ret; | 787 | goto err_free_mem; |
786 | 788 | ||
787 | /* Set predefined value for BUCK1 register 4 */ | 789 | /* Set predefined value for BUCK1 register 4 */ |
788 | i = 0; | 790 | i = 0; |
@@ -794,7 +796,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
794 | max8998->buck1_vol[3] = i; | 796 | max8998->buck1_vol[3] = i; |
795 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); | 797 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); |
796 | if (ret) | 798 | if (ret) |
797 | return ret; | 799 | goto err_free_mem; |
798 | 800 | ||
799 | } | 801 | } |
800 | 802 | ||
@@ -803,7 +805,8 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
803 | if (!pdata->buck2_set3) { | 805 | if (!pdata->buck2_set3) { |
804 | printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); | 806 | printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); |
805 | WARN_ON(!pdata->buck2_set3); | 807 | WARN_ON(!pdata->buck2_set3); |
806 | return -EIO; | 808 | ret = -EIO; |
809 | goto err_free_mem; | ||
807 | } | 810 | } |
808 | gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); | 811 | gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); |
809 | gpio_direction_output(pdata->buck2_set3, | 812 | gpio_direction_output(pdata->buck2_set3, |
@@ -818,7 +821,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
818 | max8998->buck2_vol[0] = i; | 821 | max8998->buck2_vol[0] = i; |
819 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); | 822 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); |
820 | if (ret) | 823 | if (ret) |
821 | return ret; | 824 | goto err_free_mem; |
822 | 825 | ||
823 | /* BUCK2 register 2 */ | 826 | /* BUCK2 register 2 */ |
824 | i = 0; | 827 | i = 0; |
@@ -830,7 +833,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
830 | max8998->buck2_vol[1] = i; | 833 | max8998->buck2_vol[1] = i; |
831 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); | 834 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); |
832 | if (ret) | 835 | if (ret) |
833 | return ret; | 836 | goto err_free_mem; |
834 | } | 837 | } |
835 | 838 | ||
836 | for (i = 0; i < pdata->num_regulators; i++) { | 839 | for (i = 0; i < pdata->num_regulators; i++) { |
@@ -860,6 +863,7 @@ err: | |||
860 | if (rdev[i]) | 863 | if (rdev[i]) |
861 | regulator_unregister(rdev[i]); | 864 | regulator_unregister(rdev[i]); |
862 | 865 | ||
866 | err_free_mem: | ||
863 | kfree(max8998->rdev); | 867 | kfree(max8998->rdev); |
864 | kfree(max8998); | 868 | kfree(max8998); |
865 | 869 | ||
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index b8a00c7fa441..730f43ad415b 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/regulator/driver.h> | 15 | #include <linux/regulator/driver.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
21 | #include <linux/err.h> | 20 | #include <linux/err.h> |
@@ -337,7 +336,8 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | |||
337 | { | 336 | { |
338 | struct mc13xxx_regulator_priv *priv; | 337 | struct mc13xxx_regulator_priv *priv; |
339 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); | 338 | struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); |
340 | struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev); | 339 | struct mc13783_regulator_platform_data *pdata = |
340 | dev_get_platdata(&pdev->dev); | ||
341 | struct mc13783_regulator_init_data *init_data; | 341 | struct mc13783_regulator_init_data *init_data; |
342 | int i, ret; | 342 | int i, ret; |
343 | 343 | ||
@@ -381,7 +381,8 @@ err: | |||
381 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) | 381 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) |
382 | { | 382 | { |
383 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); | 383 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); |
384 | struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev); | 384 | struct mc13783_regulator_platform_data *pdata = |
385 | dev_get_platdata(&pdev->dev); | ||
385 | int i; | 386 | int i; |
386 | 387 | ||
387 | platform_set_drvdata(pdev, NULL); | 388 | platform_set_drvdata(pdev, NULL); |
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 6f15168e5ed4..3285d41842f2 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/regulator/driver.h> | 15 | #include <linux/regulator/driver.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
21 | #include <linux/err.h> | 20 | #include <linux/err.h> |
@@ -432,7 +431,8 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, | |||
432 | int min_uV, int max_uV, unsigned *selector) | 431 | int min_uV, int max_uV, unsigned *selector) |
433 | { | 432 | { |
434 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 433 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
435 | int hi, value, val, mask, id = rdev_get_id(rdev); | 434 | int hi, value, mask, id = rdev_get_id(rdev); |
435 | u32 valread; | ||
436 | int ret; | 436 | int ret; |
437 | 437 | ||
438 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | 438 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", |
@@ -448,15 +448,16 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, | |||
448 | 448 | ||
449 | mc13xxx_lock(priv->mc13xxx); | 449 | mc13xxx_lock(priv->mc13xxx); |
450 | ret = mc13xxx_reg_read(priv->mc13xxx, | 450 | ret = mc13xxx_reg_read(priv->mc13xxx, |
451 | mc13892_regulators[id].vsel_reg, &val); | 451 | mc13892_regulators[id].vsel_reg, &valread); |
452 | if (ret) | 452 | if (ret) |
453 | goto err; | 453 | goto err; |
454 | 454 | ||
455 | hi = val & MC13892_SWITCHERS0_SWxHI; | 455 | if (value > 1375000) |
456 | if (value > 1375) | ||
457 | hi = 1; | 456 | hi = 1; |
458 | if (value < 1100) | 457 | else if (value < 1100000) |
459 | hi = 0; | 458 | hi = 0; |
459 | else | ||
460 | hi = valread & MC13892_SWITCHERS0_SWxHI; | ||
460 | 461 | ||
461 | if (hi) { | 462 | if (hi) { |
462 | value = (value - 1100000) / 25000; | 463 | value = (value - 1100000) / 25000; |
@@ -465,8 +466,10 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, | |||
465 | value = (value - 600000) / 25000; | 466 | value = (value - 600000) / 25000; |
466 | 467 | ||
467 | mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; | 468 | mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; |
468 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, | 469 | valread = (valread & ~mask) | |
469 | mask, value << mc13892_regulators[id].vsel_shift); | 470 | (value << mc13892_regulators[id].vsel_shift); |
471 | ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg, | ||
472 | valread); | ||
470 | err: | 473 | err: |
471 | mc13xxx_unlock(priv->mc13xxx); | 474 | mc13xxx_unlock(priv->mc13xxx); |
472 | 475 | ||
@@ -521,7 +524,8 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) | |||
521 | { | 524 | { |
522 | struct mc13xxx_regulator_priv *priv; | 525 | struct mc13xxx_regulator_priv *priv; |
523 | struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); | 526 | struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); |
524 | struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev); | 527 | struct mc13xxx_regulator_platform_data *pdata = |
528 | dev_get_platdata(&pdev->dev); | ||
525 | struct mc13xxx_regulator_init_data *init_data; | 529 | struct mc13xxx_regulator_init_data *init_data; |
526 | int i, ret; | 530 | int i, ret; |
527 | u32 val; | 531 | u32 val; |
@@ -595,7 +599,8 @@ err_free: | |||
595 | static int __devexit mc13892_regulator_remove(struct platform_device *pdev) | 599 | static int __devexit mc13892_regulator_remove(struct platform_device *pdev) |
596 | { | 600 | { |
597 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); | 601 | struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); |
598 | struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev); | 602 | struct mc13xxx_regulator_platform_data *pdata = |
603 | dev_get_platdata(&pdev->dev); | ||
599 | int i; | 604 | int i; |
600 | 605 | ||
601 | platform_set_drvdata(pdev, NULL); | 606 | platform_set_drvdata(pdev, NULL); |
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 2bb5de1f2421..bc27ab136378 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
@@ -174,7 +174,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) | |||
174 | 174 | ||
175 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | 175 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); |
176 | 176 | ||
177 | BUG_ON(val > mc13xxx_regulators[id].desc.n_voltages); | 177 | BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); |
178 | 178 | ||
179 | return mc13xxx_regulators[id].voltages[val]; | 179 | return mc13xxx_regulators[id].voltages[val]; |
180 | } | 180 | } |
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 1661499feda4..1011873896dc 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c | |||
@@ -137,7 +137,7 @@ static struct regulator_desc tps6105x_regulator_desc = { | |||
137 | */ | 137 | */ |
138 | static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) | 138 | static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) |
139 | { | 139 | { |
140 | struct tps6105x *tps6105x = mfd_get_data(pdev); | 140 | struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); |
141 | struct tps6105x_platform_data *pdata = tps6105x->pdata; | 141 | struct tps6105x_platform_data *pdata = tps6105x->pdata; |
142 | int ret; | 142 | int ret; |
143 | 143 | ||
@@ -158,13 +158,14 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) | |||
158 | "failed to register regulator\n"); | 158 | "failed to register regulator\n"); |
159 | return ret; | 159 | return ret; |
160 | } | 160 | } |
161 | platform_set_drvdata(pdev, tps6105x); | ||
161 | 162 | ||
162 | return 0; | 163 | return 0; |
163 | } | 164 | } |
164 | 165 | ||
165 | static int __devexit tps6105x_regulator_remove(struct platform_device *pdev) | 166 | static int __devexit tps6105x_regulator_remove(struct platform_device *pdev) |
166 | { | 167 | { |
167 | struct tps6105x *tps6105x = platform_get_drvdata(pdev); | 168 | struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); |
168 | regulator_unregister(tps6105x->regulator); | 169 | regulator_unregister(tps6105x->regulator); |
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 60a7ca5409e9..fbddc15e1811 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -466,7 +466,6 @@ static struct regulator_ops tps65023_ldo_ops = { | |||
466 | static int __devinit tps_65023_probe(struct i2c_client *client, | 466 | static int __devinit tps_65023_probe(struct i2c_client *client, |
467 | const struct i2c_device_id *id) | 467 | const struct i2c_device_id *id) |
468 | { | 468 | { |
469 | static int desc_id; | ||
470 | const struct tps_info *info = (void *)id->driver_data; | 469 | const struct tps_info *info = (void *)id->driver_data; |
471 | struct regulator_init_data *init_data; | 470 | struct regulator_init_data *init_data; |
472 | struct regulator_dev *rdev; | 471 | struct regulator_dev *rdev; |
@@ -499,7 +498,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
499 | tps->info[i] = info; | 498 | tps->info[i] = info; |
500 | 499 | ||
501 | tps->desc[i].name = info->name; | 500 | tps->desc[i].name = info->name; |
502 | tps->desc[i].id = desc_id++; | 501 | tps->desc[i].id = i; |
503 | tps->desc[i].n_voltages = num_voltages[i]; | 502 | tps->desc[i].n_voltages = num_voltages[i]; |
504 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? | 503 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? |
505 | &tps65023_ldo_ops : &tps65023_dcdc_ops); | 504 | &tps65023_ldo_ops : &tps65023_dcdc_ops); |
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 064755290599..bfffabc21eda 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -553,7 +553,6 @@ static __devinit | |||
553 | int tps6507x_pmic_probe(struct platform_device *pdev) | 553 | int tps6507x_pmic_probe(struct platform_device *pdev) |
554 | { | 554 | { |
555 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 555 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
556 | static int desc_id; | ||
557 | struct tps_info *info = &tps6507x_pmic_regs[0]; | 556 | struct tps_info *info = &tps6507x_pmic_regs[0]; |
558 | struct regulator_init_data *init_data; | 557 | struct regulator_init_data *init_data; |
559 | struct regulator_dev *rdev; | 558 | struct regulator_dev *rdev; |
@@ -598,7 +597,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) | |||
598 | } | 597 | } |
599 | 598 | ||
600 | tps->desc[i].name = info->name; | 599 | tps->desc[i].name = info->name; |
601 | tps->desc[i].id = desc_id++; | 600 | tps->desc[i].id = i; |
602 | tps->desc[i].n_voltages = num_voltages[i]; | 601 | tps->desc[i].n_voltages = num_voltages[i]; |
603 | tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? | 602 | tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? |
604 | &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); | 603 | &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c new file mode 100644 index 000000000000..55dd4e6650db --- /dev/null +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -0,0 +1,993 @@ | |||
1 | /* | ||
2 | * tps65910.c -- TI tps65910 | ||
3 | * | ||
4 | * Copyright 2010 Texas Instruments Inc. | ||
5 | * | ||
6 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | ||
7 | * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regulator/driver.h> | ||
22 | #include <linux/regulator/machine.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include <linux/mfd/tps65910.h> | ||
27 | |||
28 | #define TPS65910_REG_VRTC 0 | ||
29 | #define TPS65910_REG_VIO 1 | ||
30 | #define TPS65910_REG_VDD1 2 | ||
31 | #define TPS65910_REG_VDD2 3 | ||
32 | #define TPS65910_REG_VDD3 4 | ||
33 | #define TPS65910_REG_VDIG1 5 | ||
34 | #define TPS65910_REG_VDIG2 6 | ||
35 | #define TPS65910_REG_VPLL 7 | ||
36 | #define TPS65910_REG_VDAC 8 | ||
37 | #define TPS65910_REG_VAUX1 9 | ||
38 | #define TPS65910_REG_VAUX2 10 | ||
39 | #define TPS65910_REG_VAUX33 11 | ||
40 | #define TPS65910_REG_VMMC 12 | ||
41 | |||
42 | #define TPS65911_REG_VDDCTRL 4 | ||
43 | #define TPS65911_REG_LDO1 5 | ||
44 | #define TPS65911_REG_LDO2 6 | ||
45 | #define TPS65911_REG_LDO3 7 | ||
46 | #define TPS65911_REG_LDO4 8 | ||
47 | #define TPS65911_REG_LDO5 9 | ||
48 | #define TPS65911_REG_LDO6 10 | ||
49 | #define TPS65911_REG_LDO7 11 | ||
50 | #define TPS65911_REG_LDO8 12 | ||
51 | |||
52 | #define TPS65910_NUM_REGULATOR 13 | ||
53 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 | ||
54 | |||
55 | /* supported VIO voltages in milivolts */ | ||
56 | static const u16 VIO_VSEL_table[] = { | ||
57 | 1500, 1800, 2500, 3300, | ||
58 | }; | ||
59 | |||
60 | /* VSEL tables for TPS65910 specific LDOs and dcdc's */ | ||
61 | |||
62 | /* supported VDD3 voltages in milivolts */ | ||
63 | static const u16 VDD3_VSEL_table[] = { | ||
64 | 5000, | ||
65 | }; | ||
66 | |||
67 | /* supported VDIG1 voltages in milivolts */ | ||
68 | static const u16 VDIG1_VSEL_table[] = { | ||
69 | 1200, 1500, 1800, 2700, | ||
70 | }; | ||
71 | |||
72 | /* supported VDIG2 voltages in milivolts */ | ||
73 | static const u16 VDIG2_VSEL_table[] = { | ||
74 | 1000, 1100, 1200, 1800, | ||
75 | }; | ||
76 | |||
77 | /* supported VPLL voltages in milivolts */ | ||
78 | static const u16 VPLL_VSEL_table[] = { | ||
79 | 1000, 1100, 1800, 2500, | ||
80 | }; | ||
81 | |||
82 | /* supported VDAC voltages in milivolts */ | ||
83 | static const u16 VDAC_VSEL_table[] = { | ||
84 | 1800, 2600, 2800, 2850, | ||
85 | }; | ||
86 | |||
87 | /* supported VAUX1 voltages in milivolts */ | ||
88 | static const u16 VAUX1_VSEL_table[] = { | ||
89 | 1800, 2500, 2800, 2850, | ||
90 | }; | ||
91 | |||
92 | /* supported VAUX2 voltages in milivolts */ | ||
93 | static const u16 VAUX2_VSEL_table[] = { | ||
94 | 1800, 2800, 2900, 3300, | ||
95 | }; | ||
96 | |||
97 | /* supported VAUX33 voltages in milivolts */ | ||
98 | static const u16 VAUX33_VSEL_table[] = { | ||
99 | 1800, 2000, 2800, 3300, | ||
100 | }; | ||
101 | |||
102 | /* supported VMMC voltages in milivolts */ | ||
103 | static const u16 VMMC_VSEL_table[] = { | ||
104 | 1800, 2800, 3000, 3300, | ||
105 | }; | ||
106 | |||
107 | struct tps_info { | ||
108 | const char *name; | ||
109 | unsigned min_uV; | ||
110 | unsigned max_uV; | ||
111 | u8 table_len; | ||
112 | const u16 *table; | ||
113 | }; | ||
114 | |||
115 | static struct tps_info tps65910_regs[] = { | ||
116 | { | ||
117 | .name = "VRTC", | ||
118 | }, | ||
119 | { | ||
120 | .name = "VIO", | ||
121 | .min_uV = 1500000, | ||
122 | .max_uV = 3300000, | ||
123 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | ||
124 | .table = VIO_VSEL_table, | ||
125 | }, | ||
126 | { | ||
127 | .name = "VDD1", | ||
128 | .min_uV = 600000, | ||
129 | .max_uV = 4500000, | ||
130 | }, | ||
131 | { | ||
132 | .name = "VDD2", | ||
133 | .min_uV = 600000, | ||
134 | .max_uV = 4500000, | ||
135 | }, | ||
136 | { | ||
137 | .name = "VDD3", | ||
138 | .min_uV = 5000000, | ||
139 | .max_uV = 5000000, | ||
140 | .table_len = ARRAY_SIZE(VDD3_VSEL_table), | ||
141 | .table = VDD3_VSEL_table, | ||
142 | }, | ||
143 | { | ||
144 | .name = "VDIG1", | ||
145 | .min_uV = 1200000, | ||
146 | .max_uV = 2700000, | ||
147 | .table_len = ARRAY_SIZE(VDIG1_VSEL_table), | ||
148 | .table = VDIG1_VSEL_table, | ||
149 | }, | ||
150 | { | ||
151 | .name = "VDIG2", | ||
152 | .min_uV = 1000000, | ||
153 | .max_uV = 1800000, | ||
154 | .table_len = ARRAY_SIZE(VDIG2_VSEL_table), | ||
155 | .table = VDIG2_VSEL_table, | ||
156 | }, | ||
157 | { | ||
158 | .name = "VPLL", | ||
159 | .min_uV = 1000000, | ||
160 | .max_uV = 2500000, | ||
161 | .table_len = ARRAY_SIZE(VPLL_VSEL_table), | ||
162 | .table = VPLL_VSEL_table, | ||
163 | }, | ||
164 | { | ||
165 | .name = "VDAC", | ||
166 | .min_uV = 1800000, | ||
167 | .max_uV = 2850000, | ||
168 | .table_len = ARRAY_SIZE(VDAC_VSEL_table), | ||
169 | .table = VDAC_VSEL_table, | ||
170 | }, | ||
171 | { | ||
172 | .name = "VAUX1", | ||
173 | .min_uV = 1800000, | ||
174 | .max_uV = 2850000, | ||
175 | .table_len = ARRAY_SIZE(VAUX1_VSEL_table), | ||
176 | .table = VAUX1_VSEL_table, | ||
177 | }, | ||
178 | { | ||
179 | .name = "VAUX2", | ||
180 | .min_uV = 1800000, | ||
181 | .max_uV = 3300000, | ||
182 | .table_len = ARRAY_SIZE(VAUX2_VSEL_table), | ||
183 | .table = VAUX2_VSEL_table, | ||
184 | }, | ||
185 | { | ||
186 | .name = "VAUX33", | ||
187 | .min_uV = 1800000, | ||
188 | .max_uV = 3300000, | ||
189 | .table_len = ARRAY_SIZE(VAUX33_VSEL_table), | ||
190 | .table = VAUX33_VSEL_table, | ||
191 | }, | ||
192 | { | ||
193 | .name = "VMMC", | ||
194 | .min_uV = 1800000, | ||
195 | .max_uV = 3300000, | ||
196 | .table_len = ARRAY_SIZE(VMMC_VSEL_table), | ||
197 | .table = VMMC_VSEL_table, | ||
198 | }, | ||
199 | }; | ||
200 | |||
201 | static struct tps_info tps65911_regs[] = { | ||
202 | { | ||
203 | .name = "VIO", | ||
204 | .min_uV = 1500000, | ||
205 | .max_uV = 3300000, | ||
206 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | ||
207 | .table = VIO_VSEL_table, | ||
208 | }, | ||
209 | { | ||
210 | .name = "VDD1", | ||
211 | .min_uV = 600000, | ||
212 | .max_uV = 4500000, | ||
213 | }, | ||
214 | { | ||
215 | .name = "VDD2", | ||
216 | .min_uV = 600000, | ||
217 | .max_uV = 4500000, | ||
218 | }, | ||
219 | { | ||
220 | .name = "VDDCTRL", | ||
221 | .min_uV = 600000, | ||
222 | .max_uV = 1400000, | ||
223 | }, | ||
224 | { | ||
225 | .name = "LDO1", | ||
226 | .min_uV = 1000000, | ||
227 | .max_uV = 3300000, | ||
228 | }, | ||
229 | { | ||
230 | .name = "LDO2", | ||
231 | .min_uV = 1000000, | ||
232 | .max_uV = 3300000, | ||
233 | }, | ||
234 | { | ||
235 | .name = "LDO3", | ||
236 | .min_uV = 1000000, | ||
237 | .max_uV = 3300000, | ||
238 | }, | ||
239 | { | ||
240 | .name = "LDO4", | ||
241 | .min_uV = 1000000, | ||
242 | .max_uV = 3300000, | ||
243 | }, | ||
244 | { | ||
245 | .name = "LDO5", | ||
246 | .min_uV = 1000000, | ||
247 | .max_uV = 3300000, | ||
248 | }, | ||
249 | { | ||
250 | .name = "LDO6", | ||
251 | .min_uV = 1000000, | ||
252 | .max_uV = 3300000, | ||
253 | }, | ||
254 | { | ||
255 | .name = "LDO7", | ||
256 | .min_uV = 1000000, | ||
257 | .max_uV = 3300000, | ||
258 | }, | ||
259 | { | ||
260 | .name = "LDO8", | ||
261 | .min_uV = 1000000, | ||
262 | .max_uV = 3300000, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | struct tps65910_reg { | ||
267 | struct regulator_desc desc[TPS65910_NUM_REGULATOR]; | ||
268 | struct tps65910 *mfd; | ||
269 | struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; | ||
270 | struct tps_info *info[TPS65910_NUM_REGULATOR]; | ||
271 | struct mutex mutex; | ||
272 | int mode; | ||
273 | int (*get_ctrl_reg)(int); | ||
274 | }; | ||
275 | |||
276 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) | ||
277 | { | ||
278 | u8 val; | ||
279 | int err; | ||
280 | |||
281 | err = pmic->mfd->read(pmic->mfd, reg, 1, &val); | ||
282 | if (err) | ||
283 | return err; | ||
284 | |||
285 | return val; | ||
286 | } | ||
287 | |||
288 | static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val) | ||
289 | { | ||
290 | return pmic->mfd->write(pmic->mfd, reg, 1, &val); | ||
291 | } | ||
292 | |||
293 | static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, | ||
294 | u8 set_mask, u8 clear_mask) | ||
295 | { | ||
296 | int err, data; | ||
297 | |||
298 | mutex_lock(&pmic->mutex); | ||
299 | |||
300 | data = tps65910_read(pmic, reg); | ||
301 | if (data < 0) { | ||
302 | dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); | ||
303 | err = data; | ||
304 | goto out; | ||
305 | } | ||
306 | |||
307 | data &= ~clear_mask; | ||
308 | data |= set_mask; | ||
309 | err = tps65910_write(pmic, reg, data); | ||
310 | if (err) | ||
311 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | ||
312 | |||
313 | out: | ||
314 | mutex_unlock(&pmic->mutex); | ||
315 | return err; | ||
316 | } | ||
317 | |||
318 | static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg) | ||
319 | { | ||
320 | int data; | ||
321 | |||
322 | mutex_lock(&pmic->mutex); | ||
323 | |||
324 | data = tps65910_read(pmic, reg); | ||
325 | if (data < 0) | ||
326 | dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); | ||
327 | |||
328 | mutex_unlock(&pmic->mutex); | ||
329 | return data; | ||
330 | } | ||
331 | |||
332 | static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val) | ||
333 | { | ||
334 | int err; | ||
335 | |||
336 | mutex_lock(&pmic->mutex); | ||
337 | |||
338 | err = tps65910_write(pmic, reg, val); | ||
339 | if (err < 0) | ||
340 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | ||
341 | |||
342 | mutex_unlock(&pmic->mutex); | ||
343 | return err; | ||
344 | } | ||
345 | |||
346 | static int tps65910_get_ctrl_register(int id) | ||
347 | { | ||
348 | switch (id) { | ||
349 | case TPS65910_REG_VRTC: | ||
350 | return TPS65910_VRTC; | ||
351 | case TPS65910_REG_VIO: | ||
352 | return TPS65910_VIO; | ||
353 | case TPS65910_REG_VDD1: | ||
354 | return TPS65910_VDD1; | ||
355 | case TPS65910_REG_VDD2: | ||
356 | return TPS65910_VDD2; | ||
357 | case TPS65910_REG_VDD3: | ||
358 | return TPS65910_VDD3; | ||
359 | case TPS65910_REG_VDIG1: | ||
360 | return TPS65910_VDIG1; | ||
361 | case TPS65910_REG_VDIG2: | ||
362 | return TPS65910_VDIG2; | ||
363 | case TPS65910_REG_VPLL: | ||
364 | return TPS65910_VPLL; | ||
365 | case TPS65910_REG_VDAC: | ||
366 | return TPS65910_VDAC; | ||
367 | case TPS65910_REG_VAUX1: | ||
368 | return TPS65910_VAUX1; | ||
369 | case TPS65910_REG_VAUX2: | ||
370 | return TPS65910_VAUX2; | ||
371 | case TPS65910_REG_VAUX33: | ||
372 | return TPS65910_VAUX33; | ||
373 | case TPS65910_REG_VMMC: | ||
374 | return TPS65910_VMMC; | ||
375 | default: | ||
376 | return -EINVAL; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | static int tps65911_get_ctrl_register(int id) | ||
381 | { | ||
382 | switch (id) { | ||
383 | case TPS65910_REG_VRTC: | ||
384 | return TPS65910_VRTC; | ||
385 | case TPS65910_REG_VIO: | ||
386 | return TPS65910_VIO; | ||
387 | case TPS65910_REG_VDD1: | ||
388 | return TPS65910_VDD1; | ||
389 | case TPS65910_REG_VDD2: | ||
390 | return TPS65910_VDD2; | ||
391 | case TPS65911_REG_VDDCTRL: | ||
392 | return TPS65911_VDDCTRL; | ||
393 | case TPS65911_REG_LDO1: | ||
394 | return TPS65911_LDO1; | ||
395 | case TPS65911_REG_LDO2: | ||
396 | return TPS65911_LDO2; | ||
397 | case TPS65911_REG_LDO3: | ||
398 | return TPS65911_LDO3; | ||
399 | case TPS65911_REG_LDO4: | ||
400 | return TPS65911_LDO4; | ||
401 | case TPS65911_REG_LDO5: | ||
402 | return TPS65911_LDO5; | ||
403 | case TPS65911_REG_LDO6: | ||
404 | return TPS65911_LDO6; | ||
405 | case TPS65911_REG_LDO7: | ||
406 | return TPS65911_LDO7; | ||
407 | case TPS65911_REG_LDO8: | ||
408 | return TPS65911_LDO8; | ||
409 | default: | ||
410 | return -EINVAL; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | static int tps65910_is_enabled(struct regulator_dev *dev) | ||
415 | { | ||
416 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
417 | int reg, value, id = rdev_get_id(dev); | ||
418 | |||
419 | reg = pmic->get_ctrl_reg(id); | ||
420 | if (reg < 0) | ||
421 | return reg; | ||
422 | |||
423 | value = tps65910_reg_read(pmic, reg); | ||
424 | if (value < 0) | ||
425 | return value; | ||
426 | |||
427 | return value & TPS65910_SUPPLY_STATE_ENABLED; | ||
428 | } | ||
429 | |||
430 | static int tps65910_enable(struct regulator_dev *dev) | ||
431 | { | ||
432 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
433 | struct tps65910 *mfd = pmic->mfd; | ||
434 | int reg, id = rdev_get_id(dev); | ||
435 | |||
436 | reg = pmic->get_ctrl_reg(id); | ||
437 | if (reg < 0) | ||
438 | return reg; | ||
439 | |||
440 | return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | ||
441 | } | ||
442 | |||
443 | static int tps65910_disable(struct regulator_dev *dev) | ||
444 | { | ||
445 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
446 | struct tps65910 *mfd = pmic->mfd; | ||
447 | int reg, id = rdev_get_id(dev); | ||
448 | |||
449 | reg = pmic->get_ctrl_reg(id); | ||
450 | if (reg < 0) | ||
451 | return reg; | ||
452 | |||
453 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | ||
454 | } | ||
455 | |||
456 | |||
457 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) | ||
458 | { | ||
459 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
460 | struct tps65910 *mfd = pmic->mfd; | ||
461 | int reg, value, id = rdev_get_id(dev); | ||
462 | |||
463 | reg = pmic->get_ctrl_reg(id); | ||
464 | if (reg < 0) | ||
465 | return reg; | ||
466 | |||
467 | switch (mode) { | ||
468 | case REGULATOR_MODE_NORMAL: | ||
469 | return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT, | ||
470 | LDO_ST_MODE_BIT); | ||
471 | case REGULATOR_MODE_IDLE: | ||
472 | value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; | ||
473 | return tps65910_set_bits(mfd, reg, value); | ||
474 | case REGULATOR_MODE_STANDBY: | ||
475 | return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT); | ||
476 | } | ||
477 | |||
478 | return -EINVAL; | ||
479 | } | ||
480 | |||
481 | static unsigned int tps65910_get_mode(struct regulator_dev *dev) | ||
482 | { | ||
483 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
484 | int reg, value, id = rdev_get_id(dev); | ||
485 | |||
486 | reg = pmic->get_ctrl_reg(id); | ||
487 | if (reg < 0) | ||
488 | return reg; | ||
489 | |||
490 | value = tps65910_reg_read(pmic, reg); | ||
491 | if (value < 0) | ||
492 | return value; | ||
493 | |||
494 | if (value & LDO_ST_ON_BIT) | ||
495 | return REGULATOR_MODE_STANDBY; | ||
496 | else if (value & LDO_ST_MODE_BIT) | ||
497 | return REGULATOR_MODE_IDLE; | ||
498 | else | ||
499 | return REGULATOR_MODE_NORMAL; | ||
500 | } | ||
501 | |||
502 | static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | ||
503 | { | ||
504 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
505 | int id = rdev_get_id(dev), voltage = 0; | ||
506 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; | ||
507 | |||
508 | switch (id) { | ||
509 | case TPS65910_REG_VDD1: | ||
510 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP); | ||
511 | mult = tps65910_reg_read(pmic, TPS65910_VDD1); | ||
512 | mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; | ||
513 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR); | ||
514 | sr = opvsel & VDD1_OP_CMD_MASK; | ||
515 | opvsel &= VDD1_OP_SEL_MASK; | ||
516 | srvsel &= VDD1_SR_SEL_MASK; | ||
517 | vselmax = 75; | ||
518 | break; | ||
519 | case TPS65910_REG_VDD2: | ||
520 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP); | ||
521 | mult = tps65910_reg_read(pmic, TPS65910_VDD2); | ||
522 | mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; | ||
523 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR); | ||
524 | sr = opvsel & VDD2_OP_CMD_MASK; | ||
525 | opvsel &= VDD2_OP_SEL_MASK; | ||
526 | srvsel &= VDD2_SR_SEL_MASK; | ||
527 | vselmax = 75; | ||
528 | break; | ||
529 | case TPS65911_REG_VDDCTRL: | ||
530 | opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP); | ||
531 | srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR); | ||
532 | sr = opvsel & VDDCTRL_OP_CMD_MASK; | ||
533 | opvsel &= VDDCTRL_OP_SEL_MASK; | ||
534 | srvsel &= VDDCTRL_SR_SEL_MASK; | ||
535 | vselmax = 64; | ||
536 | break; | ||
537 | } | ||
538 | |||
539 | /* multiplier 0 == 1 but 2,3 normal */ | ||
540 | if (!mult) | ||
541 | mult=1; | ||
542 | |||
543 | if (sr) { | ||
544 | /* normalise to valid range */ | ||
545 | if (srvsel < 3) | ||
546 | srvsel = 3; | ||
547 | if (srvsel > vselmax) | ||
548 | srvsel = vselmax; | ||
549 | srvsel -= 3; | ||
550 | |||
551 | voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
552 | } else { | ||
553 | |||
554 | /* normalise to valid range*/ | ||
555 | if (opvsel < 3) | ||
556 | opvsel = 3; | ||
557 | if (opvsel > vselmax) | ||
558 | opvsel = vselmax; | ||
559 | opvsel -= 3; | ||
560 | |||
561 | voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
562 | } | ||
563 | |||
564 | voltage *= mult; | ||
565 | |||
566 | return voltage; | ||
567 | } | ||
568 | |||
569 | static int tps65910_get_voltage(struct regulator_dev *dev) | ||
570 | { | ||
571 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
572 | int reg, value, id = rdev_get_id(dev), voltage = 0; | ||
573 | |||
574 | reg = pmic->get_ctrl_reg(id); | ||
575 | if (reg < 0) | ||
576 | return reg; | ||
577 | |||
578 | value = tps65910_reg_read(pmic, reg); | ||
579 | if (value < 0) | ||
580 | return value; | ||
581 | |||
582 | switch (id) { | ||
583 | case TPS65910_REG_VIO: | ||
584 | case TPS65910_REG_VDIG1: | ||
585 | case TPS65910_REG_VDIG2: | ||
586 | case TPS65910_REG_VPLL: | ||
587 | case TPS65910_REG_VDAC: | ||
588 | case TPS65910_REG_VAUX1: | ||
589 | case TPS65910_REG_VAUX2: | ||
590 | case TPS65910_REG_VAUX33: | ||
591 | case TPS65910_REG_VMMC: | ||
592 | value &= LDO_SEL_MASK; | ||
593 | value >>= LDO_SEL_SHIFT; | ||
594 | break; | ||
595 | default: | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | |||
599 | voltage = pmic->info[id]->table[value] * 1000; | ||
600 | |||
601 | return voltage; | ||
602 | } | ||
603 | |||
604 | static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) | ||
605 | { | ||
606 | return 5 * 1000 * 1000; | ||
607 | } | ||
608 | |||
609 | static int tps65911_get_voltage(struct regulator_dev *dev) | ||
610 | { | ||
611 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
612 | int step_mv, id = rdev_get_id(dev); | ||
613 | u8 value, reg; | ||
614 | |||
615 | reg = pmic->get_ctrl_reg(id); | ||
616 | |||
617 | value = tps65910_reg_read(pmic, reg); | ||
618 | |||
619 | switch (id) { | ||
620 | case TPS65911_REG_LDO1: | ||
621 | case TPS65911_REG_LDO2: | ||
622 | case TPS65911_REG_LDO4: | ||
623 | value &= LDO1_SEL_MASK; | ||
624 | value >>= LDO_SEL_SHIFT; | ||
625 | /* The first 5 values of the selector correspond to 1V */ | ||
626 | if (value < 5) | ||
627 | value = 0; | ||
628 | else | ||
629 | value -= 4; | ||
630 | |||
631 | step_mv = 50; | ||
632 | break; | ||
633 | case TPS65911_REG_LDO3: | ||
634 | case TPS65911_REG_LDO5: | ||
635 | case TPS65911_REG_LDO6: | ||
636 | case TPS65911_REG_LDO7: | ||
637 | case TPS65911_REG_LDO8: | ||
638 | value &= LDO3_SEL_MASK; | ||
639 | value >>= LDO_SEL_SHIFT; | ||
640 | /* The first 3 values of the selector correspond to 1V */ | ||
641 | if (value < 3) | ||
642 | value = 0; | ||
643 | else | ||
644 | value -= 2; | ||
645 | |||
646 | step_mv = 100; | ||
647 | break; | ||
648 | case TPS65910_REG_VIO: | ||
649 | return pmic->info[id]->table[value] * 1000; | ||
650 | break; | ||
651 | default: | ||
652 | return -EINVAL; | ||
653 | } | ||
654 | |||
655 | return (LDO_MIN_VOLT + value * step_mv) * 1000; | ||
656 | } | ||
657 | |||
658 | static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | ||
659 | unsigned selector) | ||
660 | { | ||
661 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
662 | int id = rdev_get_id(dev), vsel; | ||
663 | int dcdc_mult = 0; | ||
664 | |||
665 | switch (id) { | ||
666 | case TPS65910_REG_VDD1: | ||
667 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | ||
668 | if (dcdc_mult == 1) | ||
669 | dcdc_mult--; | ||
670 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | ||
671 | |||
672 | tps65910_modify_bits(pmic, TPS65910_VDD1, | ||
673 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), | ||
674 | VDD1_VGAIN_SEL_MASK); | ||
675 | tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); | ||
676 | break; | ||
677 | case TPS65910_REG_VDD2: | ||
678 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | ||
679 | if (dcdc_mult == 1) | ||
680 | dcdc_mult--; | ||
681 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | ||
682 | |||
683 | tps65910_modify_bits(pmic, TPS65910_VDD2, | ||
684 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), | ||
685 | VDD1_VGAIN_SEL_MASK); | ||
686 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); | ||
687 | break; | ||
688 | case TPS65911_REG_VDDCTRL: | ||
689 | vsel = selector; | ||
690 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); | ||
691 | } | ||
692 | |||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | ||
697 | { | ||
698 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
699 | int reg, id = rdev_get_id(dev); | ||
700 | |||
701 | reg = pmic->get_ctrl_reg(id); | ||
702 | if (reg < 0) | ||
703 | return reg; | ||
704 | |||
705 | switch (id) { | ||
706 | case TPS65910_REG_VIO: | ||
707 | case TPS65910_REG_VDIG1: | ||
708 | case TPS65910_REG_VDIG2: | ||
709 | case TPS65910_REG_VPLL: | ||
710 | case TPS65910_REG_VDAC: | ||
711 | case TPS65910_REG_VAUX1: | ||
712 | case TPS65910_REG_VAUX2: | ||
713 | case TPS65910_REG_VAUX33: | ||
714 | case TPS65910_REG_VMMC: | ||
715 | return tps65910_modify_bits(pmic, reg, | ||
716 | (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); | ||
717 | } | ||
718 | |||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
722 | static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) | ||
723 | { | ||
724 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
725 | int reg, id = rdev_get_id(dev); | ||
726 | |||
727 | reg = pmic->get_ctrl_reg(id); | ||
728 | if (reg < 0) | ||
729 | return reg; | ||
730 | |||
731 | switch (id) { | ||
732 | case TPS65911_REG_LDO1: | ||
733 | case TPS65911_REG_LDO2: | ||
734 | case TPS65911_REG_LDO4: | ||
735 | return tps65910_modify_bits(pmic, reg, | ||
736 | (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK); | ||
737 | case TPS65911_REG_LDO3: | ||
738 | case TPS65911_REG_LDO5: | ||
739 | case TPS65911_REG_LDO6: | ||
740 | case TPS65911_REG_LDO7: | ||
741 | case TPS65911_REG_LDO8: | ||
742 | case TPS65910_REG_VIO: | ||
743 | return tps65910_modify_bits(pmic, reg, | ||
744 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); | ||
745 | } | ||
746 | |||
747 | return -EINVAL; | ||
748 | } | ||
749 | |||
750 | |||
751 | static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, | ||
752 | unsigned selector) | ||
753 | { | ||
754 | int volt, mult = 1, id = rdev_get_id(dev); | ||
755 | |||
756 | switch (id) { | ||
757 | case TPS65910_REG_VDD1: | ||
758 | case TPS65910_REG_VDD2: | ||
759 | mult = (selector / VDD1_2_NUM_VOLTS) + 1; | ||
760 | volt = VDD1_2_MIN_VOLT + | ||
761 | (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; | ||
762 | case TPS65911_REG_VDDCTRL: | ||
763 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); | ||
764 | } | ||
765 | |||
766 | return volt * 100 * mult; | ||
767 | } | ||
768 | |||
769 | static int tps65910_list_voltage(struct regulator_dev *dev, | ||
770 | unsigned selector) | ||
771 | { | ||
772 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
773 | int id = rdev_get_id(dev), voltage; | ||
774 | |||
775 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) | ||
776 | return -EINVAL; | ||
777 | |||
778 | if (selector >= pmic->info[id]->table_len) | ||
779 | return -EINVAL; | ||
780 | else | ||
781 | voltage = pmic->info[id]->table[selector] * 1000; | ||
782 | |||
783 | return voltage; | ||
784 | } | ||
785 | |||
786 | static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) | ||
787 | { | ||
788 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
789 | int step_mv = 0, id = rdev_get_id(dev); | ||
790 | |||
791 | switch(id) { | ||
792 | case TPS65911_REG_LDO1: | ||
793 | case TPS65911_REG_LDO2: | ||
794 | case TPS65911_REG_LDO4: | ||
795 | /* The first 5 values of the selector correspond to 1V */ | ||
796 | if (selector < 5) | ||
797 | selector = 0; | ||
798 | else | ||
799 | selector -= 4; | ||
800 | |||
801 | step_mv = 50; | ||
802 | break; | ||
803 | case TPS65911_REG_LDO3: | ||
804 | case TPS65911_REG_LDO5: | ||
805 | case TPS65911_REG_LDO6: | ||
806 | case TPS65911_REG_LDO7: | ||
807 | case TPS65911_REG_LDO8: | ||
808 | /* The first 3 values of the selector correspond to 1V */ | ||
809 | if (selector < 3) | ||
810 | selector = 0; | ||
811 | else | ||
812 | selector -= 2; | ||
813 | |||
814 | step_mv = 100; | ||
815 | break; | ||
816 | case TPS65910_REG_VIO: | ||
817 | return pmic->info[id]->table[selector] * 1000; | ||
818 | default: | ||
819 | return -EINVAL; | ||
820 | } | ||
821 | |||
822 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; | ||
823 | } | ||
824 | |||
825 | /* Regulator ops (except VRTC) */ | ||
826 | static struct regulator_ops tps65910_ops_dcdc = { | ||
827 | .is_enabled = tps65910_is_enabled, | ||
828 | .enable = tps65910_enable, | ||
829 | .disable = tps65910_disable, | ||
830 | .set_mode = tps65910_set_mode, | ||
831 | .get_mode = tps65910_get_mode, | ||
832 | .get_voltage = tps65910_get_voltage_dcdc, | ||
833 | .set_voltage_sel = tps65910_set_voltage_dcdc, | ||
834 | .list_voltage = tps65910_list_voltage_dcdc, | ||
835 | }; | ||
836 | |||
837 | static struct regulator_ops tps65910_ops_vdd3 = { | ||
838 | .is_enabled = tps65910_is_enabled, | ||
839 | .enable = tps65910_enable, | ||
840 | .disable = tps65910_disable, | ||
841 | .set_mode = tps65910_set_mode, | ||
842 | .get_mode = tps65910_get_mode, | ||
843 | .get_voltage = tps65910_get_voltage_vdd3, | ||
844 | .list_voltage = tps65910_list_voltage, | ||
845 | }; | ||
846 | |||
847 | static struct regulator_ops tps65910_ops = { | ||
848 | .is_enabled = tps65910_is_enabled, | ||
849 | .enable = tps65910_enable, | ||
850 | .disable = tps65910_disable, | ||
851 | .set_mode = tps65910_set_mode, | ||
852 | .get_mode = tps65910_get_mode, | ||
853 | .get_voltage = tps65910_get_voltage, | ||
854 | .set_voltage_sel = tps65910_set_voltage, | ||
855 | .list_voltage = tps65910_list_voltage, | ||
856 | }; | ||
857 | |||
858 | static struct regulator_ops tps65911_ops = { | ||
859 | .is_enabled = tps65910_is_enabled, | ||
860 | .enable = tps65910_enable, | ||
861 | .disable = tps65910_disable, | ||
862 | .set_mode = tps65910_set_mode, | ||
863 | .get_mode = tps65910_get_mode, | ||
864 | .get_voltage = tps65911_get_voltage, | ||
865 | .set_voltage_sel = tps65911_set_voltage, | ||
866 | .list_voltage = tps65911_list_voltage, | ||
867 | }; | ||
868 | |||
869 | static __devinit int tps65910_probe(struct platform_device *pdev) | ||
870 | { | ||
871 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | ||
872 | struct tps_info *info; | ||
873 | struct regulator_init_data *reg_data; | ||
874 | struct regulator_dev *rdev; | ||
875 | struct tps65910_reg *pmic; | ||
876 | struct tps65910_board *pmic_plat_data; | ||
877 | int i, err; | ||
878 | |||
879 | pmic_plat_data = dev_get_platdata(tps65910->dev); | ||
880 | if (!pmic_plat_data) | ||
881 | return -EINVAL; | ||
882 | |||
883 | reg_data = pmic_plat_data->tps65910_pmic_init_data; | ||
884 | |||
885 | pmic = kzalloc(sizeof(*pmic), GFP_KERNEL); | ||
886 | if (!pmic) | ||
887 | return -ENOMEM; | ||
888 | |||
889 | mutex_init(&pmic->mutex); | ||
890 | pmic->mfd = tps65910; | ||
891 | platform_set_drvdata(pdev, pmic); | ||
892 | |||
893 | /* Give control of all register to control port */ | ||
894 | tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL, | ||
895 | DEVCTRL_SR_CTL_I2C_SEL_MASK); | ||
896 | |||
897 | switch(tps65910_chip_id(tps65910)) { | ||
898 | case TPS65910: | ||
899 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; | ||
900 | info = tps65910_regs; | ||
901 | case TPS65911: | ||
902 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; | ||
903 | info = tps65911_regs; | ||
904 | default: | ||
905 | pr_err("Invalid tps chip version\n"); | ||
906 | return -ENODEV; | ||
907 | } | ||
908 | |||
909 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { | ||
910 | /* Register the regulators */ | ||
911 | pmic->info[i] = info; | ||
912 | |||
913 | pmic->desc[i].name = info->name; | ||
914 | pmic->desc[i].id = i; | ||
915 | pmic->desc[i].n_voltages = info->table_len; | ||
916 | |||
917 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { | ||
918 | pmic->desc[i].ops = &tps65910_ops_dcdc; | ||
919 | } else if (i == TPS65910_REG_VDD3) { | ||
920 | if (tps65910_chip_id(tps65910) == TPS65910) | ||
921 | pmic->desc[i].ops = &tps65910_ops_vdd3; | ||
922 | else | ||
923 | pmic->desc[i].ops = &tps65910_ops_dcdc; | ||
924 | } else { | ||
925 | if (tps65910_chip_id(tps65910) == TPS65910) | ||
926 | pmic->desc[i].ops = &tps65910_ops; | ||
927 | else | ||
928 | pmic->desc[i].ops = &tps65911_ops; | ||
929 | } | ||
930 | |||
931 | pmic->desc[i].type = REGULATOR_VOLTAGE; | ||
932 | pmic->desc[i].owner = THIS_MODULE; | ||
933 | |||
934 | rdev = regulator_register(&pmic->desc[i], | ||
935 | tps65910->dev, reg_data, pmic); | ||
936 | if (IS_ERR(rdev)) { | ||
937 | dev_err(tps65910->dev, | ||
938 | "failed to register %s regulator\n", | ||
939 | pdev->name); | ||
940 | err = PTR_ERR(rdev); | ||
941 | goto err; | ||
942 | } | ||
943 | |||
944 | /* Save regulator for cleanup */ | ||
945 | pmic->rdev[i] = rdev; | ||
946 | } | ||
947 | return 0; | ||
948 | |||
949 | err: | ||
950 | while (--i >= 0) | ||
951 | regulator_unregister(pmic->rdev[i]); | ||
952 | |||
953 | kfree(pmic); | ||
954 | return err; | ||
955 | } | ||
956 | |||
957 | static int __devexit tps65910_remove(struct platform_device *pdev) | ||
958 | { | ||
959 | struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); | ||
960 | int i; | ||
961 | |||
962 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++) | ||
963 | regulator_unregister(tps65910_reg->rdev[i]); | ||
964 | |||
965 | kfree(tps65910_reg); | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static struct platform_driver tps65910_driver = { | ||
970 | .driver = { | ||
971 | .name = "tps65910-pmic", | ||
972 | .owner = THIS_MODULE, | ||
973 | }, | ||
974 | .probe = tps65910_probe, | ||
975 | .remove = __devexit_p(tps65910_remove), | ||
976 | }; | ||
977 | |||
978 | static int __init tps65910_init(void) | ||
979 | { | ||
980 | return platform_driver_register(&tps65910_driver); | ||
981 | } | ||
982 | subsys_initcall(tps65910_init); | ||
983 | |||
984 | static void __exit tps65910_cleanup(void) | ||
985 | { | ||
986 | platform_driver_unregister(&tps65910_driver); | ||
987 | } | ||
988 | module_exit(tps65910_cleanup); | ||
989 | |||
990 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | ||
991 | MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); | ||
992 | MODULE_LICENSE("GPL v2"); | ||
993 | MODULE_ALIAS("platform:tps65910-pmic"); | ||
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 6a292852a358..87fe0f75a56e 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -51,8 +51,13 @@ struct twlreg_info { | |||
51 | u16 min_mV; | 51 | u16 min_mV; |
52 | u16 max_mV; | 52 | u16 max_mV; |
53 | 53 | ||
54 | u8 flags; | ||
55 | |||
54 | /* used by regulator core */ | 56 | /* used by regulator core */ |
55 | struct regulator_desc desc; | 57 | struct regulator_desc desc; |
58 | |||
59 | /* chip specific features */ | ||
60 | unsigned long features; | ||
56 | }; | 61 | }; |
57 | 62 | ||
58 | 63 | ||
@@ -70,12 +75,35 @@ struct twlreg_info { | |||
70 | #define VREG_TRANS 1 | 75 | #define VREG_TRANS 1 |
71 | #define VREG_STATE 2 | 76 | #define VREG_STATE 2 |
72 | #define VREG_VOLTAGE 3 | 77 | #define VREG_VOLTAGE 3 |
78 | #define VREG_VOLTAGE_SMPS 4 | ||
73 | /* TWL6030 Misc register offsets */ | 79 | /* TWL6030 Misc register offsets */ |
74 | #define VREG_BC_ALL 1 | 80 | #define VREG_BC_ALL 1 |
75 | #define VREG_BC_REF 2 | 81 | #define VREG_BC_REF 2 |
76 | #define VREG_BC_PROC 3 | 82 | #define VREG_BC_PROC 3 |
77 | #define VREG_BC_CLK_RST 4 | 83 | #define VREG_BC_CLK_RST 4 |
78 | 84 | ||
85 | /* TWL6030 LDO register values for CFG_STATE */ | ||
86 | #define TWL6030_CFG_STATE_OFF 0x00 | ||
87 | #define TWL6030_CFG_STATE_ON 0x01 | ||
88 | #define TWL6030_CFG_STATE_OFF2 0x02 | ||
89 | #define TWL6030_CFG_STATE_SLEEP 0x03 | ||
90 | #define TWL6030_CFG_STATE_GRP_SHIFT 5 | ||
91 | #define TWL6030_CFG_STATE_APP_SHIFT 2 | ||
92 | #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT) | ||
93 | #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\ | ||
94 | TWL6030_CFG_STATE_APP_SHIFT) | ||
95 | |||
96 | /* Flags for SMPS Voltage reading */ | ||
97 | #define SMPS_OFFSET_EN BIT(0) | ||
98 | #define SMPS_EXTENDED_EN BIT(1) | ||
99 | |||
100 | /* twl6025 SMPS EPROM values */ | ||
101 | #define TWL6030_SMPS_OFFSET 0xB0 | ||
102 | #define TWL6030_SMPS_MULT 0xB3 | ||
103 | #define SMPS_MULTOFFSET_SMPS4 BIT(0) | ||
104 | #define SMPS_MULTOFFSET_VIO BIT(1) | ||
105 | #define SMPS_MULTOFFSET_SMPS3 BIT(6) | ||
106 | |||
79 | static inline int | 107 | static inline int |
80 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) | 108 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) |
81 | { | 109 | { |
@@ -118,21 +146,38 @@ static int twlreg_grp(struct regulator_dev *rdev) | |||
118 | #define P2_GRP_6030 BIT(1) /* "peripherals" */ | 146 | #define P2_GRP_6030 BIT(1) /* "peripherals" */ |
119 | #define P1_GRP_6030 BIT(0) /* CPU/Linux */ | 147 | #define P1_GRP_6030 BIT(0) /* CPU/Linux */ |
120 | 148 | ||
121 | static int twlreg_is_enabled(struct regulator_dev *rdev) | 149 | static int twl4030reg_is_enabled(struct regulator_dev *rdev) |
122 | { | 150 | { |
123 | int state = twlreg_grp(rdev); | 151 | int state = twlreg_grp(rdev); |
124 | 152 | ||
125 | if (state < 0) | 153 | if (state < 0) |
126 | return state; | 154 | return state; |
127 | 155 | ||
128 | if (twl_class_is_4030()) | 156 | return state & P1_GRP_4030; |
129 | state &= P1_GRP_4030; | 157 | } |
158 | |||
159 | static int twl6030reg_is_enabled(struct regulator_dev *rdev) | ||
160 | { | ||
161 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
162 | int grp = 0, val; | ||
163 | |||
164 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | ||
165 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); | ||
166 | if (grp < 0) | ||
167 | return grp; | ||
168 | |||
169 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | ||
170 | grp &= P1_GRP_6030; | ||
130 | else | 171 | else |
131 | state &= P1_GRP_6030; | 172 | grp = 1; |
132 | return state; | 173 | |
174 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); | ||
175 | val = TWL6030_CFG_STATE_APP(val); | ||
176 | |||
177 | return grp && (val == TWL6030_CFG_STATE_ON); | ||
133 | } | 178 | } |
134 | 179 | ||
135 | static int twlreg_enable(struct regulator_dev *rdev) | 180 | static int twl4030reg_enable(struct regulator_dev *rdev) |
136 | { | 181 | { |
137 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 182 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
138 | int grp; | 183 | int grp; |
@@ -142,10 +187,7 @@ static int twlreg_enable(struct regulator_dev *rdev) | |||
142 | if (grp < 0) | 187 | if (grp < 0) |
143 | return grp; | 188 | return grp; |
144 | 189 | ||
145 | if (twl_class_is_4030()) | 190 | grp |= P1_GRP_4030; |
146 | grp |= P1_GRP_4030; | ||
147 | else | ||
148 | grp |= P1_GRP_6030; | ||
149 | 191 | ||
150 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 192 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
151 | 193 | ||
@@ -154,29 +196,63 @@ static int twlreg_enable(struct regulator_dev *rdev) | |||
154 | return ret; | 196 | return ret; |
155 | } | 197 | } |
156 | 198 | ||
157 | static int twlreg_disable(struct regulator_dev *rdev) | 199 | static int twl6030reg_enable(struct regulator_dev *rdev) |
200 | { | ||
201 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
202 | int grp = 0; | ||
203 | int ret; | ||
204 | |||
205 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | ||
206 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); | ||
207 | if (grp < 0) | ||
208 | return grp; | ||
209 | |||
210 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | ||
211 | grp << TWL6030_CFG_STATE_GRP_SHIFT | | ||
212 | TWL6030_CFG_STATE_ON); | ||
213 | |||
214 | udelay(info->delay); | ||
215 | |||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static int twl4030reg_disable(struct regulator_dev *rdev) | ||
158 | { | 220 | { |
159 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 221 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
160 | int grp; | 222 | int grp; |
223 | int ret; | ||
161 | 224 | ||
162 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); | 225 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); |
163 | if (grp < 0) | 226 | if (grp < 0) |
164 | return grp; | 227 | return grp; |
165 | 228 | ||
166 | if (twl_class_is_4030()) | 229 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); |
167 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); | ||
168 | else | ||
169 | grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); | ||
170 | 230 | ||
171 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 231 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
232 | |||
233 | return ret; | ||
172 | } | 234 | } |
173 | 235 | ||
174 | static int twlreg_get_status(struct regulator_dev *rdev) | 236 | static int twl6030reg_disable(struct regulator_dev *rdev) |
175 | { | 237 | { |
176 | int state = twlreg_grp(rdev); | 238 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
239 | int grp = 0; | ||
240 | int ret; | ||
241 | |||
242 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | ||
243 | grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030; | ||
244 | |||
245 | /* For 6030, set the off state for all grps enabled */ | ||
246 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | ||
247 | (grp) << TWL6030_CFG_STATE_GRP_SHIFT | | ||
248 | TWL6030_CFG_STATE_OFF); | ||
249 | |||
250 | return ret; | ||
251 | } | ||
177 | 252 | ||
178 | if (twl_class_is_6030()) | 253 | static int twl4030reg_get_status(struct regulator_dev *rdev) |
179 | return 0; /* FIXME return for 6030 regulator */ | 254 | { |
255 | int state = twlreg_grp(rdev); | ||
180 | 256 | ||
181 | if (state < 0) | 257 | if (state < 0) |
182 | return state; | 258 | return state; |
@@ -190,15 +266,39 @@ static int twlreg_get_status(struct regulator_dev *rdev) | |||
190 | : REGULATOR_STATUS_STANDBY; | 266 | : REGULATOR_STATUS_STANDBY; |
191 | } | 267 | } |
192 | 268 | ||
193 | static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode) | 269 | static int twl6030reg_get_status(struct regulator_dev *rdev) |
270 | { | ||
271 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
272 | int val; | ||
273 | |||
274 | val = twlreg_grp(rdev); | ||
275 | if (val < 0) | ||
276 | return val; | ||
277 | |||
278 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); | ||
279 | |||
280 | switch (TWL6030_CFG_STATE_APP(val)) { | ||
281 | case TWL6030_CFG_STATE_ON: | ||
282 | return REGULATOR_STATUS_NORMAL; | ||
283 | |||
284 | case TWL6030_CFG_STATE_SLEEP: | ||
285 | return REGULATOR_STATUS_STANDBY; | ||
286 | |||
287 | case TWL6030_CFG_STATE_OFF: | ||
288 | case TWL6030_CFG_STATE_OFF2: | ||
289 | default: | ||
290 | break; | ||
291 | } | ||
292 | |||
293 | return REGULATOR_STATUS_OFF; | ||
294 | } | ||
295 | |||
296 | static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) | ||
194 | { | 297 | { |
195 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 298 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
196 | unsigned message; | 299 | unsigned message; |
197 | int status; | 300 | int status; |
198 | 301 | ||
199 | if (twl_class_is_6030()) | ||
200 | return 0; /* FIXME return for 6030 regulator */ | ||
201 | |||
202 | /* We can only set the mode through state machine commands... */ | 302 | /* We can only set the mode through state machine commands... */ |
203 | switch (mode) { | 303 | switch (mode) { |
204 | case REGULATOR_MODE_NORMAL: | 304 | case REGULATOR_MODE_NORMAL: |
@@ -227,6 +327,36 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode) | |||
227 | message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB); | 327 | message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB); |
228 | } | 328 | } |
229 | 329 | ||
330 | static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) | ||
331 | { | ||
332 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
333 | int grp = 0; | ||
334 | int val; | ||
335 | |||
336 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | ||
337 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); | ||
338 | |||
339 | if (grp < 0) | ||
340 | return grp; | ||
341 | |||
342 | /* Compose the state register settings */ | ||
343 | val = grp << TWL6030_CFG_STATE_GRP_SHIFT; | ||
344 | /* We can only set the mode through state machine commands... */ | ||
345 | switch (mode) { | ||
346 | case REGULATOR_MODE_NORMAL: | ||
347 | val |= TWL6030_CFG_STATE_ON; | ||
348 | break; | ||
349 | case REGULATOR_MODE_STANDBY: | ||
350 | val |= TWL6030_CFG_STATE_SLEEP; | ||
351 | break; | ||
352 | |||
353 | default: | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | |||
357 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val); | ||
358 | } | ||
359 | |||
230 | /*----------------------------------------------------------------------*/ | 360 | /*----------------------------------------------------------------------*/ |
231 | 361 | ||
232 | /* | 362 | /* |
@@ -375,13 +505,13 @@ static struct regulator_ops twl4030ldo_ops = { | |||
375 | .set_voltage = twl4030ldo_set_voltage, | 505 | .set_voltage = twl4030ldo_set_voltage, |
376 | .get_voltage = twl4030ldo_get_voltage, | 506 | .get_voltage = twl4030ldo_get_voltage, |
377 | 507 | ||
378 | .enable = twlreg_enable, | 508 | .enable = twl4030reg_enable, |
379 | .disable = twlreg_disable, | 509 | .disable = twl4030reg_disable, |
380 | .is_enabled = twlreg_is_enabled, | 510 | .is_enabled = twl4030reg_is_enabled, |
381 | 511 | ||
382 | .set_mode = twlreg_set_mode, | 512 | .set_mode = twl4030reg_set_mode, |
383 | 513 | ||
384 | .get_status = twlreg_get_status, | 514 | .get_status = twl4030reg_get_status, |
385 | }; | 515 | }; |
386 | 516 | ||
387 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | 517 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) |
@@ -433,13 +563,13 @@ static struct regulator_ops twl6030ldo_ops = { | |||
433 | .set_voltage = twl6030ldo_set_voltage, | 563 | .set_voltage = twl6030ldo_set_voltage, |
434 | .get_voltage = twl6030ldo_get_voltage, | 564 | .get_voltage = twl6030ldo_get_voltage, |
435 | 565 | ||
436 | .enable = twlreg_enable, | 566 | .enable = twl6030reg_enable, |
437 | .disable = twlreg_disable, | 567 | .disable = twl6030reg_disable, |
438 | .is_enabled = twlreg_is_enabled, | 568 | .is_enabled = twl6030reg_is_enabled, |
439 | 569 | ||
440 | .set_mode = twlreg_set_mode, | 570 | .set_mode = twl6030reg_set_mode, |
441 | 571 | ||
442 | .get_status = twlreg_get_status, | 572 | .get_status = twl6030reg_get_status, |
443 | }; | 573 | }; |
444 | 574 | ||
445 | /*----------------------------------------------------------------------*/ | 575 | /*----------------------------------------------------------------------*/ |
@@ -461,25 +591,242 @@ static int twlfixed_get_voltage(struct regulator_dev *rdev) | |||
461 | return info->min_mV * 1000; | 591 | return info->min_mV * 1000; |
462 | } | 592 | } |
463 | 593 | ||
464 | static struct regulator_ops twlfixed_ops = { | 594 | static struct regulator_ops twl4030fixed_ops = { |
595 | .list_voltage = twlfixed_list_voltage, | ||
596 | |||
597 | .get_voltage = twlfixed_get_voltage, | ||
598 | |||
599 | .enable = twl4030reg_enable, | ||
600 | .disable = twl4030reg_disable, | ||
601 | .is_enabled = twl4030reg_is_enabled, | ||
602 | |||
603 | .set_mode = twl4030reg_set_mode, | ||
604 | |||
605 | .get_status = twl4030reg_get_status, | ||
606 | }; | ||
607 | |||
608 | static struct regulator_ops twl6030fixed_ops = { | ||
465 | .list_voltage = twlfixed_list_voltage, | 609 | .list_voltage = twlfixed_list_voltage, |
466 | 610 | ||
467 | .get_voltage = twlfixed_get_voltage, | 611 | .get_voltage = twlfixed_get_voltage, |
468 | 612 | ||
469 | .enable = twlreg_enable, | 613 | .enable = twl6030reg_enable, |
470 | .disable = twlreg_disable, | 614 | .disable = twl6030reg_disable, |
471 | .is_enabled = twlreg_is_enabled, | 615 | .is_enabled = twl6030reg_is_enabled, |
472 | 616 | ||
473 | .set_mode = twlreg_set_mode, | 617 | .set_mode = twl6030reg_set_mode, |
474 | 618 | ||
475 | .get_status = twlreg_get_status, | 619 | .get_status = twl6030reg_get_status, |
476 | }; | 620 | }; |
477 | 621 | ||
478 | static struct regulator_ops twl6030_fixed_resource = { | 622 | static struct regulator_ops twl6030_fixed_resource = { |
479 | .enable = twlreg_enable, | 623 | .enable = twl6030reg_enable, |
480 | .disable = twlreg_disable, | 624 | .disable = twl6030reg_disable, |
481 | .is_enabled = twlreg_is_enabled, | 625 | .is_enabled = twl6030reg_is_enabled, |
482 | .get_status = twlreg_get_status, | 626 | .get_status = twl6030reg_get_status, |
627 | }; | ||
628 | |||
629 | /* | ||
630 | * SMPS status and control | ||
631 | */ | ||
632 | |||
633 | static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index) | ||
634 | { | ||
635 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
636 | |||
637 | int voltage = 0; | ||
638 | |||
639 | switch (info->flags) { | ||
640 | case SMPS_OFFSET_EN: | ||
641 | voltage = 100000; | ||
642 | /* fall through */ | ||
643 | case 0: | ||
644 | switch (index) { | ||
645 | case 0: | ||
646 | voltage = 0; | ||
647 | break; | ||
648 | case 58: | ||
649 | voltage = 1350 * 1000; | ||
650 | break; | ||
651 | case 59: | ||
652 | voltage = 1500 * 1000; | ||
653 | break; | ||
654 | case 60: | ||
655 | voltage = 1800 * 1000; | ||
656 | break; | ||
657 | case 61: | ||
658 | voltage = 1900 * 1000; | ||
659 | break; | ||
660 | case 62: | ||
661 | voltage = 2100 * 1000; | ||
662 | break; | ||
663 | default: | ||
664 | voltage += (600000 + (12500 * (index - 1))); | ||
665 | } | ||
666 | break; | ||
667 | case SMPS_EXTENDED_EN: | ||
668 | switch (index) { | ||
669 | case 0: | ||
670 | voltage = 0; | ||
671 | break; | ||
672 | case 58: | ||
673 | voltage = 2084 * 1000; | ||
674 | break; | ||
675 | case 59: | ||
676 | voltage = 2315 * 1000; | ||
677 | break; | ||
678 | case 60: | ||
679 | voltage = 2778 * 1000; | ||
680 | break; | ||
681 | case 61: | ||
682 | voltage = 2932 * 1000; | ||
683 | break; | ||
684 | case 62: | ||
685 | voltage = 3241 * 1000; | ||
686 | break; | ||
687 | default: | ||
688 | voltage = (1852000 + (38600 * (index - 1))); | ||
689 | } | ||
690 | break; | ||
691 | case SMPS_OFFSET_EN | SMPS_EXTENDED_EN: | ||
692 | switch (index) { | ||
693 | case 0: | ||
694 | voltage = 0; | ||
695 | break; | ||
696 | case 58: | ||
697 | voltage = 4167 * 1000; | ||
698 | break; | ||
699 | case 59: | ||
700 | voltage = 2315 * 1000; | ||
701 | break; | ||
702 | case 60: | ||
703 | voltage = 2778 * 1000; | ||
704 | break; | ||
705 | case 61: | ||
706 | voltage = 2932 * 1000; | ||
707 | break; | ||
708 | case 62: | ||
709 | voltage = 3241 * 1000; | ||
710 | break; | ||
711 | default: | ||
712 | voltage = (2161000 + (38600 * (index - 1))); | ||
713 | } | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | return voltage; | ||
718 | } | ||
719 | |||
720 | static int | ||
721 | twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | ||
722 | unsigned int *selector) | ||
723 | { | ||
724 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
725 | int vsel = 0; | ||
726 | |||
727 | switch (info->flags) { | ||
728 | case 0: | ||
729 | if (min_uV == 0) | ||
730 | vsel = 0; | ||
731 | else if ((min_uV >= 600000) && (max_uV <= 1300000)) { | ||
732 | vsel = (min_uV - 600000) / 125; | ||
733 | if (vsel % 100) | ||
734 | vsel += 100; | ||
735 | vsel /= 100; | ||
736 | vsel++; | ||
737 | } | ||
738 | /* Values 1..57 for vsel are linear and can be calculated | ||
739 | * values 58..62 are non linear. | ||
740 | */ | ||
741 | else if ((min_uV > 1900000) && (max_uV >= 2100000)) | ||
742 | vsel = 62; | ||
743 | else if ((min_uV > 1800000) && (max_uV >= 1900000)) | ||
744 | vsel = 61; | ||
745 | else if ((min_uV > 1500000) && (max_uV >= 1800000)) | ||
746 | vsel = 60; | ||
747 | else if ((min_uV > 1350000) && (max_uV >= 1500000)) | ||
748 | vsel = 59; | ||
749 | else if ((min_uV > 1300000) && (max_uV >= 1350000)) | ||
750 | vsel = 58; | ||
751 | else | ||
752 | return -EINVAL; | ||
753 | break; | ||
754 | case SMPS_OFFSET_EN: | ||
755 | if (min_uV == 0) | ||
756 | vsel = 0; | ||
757 | else if ((min_uV >= 700000) && (max_uV <= 1420000)) { | ||
758 | vsel = (min_uV - 700000) / 125; | ||
759 | if (vsel % 100) | ||
760 | vsel += 100; | ||
761 | vsel /= 100; | ||
762 | vsel++; | ||
763 | } | ||
764 | /* Values 1..57 for vsel are linear and can be calculated | ||
765 | * values 58..62 are non linear. | ||
766 | */ | ||
767 | else if ((min_uV > 1900000) && (max_uV >= 2100000)) | ||
768 | vsel = 62; | ||
769 | else if ((min_uV > 1800000) && (max_uV >= 1900000)) | ||
770 | vsel = 61; | ||
771 | else if ((min_uV > 1350000) && (max_uV >= 1800000)) | ||
772 | vsel = 60; | ||
773 | else if ((min_uV > 1350000) && (max_uV >= 1500000)) | ||
774 | vsel = 59; | ||
775 | else if ((min_uV > 1300000) && (max_uV >= 1350000)) | ||
776 | vsel = 58; | ||
777 | else | ||
778 | return -EINVAL; | ||
779 | break; | ||
780 | case SMPS_EXTENDED_EN: | ||
781 | if (min_uV == 0) | ||
782 | vsel = 0; | ||
783 | else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { | ||
784 | vsel = (min_uV - 1852000) / 386; | ||
785 | if (vsel % 100) | ||
786 | vsel += 100; | ||
787 | vsel /= 100; | ||
788 | vsel++; | ||
789 | } | ||
790 | break; | ||
791 | case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: | ||
792 | if (min_uV == 0) | ||
793 | vsel = 0; | ||
794 | else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { | ||
795 | vsel = (min_uV - 1852000) / 386; | ||
796 | if (vsel % 100) | ||
797 | vsel += 100; | ||
798 | vsel /= 100; | ||
799 | vsel++; | ||
800 | } | ||
801 | break; | ||
802 | } | ||
803 | |||
804 | *selector = vsel; | ||
805 | |||
806 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS, | ||
807 | vsel); | ||
808 | } | ||
809 | |||
810 | static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) | ||
811 | { | ||
812 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
813 | |||
814 | return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS); | ||
815 | } | ||
816 | |||
817 | static struct regulator_ops twlsmps_ops = { | ||
818 | .list_voltage = twl6030smps_list_voltage, | ||
819 | |||
820 | .set_voltage = twl6030smps_set_voltage, | ||
821 | .get_voltage_sel = twl6030smps_get_voltage_sel, | ||
822 | |||
823 | .enable = twl6030reg_enable, | ||
824 | .disable = twl6030reg_disable, | ||
825 | .is_enabled = twl6030reg_is_enabled, | ||
826 | |||
827 | .set_mode = twl6030reg_set_mode, | ||
828 | |||
829 | .get_status = twl6030reg_get_status, | ||
483 | }; | 830 | }; |
484 | 831 | ||
485 | /*----------------------------------------------------------------------*/ | 832 | /*----------------------------------------------------------------------*/ |
@@ -487,11 +834,10 @@ static struct regulator_ops twl6030_fixed_resource = { | |||
487 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 834 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
488 | remap_conf) \ | 835 | remap_conf) \ |
489 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 836 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
490 | remap_conf, TWL4030) | 837 | remap_conf, TWL4030, twl4030fixed_ops) |
491 | #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 838 | #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \ |
492 | remap_conf) \ | ||
493 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 839 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
494 | remap_conf, TWL6030) | 840 | 0x0, TWL6030, twl6030fixed_ops) |
495 | 841 | ||
496 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ | 842 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ |
497 | .base = offset, \ | 843 | .base = offset, \ |
@@ -510,13 +856,11 @@ static struct regulator_ops twl6030_fixed_resource = { | |||
510 | }, \ | 856 | }, \ |
511 | } | 857 | } |
512 | 858 | ||
513 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ | 859 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ |
514 | remap_conf) { \ | ||
515 | .base = offset, \ | 860 | .base = offset, \ |
516 | .id = num, \ | 861 | .id = num, \ |
517 | .min_mV = min_mVolts, \ | 862 | .min_mV = min_mVolts, \ |
518 | .max_mV = max_mVolts, \ | 863 | .max_mV = max_mVolts, \ |
519 | .remap = remap_conf, \ | ||
520 | .desc = { \ | 864 | .desc = { \ |
521 | .name = #label, \ | 865 | .name = #label, \ |
522 | .id = TWL6030_REG_##label, \ | 866 | .id = TWL6030_REG_##label, \ |
@@ -527,9 +871,23 @@ static struct regulator_ops twl6030_fixed_resource = { | |||
527 | }, \ | 871 | }, \ |
528 | } | 872 | } |
529 | 873 | ||
874 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ | ||
875 | .base = offset, \ | ||
876 | .id = num, \ | ||
877 | .min_mV = min_mVolts, \ | ||
878 | .max_mV = max_mVolts, \ | ||
879 | .desc = { \ | ||
880 | .name = #label, \ | ||
881 | .id = TWL6025_REG_##label, \ | ||
882 | .n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \ | ||
883 | .ops = &twl6030ldo_ops, \ | ||
884 | .type = REGULATOR_VOLTAGE, \ | ||
885 | .owner = THIS_MODULE, \ | ||
886 | }, \ | ||
887 | } | ||
530 | 888 | ||
531 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ | 889 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ |
532 | family) { \ | 890 | family, operations) { \ |
533 | .base = offset, \ | 891 | .base = offset, \ |
534 | .id = num, \ | 892 | .id = num, \ |
535 | .min_mV = mVolts, \ | 893 | .min_mV = mVolts, \ |
@@ -539,17 +897,16 @@ static struct regulator_ops twl6030_fixed_resource = { | |||
539 | .name = #label, \ | 897 | .name = #label, \ |
540 | .id = family##_REG_##label, \ | 898 | .id = family##_REG_##label, \ |
541 | .n_voltages = 1, \ | 899 | .n_voltages = 1, \ |
542 | .ops = &twlfixed_ops, \ | 900 | .ops = &operations, \ |
543 | .type = REGULATOR_VOLTAGE, \ | 901 | .type = REGULATOR_VOLTAGE, \ |
544 | .owner = THIS_MODULE, \ | 902 | .owner = THIS_MODULE, \ |
545 | }, \ | 903 | }, \ |
546 | } | 904 | } |
547 | 905 | ||
548 | #define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \ | 906 | #define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \ |
549 | .base = offset, \ | 907 | .base = offset, \ |
550 | .id = num, \ | 908 | .id = num, \ |
551 | .delay = turnon_delay, \ | 909 | .delay = turnon_delay, \ |
552 | .remap = remap_conf, \ | ||
553 | .desc = { \ | 910 | .desc = { \ |
554 | .name = #label, \ | 911 | .name = #label, \ |
555 | .id = TWL6030_REG_##label, \ | 912 | .id = TWL6030_REG_##label, \ |
@@ -559,6 +916,21 @@ static struct regulator_ops twl6030_fixed_resource = { | |||
559 | }, \ | 916 | }, \ |
560 | } | 917 | } |
561 | 918 | ||
919 | #define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \ | ||
920 | .base = offset, \ | ||
921 | .id = num, \ | ||
922 | .min_mV = 600, \ | ||
923 | .max_mV = 2100, \ | ||
924 | .desc = { \ | ||
925 | .name = #label, \ | ||
926 | .id = TWL6025_REG_##label, \ | ||
927 | .n_voltages = 63, \ | ||
928 | .ops = &twlsmps_ops, \ | ||
929 | .type = REGULATOR_VOLTAGE, \ | ||
930 | .owner = THIS_MODULE, \ | ||
931 | }, \ | ||
932 | } | ||
933 | |||
562 | /* | 934 | /* |
563 | * We list regulators here if systems need some level of | 935 | * We list regulators here if systems need some level of |
564 | * software control over them after boot. | 936 | * software control over them after boot. |
@@ -589,19 +961,52 @@ static struct twlreg_info twl_regs[] = { | |||
589 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ | 961 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ |
590 | /* Turnon-delay and remap configuration values for 6030 are not | 962 | /* Turnon-delay and remap configuration values for 6030 are not |
591 | verified since the specification is not public */ | 963 | verified since the specification is not public */ |
592 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21), | 964 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1), |
593 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21), | 965 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2), |
594 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21), | 966 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3), |
595 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21), | 967 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4), |
596 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21), | 968 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5), |
597 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21), | 969 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7), |
598 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), | 970 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0), |
599 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), | 971 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0), |
600 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), | 972 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0), |
601 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21), | 973 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0), |
602 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21), | 974 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0), |
975 | |||
976 | /* 6025 are renamed compared to 6030 versions */ | ||
977 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1), | ||
978 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2), | ||
979 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3), | ||
980 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4), | ||
981 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5), | ||
982 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7), | ||
983 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16), | ||
984 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17), | ||
985 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18), | ||
986 | |||
987 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1), | ||
988 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2), | ||
989 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3), | ||
603 | }; | 990 | }; |
604 | 991 | ||
992 | static u8 twl_get_smps_offset(void) | ||
993 | { | ||
994 | u8 value; | ||
995 | |||
996 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, | ||
997 | TWL6030_SMPS_OFFSET); | ||
998 | return value; | ||
999 | } | ||
1000 | |||
1001 | static u8 twl_get_smps_mult(void) | ||
1002 | { | ||
1003 | u8 value; | ||
1004 | |||
1005 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, | ||
1006 | TWL6030_SMPS_MULT); | ||
1007 | return value; | ||
1008 | } | ||
1009 | |||
605 | static int __devinit twlreg_probe(struct platform_device *pdev) | 1010 | static int __devinit twlreg_probe(struct platform_device *pdev) |
606 | { | 1011 | { |
607 | int i; | 1012 | int i; |
@@ -623,6 +1028,9 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
623 | if (!initdata) | 1028 | if (!initdata) |
624 | return -EINVAL; | 1029 | return -EINVAL; |
625 | 1030 | ||
1031 | /* copy the features into regulator data */ | ||
1032 | info->features = (unsigned long)initdata->driver_data; | ||
1033 | |||
626 | /* Constrain board-specific capabilities according to what | 1034 | /* Constrain board-specific capabilities according to what |
627 | * this driver and the chip itself can actually do. | 1035 | * this driver and the chip itself can actually do. |
628 | */ | 1036 | */ |
@@ -645,6 +1053,27 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
645 | break; | 1053 | break; |
646 | } | 1054 | } |
647 | 1055 | ||
1056 | switch (pdev->id) { | ||
1057 | case TWL6025_REG_SMPS3: | ||
1058 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) | ||
1059 | info->flags |= SMPS_EXTENDED_EN; | ||
1060 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) | ||
1061 | info->flags |= SMPS_OFFSET_EN; | ||
1062 | break; | ||
1063 | case TWL6025_REG_SMPS4: | ||
1064 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) | ||
1065 | info->flags |= SMPS_EXTENDED_EN; | ||
1066 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) | ||
1067 | info->flags |= SMPS_OFFSET_EN; | ||
1068 | break; | ||
1069 | case TWL6025_REG_VIO: | ||
1070 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) | ||
1071 | info->flags |= SMPS_EXTENDED_EN; | ||
1072 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) | ||
1073 | info->flags |= SMPS_OFFSET_EN; | ||
1074 | break; | ||
1075 | } | ||
1076 | |||
648 | rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); | 1077 | rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); |
649 | if (IS_ERR(rdev)) { | 1078 | if (IS_ERR(rdev)) { |
650 | dev_err(&pdev->dev, "can't register %s, %ld\n", | 1079 | dev_err(&pdev->dev, "can't register %s, %ld\n", |
@@ -653,7 +1082,8 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
653 | } | 1082 | } |
654 | platform_set_drvdata(pdev, rdev); | 1083 | platform_set_drvdata(pdev, rdev); |
655 | 1084 | ||
656 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, | 1085 | if (twl_class_is_4030()) |
1086 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, | ||
657 | info->remap); | 1087 | info->remap); |
658 | 1088 | ||
659 | /* NOTE: many regulators support short-circuit IRQs (presentable | 1089 | /* NOTE: many regulators support short-circuit IRQs (presentable |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index e93453b1b978..a0982e809851 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -600,7 +600,6 @@ err: | |||
600 | static __devexit int wm831x_buckv_remove(struct platform_device *pdev) | 600 | static __devexit int wm831x_buckv_remove(struct platform_device *pdev) |
601 | { | 601 | { |
602 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); | 602 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); |
603 | struct wm831x *wm831x = dcdc->wm831x; | ||
604 | 603 | ||
605 | platform_set_drvdata(pdev, NULL); | 604 | platform_set_drvdata(pdev, NULL); |
606 | 605 | ||
@@ -776,7 +775,6 @@ err: | |||
776 | static __devexit int wm831x_buckp_remove(struct platform_device *pdev) | 775 | static __devexit int wm831x_buckp_remove(struct platform_device *pdev) |
777 | { | 776 | { |
778 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); | 777 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); |
779 | struct wm831x *wm831x = dcdc->wm831x; | ||
780 | 778 | ||
781 | platform_set_drvdata(pdev, NULL); | 779 | platform_set_drvdata(pdev, NULL); |
782 | 780 | ||
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index b42d01cef35a..0f12c70bebc9 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c | |||
@@ -55,7 +55,7 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev, | |||
55 | return 1600000 + ((selector - 14) * 100000); | 55 | return 1600000 + ((selector - 14) * 100000); |
56 | } | 56 | } |
57 | 57 | ||
58 | static int wm8400_ldo_get_voltage(struct regulator_dev *dev) | 58 | static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev) |
59 | { | 59 | { |
60 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); | 60 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); |
61 | u16 val; | 61 | u16 val; |
@@ -63,7 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev) | |||
63 | val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); | 63 | val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); |
64 | val &= WM8400_LDO1_VSEL_MASK; | 64 | val &= WM8400_LDO1_VSEL_MASK; |
65 | 65 | ||
66 | return wm8400_ldo_list_voltage(dev, val); | 66 | return val; |
67 | } | 67 | } |
68 | 68 | ||
69 | static int wm8400_ldo_set_voltage(struct regulator_dev *dev, | 69 | static int wm8400_ldo_set_voltage(struct regulator_dev *dev, |
@@ -104,7 +104,7 @@ static struct regulator_ops wm8400_ldo_ops = { | |||
104 | .enable = wm8400_ldo_enable, | 104 | .enable = wm8400_ldo_enable, |
105 | .disable = wm8400_ldo_disable, | 105 | .disable = wm8400_ldo_disable, |
106 | .list_voltage = wm8400_ldo_list_voltage, | 106 | .list_voltage = wm8400_ldo_list_voltage, |
107 | .get_voltage = wm8400_ldo_get_voltage, | 107 | .get_voltage_sel = wm8400_ldo_get_voltage_sel, |
108 | .set_voltage = wm8400_ldo_set_voltage, | 108 | .set_voltage = wm8400_ldo_set_voltage, |
109 | }; | 109 | }; |
110 | 110 | ||
@@ -145,7 +145,7 @@ static int wm8400_dcdc_list_voltage(struct regulator_dev *dev, | |||
145 | return 850000 + (selector * 25000); | 145 | return 850000 + (selector * 25000); |
146 | } | 146 | } |
147 | 147 | ||
148 | static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) | 148 | static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev) |
149 | { | 149 | { |
150 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); | 150 | struct wm8400 *wm8400 = rdev_get_drvdata(dev); |
151 | u16 val; | 151 | u16 val; |
@@ -154,7 +154,7 @@ static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) | |||
154 | val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); | 154 | val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); |
155 | val &= WM8400_DC1_VSEL_MASK; | 155 | val &= WM8400_DC1_VSEL_MASK; |
156 | 156 | ||
157 | return 850000 + (25000 * val); | 157 | return val; |
158 | } | 158 | } |
159 | 159 | ||
160 | static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, | 160 | static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, |
@@ -261,7 +261,7 @@ static struct regulator_ops wm8400_dcdc_ops = { | |||
261 | .enable = wm8400_dcdc_enable, | 261 | .enable = wm8400_dcdc_enable, |
262 | .disable = wm8400_dcdc_disable, | 262 | .disable = wm8400_dcdc_disable, |
263 | .list_voltage = wm8400_dcdc_list_voltage, | 263 | .list_voltage = wm8400_dcdc_list_voltage, |
264 | .get_voltage = wm8400_dcdc_get_voltage, | 264 | .get_voltage_sel = wm8400_dcdc_get_voltage_sel, |
265 | .set_voltage = wm8400_dcdc_set_voltage, | 265 | .set_voltage = wm8400_dcdc_set_voltage, |
266 | .get_mode = wm8400_dcdc_get_mode, | 266 | .get_mode = wm8400_dcdc_get_mode, |
267 | .set_mode = wm8400_dcdc_set_mode, | 267 | .set_mode = wm8400_dcdc_set_mode, |