diff options
Diffstat (limited to 'drivers/regulator')
32 files changed, 1363 insertions, 518 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 9bc774904631..e98a5e7827df 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -109,6 +109,17 @@ config REGULATOR_DA9052 | |||
109 | This driver supports the voltage regulators of DA9052-BC and | 109 | This driver supports the voltage regulators of DA9052-BC and |
110 | DA9053-AA/Bx PMIC. | 110 | DA9053-AA/Bx PMIC. |
111 | 111 | ||
112 | config REGULATOR_FAN53555 | ||
113 | tristate "Fairchild FAN53555 Regulator" | ||
114 | depends on I2C | ||
115 | select REGMAP_I2C | ||
116 | help | ||
117 | This driver supports Fairchild FAN53555 Digitally Programmable | ||
118 | TinyBuck Regulator. The FAN53555 is a step-down switching voltage | ||
119 | regulator that delivers a digitally programmable output from an | ||
120 | input voltage supply of 2.5V to 5.5V. The output voltage is | ||
121 | programmed through an I2C interface. | ||
122 | |||
112 | config REGULATOR_ANATOP | 123 | config REGULATOR_ANATOP |
113 | tristate "Freescale i.MX on-chip ANATOP LDO regulators" | 124 | tristate "Freescale i.MX on-chip ANATOP LDO regulators" |
114 | depends on MFD_ANATOP | 125 | depends on MFD_ANATOP |
@@ -171,6 +182,14 @@ config REGULATOR_MAX8660 | |||
171 | This driver controls a Maxim 8660/8661 voltage output | 182 | This driver controls a Maxim 8660/8661 voltage output |
172 | regulator via I2C bus. | 183 | regulator via I2C bus. |
173 | 184 | ||
185 | config REGULATOR_MAX8907 | ||
186 | tristate "Maxim 8907 voltage regulator" | ||
187 | depends on MFD_MAX8907 | ||
188 | help | ||
189 | This driver controls a Maxim 8907 voltage output regulator | ||
190 | via I2C bus. The provided regulator is suitable for Tegra | ||
191 | chip to control Step-Down DC-DC and LDOs. | ||
192 | |||
174 | config REGULATOR_MAX8925 | 193 | config REGULATOR_MAX8925 |
175 | tristate "Maxim MAX8925 Power Management IC" | 194 | tristate "Maxim MAX8925 Power Management IC" |
176 | depends on MFD_MAX8925 | 195 | depends on MFD_MAX8925 |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 3342615cf25e..e431eed8a878 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | |||
20 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 20 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
21 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | 21 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o |
22 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | 22 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o |
23 | obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o | ||
23 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o | 24 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o |
24 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | 25 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
25 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o | 26 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o |
@@ -30,6 +31,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o | |||
30 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o | 31 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o |
31 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 32 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
32 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o | 33 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o |
34 | obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o | ||
33 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o | 35 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o |
34 | obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o | 36 | obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o |
35 | obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o | 37 | obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o |
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 6f45bfd22e83..167c93f21981 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c | |||
@@ -162,7 +162,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id) | |||
162 | static int aat2870_regulator_probe(struct platform_device *pdev) | 162 | static int aat2870_regulator_probe(struct platform_device *pdev) |
163 | { | 163 | { |
164 | struct aat2870_regulator *ri; | 164 | struct aat2870_regulator *ri; |
165 | struct regulator_config config = { 0 }; | 165 | struct regulator_config config = { }; |
166 | struct regulator_dev *rdev; | 166 | struct regulator_dev *rdev; |
167 | 167 | ||
168 | ri = aat2870_get_regulator(pdev->id); | 168 | ri = aat2870_get_regulator(pdev->id); |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 182b553059c9..65ad2b36ce36 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -347,17 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) | |||
347 | return abreg->plfdata->external_voltage; | 347 | return abreg->plfdata->external_voltage; |
348 | } | 348 | } |
349 | 349 | ||
350 | static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg) | ||
351 | { | ||
352 | return reg->desc->min_uV; | ||
353 | } | ||
354 | |||
355 | static struct regulator_ops regulator_ops_fixed = { | 350 | static struct regulator_ops regulator_ops_fixed = { |
356 | .list_voltage = regulator_list_voltage_linear, | 351 | .list_voltage = regulator_list_voltage_linear, |
357 | .enable = ab3100_enable_regulator, | 352 | .enable = ab3100_enable_regulator, |
358 | .disable = ab3100_disable_regulator, | 353 | .disable = ab3100_disable_regulator, |
359 | .is_enabled = ab3100_is_enabled_regulator, | 354 | .is_enabled = ab3100_is_enabled_regulator, |
360 | .get_voltage = ab3100_get_fixed_voltage_regulator, | ||
361 | }; | 355 | }; |
362 | 356 | ||
363 | static struct regulator_ops regulator_ops_variable = { | 357 | static struct regulator_ops regulator_ops_variable = { |
@@ -486,6 +480,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { | |||
486 | .id = AB3100_BUCK, | 480 | .id = AB3100_BUCK, |
487 | .ops = ®ulator_ops_variable_sleepable, | 481 | .ops = ®ulator_ops_variable_sleepable, |
488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), | 482 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), |
483 | .volt_table = ldo_e_buck_typ_voltages, | ||
489 | .type = REGULATOR_VOLTAGE, | 484 | .type = REGULATOR_VOLTAGE, |
490 | .owner = THIS_MODULE, | 485 | .owner = THIS_MODULE, |
491 | .enable_time = 1000, | 486 | .enable_time = 1000, |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 10f2f4d4d190..e3d1d063025a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -37,6 +37,7 @@ | |||
37 | * @voltage_bank: bank to control regulator voltage | 37 | * @voltage_bank: bank to control regulator voltage |
38 | * @voltage_reg: register to control regulator voltage | 38 | * @voltage_reg: register to control regulator voltage |
39 | * @voltage_mask: mask to control regulator voltage | 39 | * @voltage_mask: mask to control regulator voltage |
40 | * @voltage_shift: shift to control regulator voltage | ||
40 | * @delay: startup/set voltage delay in us | 41 | * @delay: startup/set voltage delay in us |
41 | */ | 42 | */ |
42 | struct ab8500_regulator_info { | 43 | struct ab8500_regulator_info { |
@@ -50,6 +51,7 @@ struct ab8500_regulator_info { | |||
50 | u8 voltage_bank; | 51 | u8 voltage_bank; |
51 | u8 voltage_reg; | 52 | u8 voltage_reg; |
52 | u8 voltage_mask; | 53 | u8 voltage_mask; |
54 | u8 voltage_shift; | ||
53 | unsigned int delay; | 55 | unsigned int delay; |
54 | }; | 56 | }; |
55 | 57 | ||
@@ -195,17 +197,14 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) | |||
195 | } | 197 | } |
196 | 198 | ||
197 | dev_vdbg(rdev_get_dev(rdev), | 199 | dev_vdbg(rdev_get_dev(rdev), |
198 | "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," | 200 | "%s-get_voltage (bank, reg, mask, shift, value): " |
199 | " 0x%x\n", | 201 | "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", |
200 | info->desc.name, info->voltage_bank, info->voltage_reg, | 202 | info->desc.name, info->voltage_bank, |
201 | info->voltage_mask, regval); | 203 | info->voltage_reg, info->voltage_mask, |
204 | info->voltage_shift, regval); | ||
202 | 205 | ||
203 | /* vintcore has a different layout */ | ||
204 | val = regval & info->voltage_mask; | 206 | val = regval & info->voltage_mask; |
205 | if (info->desc.id == AB8500_LDO_INTCORE) | 207 | return val >> info->voltage_shift; |
206 | return val >> 0x3; | ||
207 | else | ||
208 | return val; | ||
209 | } | 208 | } |
210 | 209 | ||
211 | static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, | 210 | static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, |
@@ -221,7 +220,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
221 | } | 220 | } |
222 | 221 | ||
223 | /* set the registers for the request */ | 222 | /* set the registers for the request */ |
224 | regval = (u8)selector; | 223 | regval = (u8)selector << info->voltage_shift; |
225 | ret = abx500_mask_and_set_register_interruptible(info->dev, | 224 | ret = abx500_mask_and_set_register_interruptible(info->dev, |
226 | info->voltage_bank, info->voltage_reg, | 225 | info->voltage_bank, info->voltage_reg, |
227 | info->voltage_mask, regval); | 226 | info->voltage_mask, regval); |
@@ -238,13 +237,6 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
238 | return ret; | 237 | return ret; |
239 | } | 238 | } |
240 | 239 | ||
241 | static int ab8500_regulator_enable_time(struct regulator_dev *rdev) | ||
242 | { | ||
243 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
244 | |||
245 | return info->delay; | ||
246 | } | ||
247 | |||
248 | static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | 240 | static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, |
249 | unsigned int old_sel, | 241 | unsigned int old_sel, |
250 | unsigned int new_sel) | 242 | unsigned int new_sel) |
@@ -261,22 +253,14 @@ static struct regulator_ops ab8500_regulator_ops = { | |||
261 | .get_voltage_sel = ab8500_regulator_get_voltage_sel, | 253 | .get_voltage_sel = ab8500_regulator_get_voltage_sel, |
262 | .set_voltage_sel = ab8500_regulator_set_voltage_sel, | 254 | .set_voltage_sel = ab8500_regulator_set_voltage_sel, |
263 | .list_voltage = regulator_list_voltage_table, | 255 | .list_voltage = regulator_list_voltage_table, |
264 | .enable_time = ab8500_regulator_enable_time, | ||
265 | .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, | 256 | .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, |
266 | }; | 257 | }; |
267 | 258 | ||
268 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) | ||
269 | { | ||
270 | return rdev->desc->min_uV; | ||
271 | } | ||
272 | |||
273 | static struct regulator_ops ab8500_regulator_fixed_ops = { | 259 | static struct regulator_ops ab8500_regulator_fixed_ops = { |
274 | .enable = ab8500_regulator_enable, | 260 | .enable = ab8500_regulator_enable, |
275 | .disable = ab8500_regulator_disable, | 261 | .disable = ab8500_regulator_disable, |
276 | .is_enabled = ab8500_regulator_is_enabled, | 262 | .is_enabled = ab8500_regulator_is_enabled, |
277 | .get_voltage = ab8500_fixed_get_voltage, | ||
278 | .list_voltage = regulator_list_voltage_linear, | 263 | .list_voltage = regulator_list_voltage_linear, |
279 | .enable_time = ab8500_regulator_enable_time, | ||
280 | }; | 264 | }; |
281 | 265 | ||
282 | static struct ab8500_regulator_info | 266 | static struct ab8500_regulator_info |
@@ -358,6 +342,7 @@ static struct ab8500_regulator_info | |||
358 | .voltage_bank = 0x03, | 342 | .voltage_bank = 0x03, |
359 | .voltage_reg = 0x80, | 343 | .voltage_reg = 0x80, |
360 | .voltage_mask = 0x38, | 344 | .voltage_mask = 0x38, |
345 | .voltage_shift = 3, | ||
361 | }, | 346 | }, |
362 | 347 | ||
363 | /* | 348 | /* |
@@ -374,6 +359,7 @@ static struct ab8500_regulator_info | |||
374 | .owner = THIS_MODULE, | 359 | .owner = THIS_MODULE, |
375 | .n_voltages = 1, | 360 | .n_voltages = 1, |
376 | .min_uV = 2000000, | 361 | .min_uV = 2000000, |
362 | .enable_time = 10000, | ||
377 | }, | 363 | }, |
378 | .delay = 10000, | 364 | .delay = 10000, |
379 | .update_bank = 0x03, | 365 | .update_bank = 0x03, |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..ce0fe72a428e 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -64,14 +64,15 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) | |||
64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) | 64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) |
65 | { | 65 | { |
66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
67 | u32 val; | 67 | u32 val, mask; |
68 | 68 | ||
69 | if (!anatop_reg->control_reg) | 69 | if (!anatop_reg->control_reg) |
70 | return -ENOTSUPP; | 70 | return -ENOTSUPP; |
71 | 71 | ||
72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); | 72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); |
73 | val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> | 73 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << |
74 | anatop_reg->vol_bit_shift; | 74 | anatop_reg->vol_bit_shift; |
75 | val = (val & mask) >> anatop_reg->vol_bit_shift; | ||
75 | 76 | ||
76 | return val - anatop_reg->min_bit_val; | 77 | return val - anatop_reg->min_bit_val; |
77 | } | 78 | } |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index c8f95c07adb6..d184aa35abcb 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
@@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = { | |||
39 | .map_voltage = regulator_map_voltage_linear, | 39 | .map_voltage = regulator_map_voltage_linear, |
40 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 40 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
41 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 41 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
42 | .get_bypass = regulator_get_bypass_regmap, | ||
43 | .set_bypass = regulator_set_bypass_regmap, | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | static const struct regulator_desc arizona_ldo1 = { | 46 | static const struct regulator_desc arizona_ldo1 = { |
@@ -49,9 +51,11 @@ static const struct regulator_desc arizona_ldo1 = { | |||
49 | 51 | ||
50 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, | 52 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, |
51 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, | 53 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, |
54 | .bypass_reg = ARIZONA_LDO1_CONTROL_1, | ||
55 | .bypass_mask = ARIZONA_LDO1_BYPASS, | ||
52 | .min_uV = 900000, | 56 | .min_uV = 900000, |
53 | .uV_step = 50000, | 57 | .uV_step = 50000, |
54 | .n_voltages = 7, | 58 | .n_voltages = 6, |
55 | 59 | ||
56 | .owner = THIS_MODULE, | 60 | .owner = THIS_MODULE, |
57 | }; | 61 | }; |
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 450a069aa9b6..d9b1f82cc5bd 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c | |||
@@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = { | |||
82 | 82 | ||
83 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 83 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
84 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 84 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
85 | |||
86 | .get_bypass = regulator_get_bypass_regmap, | ||
87 | .set_bypass = regulator_set_bypass_regmap, | ||
85 | }; | 88 | }; |
86 | 89 | ||
87 | static const struct regulator_desc arizona_micsupp = { | 90 | static const struct regulator_desc arizona_micsupp = { |
@@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = { | |||
95 | .vsel_mask = ARIZONA_LDO2_VSEL_MASK, | 98 | .vsel_mask = ARIZONA_LDO2_VSEL_MASK, |
96 | .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, | 99 | .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1, |
97 | .enable_mask = ARIZONA_CPMIC_ENA, | 100 | .enable_mask = ARIZONA_CPMIC_ENA, |
101 | .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, | ||
102 | .bypass_mask = ARIZONA_CPMIC_BYPASS, | ||
98 | 103 | ||
99 | .owner = THIS_MODULE, | 104 | .owner = THIS_MODULE, |
100 | }; | 105 | }; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 03fad8153476..2e0352dc26bd 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -77,6 +77,7 @@ struct regulator { | |||
77 | struct device *dev; | 77 | struct device *dev; |
78 | struct list_head list; | 78 | struct list_head list; |
79 | unsigned int always_on:1; | 79 | unsigned int always_on:1; |
80 | unsigned int bypass:1; | ||
80 | int uA_load; | 81 | int uA_load; |
81 | int min_uV; | 82 | int min_uV; |
82 | int max_uV; | 83 | int max_uV; |
@@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev, | |||
394 | case REGULATOR_STATUS_STANDBY: | 395 | case REGULATOR_STATUS_STANDBY: |
395 | label = "standby"; | 396 | label = "standby"; |
396 | break; | 397 | break; |
398 | case REGULATOR_STATUS_BYPASS: | ||
399 | label = "bypass"; | ||
400 | break; | ||
397 | case REGULATOR_STATUS_UNDEFINED: | 401 | case REGULATOR_STATUS_UNDEFINED: |
398 | label = "undefined"; | 402 | label = "undefined"; |
399 | break; | 403 | break; |
@@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev, | |||
585 | static DEVICE_ATTR(suspend_standby_state, 0444, | 589 | static DEVICE_ATTR(suspend_standby_state, 0444, |
586 | regulator_suspend_standby_state_show, NULL); | 590 | regulator_suspend_standby_state_show, NULL); |
587 | 591 | ||
592 | static ssize_t regulator_bypass_show(struct device *dev, | ||
593 | struct device_attribute *attr, char *buf) | ||
594 | { | ||
595 | struct regulator_dev *rdev = dev_get_drvdata(dev); | ||
596 | const char *report; | ||
597 | bool bypass; | ||
598 | int ret; | ||
599 | |||
600 | ret = rdev->desc->ops->get_bypass(rdev, &bypass); | ||
601 | |||
602 | if (ret != 0) | ||
603 | report = "unknown"; | ||
604 | else if (bypass) | ||
605 | report = "enabled"; | ||
606 | else | ||
607 | report = "disabled"; | ||
608 | |||
609 | return sprintf(buf, "%s\n", report); | ||
610 | } | ||
611 | static DEVICE_ATTR(bypass, 0444, | ||
612 | regulator_bypass_show, NULL); | ||
588 | 613 | ||
589 | /* | 614 | /* |
590 | * These are the only attributes are present for all regulators. | 615 | * These are the only attributes are present for all regulators. |
@@ -2686,6 +2711,100 @@ out: | |||
2686 | EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); | 2711 | EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); |
2687 | 2712 | ||
2688 | /** | 2713 | /** |
2714 | * regulator_set_bypass_regmap - Default set_bypass() using regmap | ||
2715 | * | ||
2716 | * @rdev: device to operate on. | ||
2717 | * @enable: state to set. | ||
2718 | */ | ||
2719 | int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | ||
2720 | { | ||
2721 | unsigned int val; | ||
2722 | |||
2723 | if (enable) | ||
2724 | val = rdev->desc->bypass_mask; | ||
2725 | else | ||
2726 | val = 0; | ||
2727 | |||
2728 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | ||
2729 | rdev->desc->bypass_mask, val); | ||
2730 | } | ||
2731 | EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); | ||
2732 | |||
2733 | /** | ||
2734 | * regulator_get_bypass_regmap - Default get_bypass() using regmap | ||
2735 | * | ||
2736 | * @rdev: device to operate on. | ||
2737 | * @enable: current state. | ||
2738 | */ | ||
2739 | int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) | ||
2740 | { | ||
2741 | unsigned int val; | ||
2742 | int ret; | ||
2743 | |||
2744 | ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); | ||
2745 | if (ret != 0) | ||
2746 | return ret; | ||
2747 | |||
2748 | *enable = val & rdev->desc->bypass_mask; | ||
2749 | |||
2750 | return 0; | ||
2751 | } | ||
2752 | EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); | ||
2753 | |||
2754 | /** | ||
2755 | * regulator_allow_bypass - allow the regulator to go into bypass mode | ||
2756 | * | ||
2757 | * @regulator: Regulator to configure | ||
2758 | * @allow: enable or disable bypass mode | ||
2759 | * | ||
2760 | * Allow the regulator to go into bypass mode if all other consumers | ||
2761 | * for the regulator also enable bypass mode and the machine | ||
2762 | * constraints allow this. Bypass mode means that the regulator is | ||
2763 | * simply passing the input directly to the output with no regulation. | ||
2764 | */ | ||
2765 | int regulator_allow_bypass(struct regulator *regulator, bool enable) | ||
2766 | { | ||
2767 | struct regulator_dev *rdev = regulator->rdev; | ||
2768 | int ret = 0; | ||
2769 | |||
2770 | if (!rdev->desc->ops->set_bypass) | ||
2771 | return 0; | ||
2772 | |||
2773 | if (rdev->constraints && | ||
2774 | !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS)) | ||
2775 | return 0; | ||
2776 | |||
2777 | mutex_lock(&rdev->mutex); | ||
2778 | |||
2779 | if (enable && !regulator->bypass) { | ||
2780 | rdev->bypass_count++; | ||
2781 | |||
2782 | if (rdev->bypass_count == rdev->open_count) { | ||
2783 | ret = rdev->desc->ops->set_bypass(rdev, enable); | ||
2784 | if (ret != 0) | ||
2785 | rdev->bypass_count--; | ||
2786 | } | ||
2787 | |||
2788 | } else if (!enable && regulator->bypass) { | ||
2789 | rdev->bypass_count--; | ||
2790 | |||
2791 | if (rdev->bypass_count != rdev->open_count) { | ||
2792 | ret = rdev->desc->ops->set_bypass(rdev, enable); | ||
2793 | if (ret != 0) | ||
2794 | rdev->bypass_count++; | ||
2795 | } | ||
2796 | } | ||
2797 | |||
2798 | if (ret == 0) | ||
2799 | regulator->bypass = enable; | ||
2800 | |||
2801 | mutex_unlock(&rdev->mutex); | ||
2802 | |||
2803 | return ret; | ||
2804 | } | ||
2805 | EXPORT_SYMBOL_GPL(regulator_allow_bypass); | ||
2806 | |||
2807 | /** | ||
2689 | * regulator_register_notifier - register regulator event notifier | 2808 | * regulator_register_notifier - register regulator event notifier |
2690 | * @regulator: regulator source | 2809 | * @regulator: regulator source |
2691 | * @nb: notifier block | 2810 | * @nb: notifier block |
@@ -3049,6 +3168,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
3049 | if (status < 0) | 3168 | if (status < 0) |
3050 | return status; | 3169 | return status; |
3051 | } | 3170 | } |
3171 | if (ops->get_bypass) { | ||
3172 | status = device_create_file(dev, &dev_attr_bypass); | ||
3173 | if (status < 0) | ||
3174 | return status; | ||
3175 | } | ||
3052 | 3176 | ||
3053 | /* some attributes are type-specific */ | 3177 | /* some attributes are type-specific */ |
3054 | if (rdev->desc->type == REGULATOR_CURRENT) { | 3178 | if (rdev->desc->type == REGULATOR_CURRENT) { |
@@ -3137,6 +3261,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) | |||
3137 | &rdev->use_count); | 3261 | &rdev->use_count); |
3138 | debugfs_create_u32("open_count", 0444, rdev->debugfs, | 3262 | debugfs_create_u32("open_count", 0444, rdev->debugfs, |
3139 | &rdev->open_count); | 3263 | &rdev->open_count); |
3264 | debugfs_create_u32("bypass_count", 0444, rdev->debugfs, | ||
3265 | &rdev->bypass_count); | ||
3140 | } | 3266 | } |
3141 | 3267 | ||
3142 | /** | 3268 | /** |
@@ -3232,7 +3358,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3232 | 3358 | ||
3233 | dev_set_drvdata(&rdev->dev, rdev); | 3359 | dev_set_drvdata(&rdev->dev, rdev); |
3234 | 3360 | ||
3235 | if (config->ena_gpio) { | 3361 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { |
3236 | ret = gpio_request_one(config->ena_gpio, | 3362 | ret = gpio_request_one(config->ena_gpio, |
3237 | GPIOF_DIR_OUT | config->ena_gpio_flags, | 3363 | GPIOF_DIR_OUT | config->ena_gpio_flags, |
3238 | rdev_get_name(rdev)); | 3364 | rdev_get_name(rdev)); |
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 903299cf15cf..27355b1199e5 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
@@ -133,8 +133,8 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA, | |||
133 | max_uA < da9052_current_limits[row][DA9052_MIN_UA]) | 133 | max_uA < da9052_current_limits[row][DA9052_MIN_UA]) |
134 | return -EINVAL; | 134 | return -EINVAL; |
135 | 135 | ||
136 | for (i = 0; i < DA9052_CURRENT_RANGE; i++) { | 136 | for (i = DA9052_CURRENT_RANGE - 1; i >= 0; i--) { |
137 | if (min_uA <= da9052_current_limits[row][i]) { | 137 | if (da9052_current_limits[row][i] <= max_uA) { |
138 | reg_val = i; | 138 | reg_val = i; |
139 | break; | 139 | break; |
140 | } | 140 | } |
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c new file mode 100644 index 000000000000..339f4d732e97 --- /dev/null +++ b/drivers/regulator/fan53555.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. | ||
3 | * | ||
4 | * Supported Part Numbers: | ||
5 | * FAN53555UC00X/01X/03X/04X/05X | ||
6 | * | ||
7 | * Copyright (c) 2012 Marvell Technology Ltd. | ||
8 | * Yunfan Zhang <yfzhang@marvell.com> | ||
9 | * | ||
10 | * This package is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/param.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/regulator/driver.h> | ||
20 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/regulator/fan53555.h> | ||
25 | |||
26 | /* Voltage setting */ | ||
27 | #define FAN53555_VSEL0 0x00 | ||
28 | #define FAN53555_VSEL1 0x01 | ||
29 | /* Control register */ | ||
30 | #define FAN53555_CONTROL 0x02 | ||
31 | /* IC Type */ | ||
32 | #define FAN53555_ID1 0x03 | ||
33 | /* IC mask version */ | ||
34 | #define FAN53555_ID2 0x04 | ||
35 | /* Monitor register */ | ||
36 | #define FAN53555_MONITOR 0x05 | ||
37 | |||
38 | /* VSEL bit definitions */ | ||
39 | #define VSEL_BUCK_EN (1 << 7) | ||
40 | #define VSEL_MODE (1 << 6) | ||
41 | #define VSEL_NSEL_MASK 0x3F | ||
42 | /* Chip ID and Verison */ | ||
43 | #define DIE_ID 0x0F /* ID1 */ | ||
44 | #define DIE_REV 0x0F /* ID2 */ | ||
45 | /* Control bit definitions */ | ||
46 | #define CTL_OUTPUT_DISCHG (1 << 7) | ||
47 | #define CTL_SLEW_MASK (0x7 << 4) | ||
48 | #define CTL_SLEW_SHIFT 4 | ||
49 | #define CTL_RESET (1 << 2) | ||
50 | |||
51 | #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ | ||
52 | |||
53 | /* IC Type */ | ||
54 | enum { | ||
55 | FAN53555_CHIP_ID_00 = 0, | ||
56 | FAN53555_CHIP_ID_01, | ||
57 | FAN53555_CHIP_ID_02, | ||
58 | FAN53555_CHIP_ID_03, | ||
59 | FAN53555_CHIP_ID_04, | ||
60 | FAN53555_CHIP_ID_05, | ||
61 | }; | ||
62 | |||
63 | struct fan53555_device_info { | ||
64 | struct regmap *regmap; | ||
65 | struct device *dev; | ||
66 | struct regulator_desc desc; | ||
67 | struct regulator_dev *rdev; | ||
68 | struct regulator_init_data *regulator; | ||
69 | /* IC Type and Rev */ | ||
70 | int chip_id; | ||
71 | int chip_rev; | ||
72 | /* Voltage setting register */ | ||
73 | unsigned int vol_reg; | ||
74 | unsigned int sleep_reg; | ||
75 | /* Voltage range and step(linear) */ | ||
76 | unsigned int vsel_min; | ||
77 | unsigned int vsel_step; | ||
78 | /* Voltage slew rate limiting */ | ||
79 | unsigned int slew_rate; | ||
80 | /* Sleep voltage cache */ | ||
81 | unsigned int sleep_vol_cache; | ||
82 | }; | ||
83 | |||
84 | static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) | ||
85 | { | ||
86 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | ||
87 | int ret; | ||
88 | |||
89 | if (di->sleep_vol_cache == uV) | ||
90 | return 0; | ||
91 | ret = regulator_map_voltage_linear(rdev, uV, uV); | ||
92 | if (ret < 0) | ||
93 | return -EINVAL; | ||
94 | ret = regmap_update_bits(di->regmap, di->sleep_reg, | ||
95 | VSEL_NSEL_MASK, ret); | ||
96 | if (ret < 0) | ||
97 | return -EINVAL; | ||
98 | /* Cache the sleep voltage setting. | ||
99 | * Might not be the real voltage which is rounded */ | ||
100 | di->sleep_vol_cache = uV; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode) | ||
106 | { | ||
107 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | ||
108 | |||
109 | switch (mode) { | ||
110 | case REGULATOR_MODE_FAST: | ||
111 | regmap_update_bits(di->regmap, di->vol_reg, | ||
112 | VSEL_MODE, VSEL_MODE); | ||
113 | break; | ||
114 | case REGULATOR_MODE_NORMAL: | ||
115 | regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0); | ||
116 | break; | ||
117 | default: | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static unsigned int fan53555_get_mode(struct regulator_dev *rdev) | ||
124 | { | ||
125 | struct fan53555_device_info *di = rdev_get_drvdata(rdev); | ||
126 | unsigned int val; | ||
127 | int ret = 0; | ||
128 | |||
129 | ret = regmap_read(di->regmap, di->vol_reg, &val); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | if (val & VSEL_MODE) | ||
133 | return REGULATOR_MODE_FAST; | ||
134 | else | ||
135 | return REGULATOR_MODE_NORMAL; | ||
136 | } | ||
137 | |||
138 | static struct regulator_ops fan53555_regulator_ops = { | ||
139 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
140 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
141 | .map_voltage = regulator_map_voltage_linear, | ||
142 | .list_voltage = regulator_list_voltage_linear, | ||
143 | .set_suspend_voltage = fan53555_set_suspend_voltage, | ||
144 | .enable = regulator_enable_regmap, | ||
145 | .disable = regulator_disable_regmap, | ||
146 | .is_enabled = regulator_is_enabled_regmap, | ||
147 | .set_mode = fan53555_set_mode, | ||
148 | .get_mode = fan53555_get_mode, | ||
149 | }; | ||
150 | |||
151 | /* For 00,01,03,05 options: | ||
152 | * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V. | ||
153 | * For 04 option: | ||
154 | * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V. | ||
155 | * */ | ||
156 | static int fan53555_device_setup(struct fan53555_device_info *di, | ||
157 | struct fan53555_platform_data *pdata) | ||
158 | { | ||
159 | unsigned int reg, data, mask; | ||
160 | |||
161 | /* Setup voltage control register */ | ||
162 | switch (pdata->sleep_vsel_id) { | ||
163 | case FAN53555_VSEL_ID_0: | ||
164 | di->sleep_reg = FAN53555_VSEL0; | ||
165 | di->vol_reg = FAN53555_VSEL1; | ||
166 | break; | ||
167 | case FAN53555_VSEL_ID_1: | ||
168 | di->sleep_reg = FAN53555_VSEL1; | ||
169 | di->vol_reg = FAN53555_VSEL0; | ||
170 | break; | ||
171 | default: | ||
172 | dev_err(di->dev, "Invalid VSEL ID!\n"); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | /* Init voltage range and step */ | ||
176 | switch (di->chip_id) { | ||
177 | case FAN53555_CHIP_ID_00: | ||
178 | case FAN53555_CHIP_ID_01: | ||
179 | case FAN53555_CHIP_ID_03: | ||
180 | case FAN53555_CHIP_ID_05: | ||
181 | di->vsel_min = 600000; | ||
182 | di->vsel_step = 10000; | ||
183 | break; | ||
184 | case FAN53555_CHIP_ID_04: | ||
185 | di->vsel_min = 603000; | ||
186 | di->vsel_step = 12826; | ||
187 | break; | ||
188 | default: | ||
189 | dev_err(di->dev, | ||
190 | "Chip ID[%d]\n not supported!\n", di->chip_id); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | /* Init slew rate */ | ||
194 | if (pdata->slew_rate & 0x7) | ||
195 | di->slew_rate = pdata->slew_rate; | ||
196 | else | ||
197 | di->slew_rate = FAN53555_SLEW_RATE_64MV; | ||
198 | reg = FAN53555_CONTROL; | ||
199 | data = di->slew_rate << CTL_SLEW_SHIFT; | ||
200 | mask = CTL_SLEW_MASK; | ||
201 | return regmap_update_bits(di->regmap, reg, mask, data); | ||
202 | } | ||
203 | |||
204 | static int fan53555_regulator_register(struct fan53555_device_info *di, | ||
205 | struct regulator_config *config) | ||
206 | { | ||
207 | struct regulator_desc *rdesc = &di->desc; | ||
208 | |||
209 | rdesc->name = "fan53555-reg"; | ||
210 | rdesc->ops = &fan53555_regulator_ops; | ||
211 | rdesc->type = REGULATOR_VOLTAGE; | ||
212 | rdesc->n_voltages = FAN53555_NVOLTAGES; | ||
213 | rdesc->enable_reg = di->vol_reg; | ||
214 | rdesc->enable_mask = VSEL_BUCK_EN; | ||
215 | rdesc->min_uV = di->vsel_min; | ||
216 | rdesc->uV_step = di->vsel_step; | ||
217 | rdesc->vsel_reg = di->vol_reg; | ||
218 | rdesc->vsel_mask = VSEL_NSEL_MASK; | ||
219 | rdesc->owner = THIS_MODULE; | ||
220 | |||
221 | di->rdev = regulator_register(&di->desc, config); | ||
222 | if (IS_ERR(di->rdev)) | ||
223 | return PTR_ERR(di->rdev); | ||
224 | return 0; | ||
225 | |||
226 | } | ||
227 | |||
228 | static struct regmap_config fan53555_regmap_config = { | ||
229 | .reg_bits = 8, | ||
230 | .val_bits = 8, | ||
231 | }; | ||
232 | |||
233 | static int __devinit fan53555_regulator_probe(struct i2c_client *client, | ||
234 | const struct i2c_device_id *id) | ||
235 | { | ||
236 | struct fan53555_device_info *di; | ||
237 | struct fan53555_platform_data *pdata; | ||
238 | struct regulator_config config = { }; | ||
239 | unsigned int val; | ||
240 | int ret; | ||
241 | |||
242 | pdata = client->dev.platform_data; | ||
243 | if (!pdata || !pdata->regulator) { | ||
244 | dev_err(&client->dev, "Platform data not found!\n"); | ||
245 | return -ENODEV; | ||
246 | } | ||
247 | |||
248 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | ||
249 | GFP_KERNEL); | ||
250 | if (!di) { | ||
251 | dev_err(&client->dev, "Failed to allocate device info data!\n"); | ||
252 | return -ENOMEM; | ||
253 | } | ||
254 | di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); | ||
255 | if (IS_ERR(di->regmap)) { | ||
256 | dev_err(&client->dev, "Failed to allocate regmap!\n"); | ||
257 | return PTR_ERR(di->regmap); | ||
258 | } | ||
259 | di->dev = &client->dev; | ||
260 | di->regulator = pdata->regulator; | ||
261 | i2c_set_clientdata(client, di); | ||
262 | /* Get chip ID */ | ||
263 | ret = regmap_read(di->regmap, FAN53555_ID1, &val); | ||
264 | if (ret < 0) { | ||
265 | dev_err(&client->dev, "Failed to get chip ID!\n"); | ||
266 | return -ENODEV; | ||
267 | } | ||
268 | di->chip_id = val & DIE_ID; | ||
269 | /* Get chip revision */ | ||
270 | ret = regmap_read(di->regmap, FAN53555_ID2, &val); | ||
271 | if (ret < 0) { | ||
272 | dev_err(&client->dev, "Failed to get chip Rev!\n"); | ||
273 | return -ENODEV; | ||
274 | } | ||
275 | di->chip_rev = val & DIE_REV; | ||
276 | dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n", | ||
277 | di->chip_id, di->chip_rev); | ||
278 | /* Device init */ | ||
279 | ret = fan53555_device_setup(di, pdata); | ||
280 | if (ret < 0) { | ||
281 | dev_err(&client->dev, "Failed to setup device!\n"); | ||
282 | return ret; | ||
283 | } | ||
284 | /* Register regulator */ | ||
285 | config.dev = di->dev; | ||
286 | config.init_data = di->regulator; | ||
287 | config.regmap = di->regmap; | ||
288 | config.driver_data = di; | ||
289 | ret = fan53555_regulator_register(di, &config); | ||
290 | if (ret < 0) | ||
291 | dev_err(&client->dev, "Failed to register regulator!\n"); | ||
292 | return ret; | ||
293 | |||
294 | } | ||
295 | |||
296 | static int __devexit fan53555_regulator_remove(struct i2c_client *client) | ||
297 | { | ||
298 | struct fan53555_device_info *di = i2c_get_clientdata(client); | ||
299 | |||
300 | regulator_unregister(di->rdev); | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static const struct i2c_device_id fan53555_id[] = { | ||
305 | {"fan53555", -1}, | ||
306 | { }, | ||
307 | }; | ||
308 | |||
309 | static struct i2c_driver fan53555_regulator_driver = { | ||
310 | .driver = { | ||
311 | .name = "fan53555-regulator", | ||
312 | }, | ||
313 | .probe = fan53555_regulator_probe, | ||
314 | .remove = __devexit_p(fan53555_regulator_remove), | ||
315 | .id_table = fan53555_id, | ||
316 | }; | ||
317 | |||
318 | module_i2c_driver(fan53555_regulator_driver); | ||
319 | |||
320 | MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>"); | ||
321 | MODULE_DESCRIPTION("FAN53555 regulator driver"); | ||
322 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 34b67bee9323..8b5944f2d7d1 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) | |||
57 | return -EINVAL; | 57 | return -EINVAL; |
58 | } | 58 | } |
59 | 59 | ||
60 | static int gpio_regulator_set_value(struct regulator_dev *dev, | 60 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, |
61 | int min, int max, unsigned *selector) | 61 | int min_uV, int max_uV, |
62 | unsigned *selector) | ||
62 | { | 63 | { |
63 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | 64 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
64 | int ptr, target = 0, state, best_val = INT_MAX; | 65 | int ptr, target = 0, state, best_val = INT_MAX; |
65 | 66 | ||
66 | for (ptr = 0; ptr < data->nr_states; ptr++) | 67 | for (ptr = 0; ptr < data->nr_states; ptr++) |
67 | if (data->states[ptr].value < best_val && | 68 | if (data->states[ptr].value < best_val && |
68 | data->states[ptr].value >= min && | 69 | data->states[ptr].value >= min_uV && |
69 | data->states[ptr].value <= max) { | 70 | data->states[ptr].value <= max_uV) { |
70 | target = data->states[ptr].gpios; | 71 | target = data->states[ptr].gpios; |
71 | best_val = data->states[ptr].value; | 72 | best_val = data->states[ptr].value; |
72 | if (selector) | 73 | if (selector) |
@@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, | |||
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
87 | 88 | ||
88 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, | ||
89 | int min_uV, int max_uV, | ||
90 | unsigned *selector) | ||
91 | { | ||
92 | return gpio_regulator_set_value(dev, min_uV, max_uV, selector); | ||
93 | } | ||
94 | |||
95 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, | 89 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, |
96 | unsigned selector) | 90 | unsigned selector) |
97 | { | 91 | { |
@@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, | |||
106 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, | 100 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, |
107 | int min_uA, int max_uA) | 101 | int min_uA, int max_uA) |
108 | { | 102 | { |
109 | return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); | 103 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
104 | int ptr, target = 0, state, best_val = 0; | ||
105 | |||
106 | for (ptr = 0; ptr < data->nr_states; ptr++) | ||
107 | if (data->states[ptr].value > best_val && | ||
108 | data->states[ptr].value >= min_uA && | ||
109 | data->states[ptr].value <= max_uA) { | ||
110 | target = data->states[ptr].gpios; | ||
111 | best_val = data->states[ptr].value; | ||
112 | } | ||
113 | |||
114 | if (best_val == 0) | ||
115 | return -EINVAL; | ||
116 | |||
117 | for (ptr = 0; ptr < data->nr_gpios; ptr++) { | ||
118 | state = (target & (1 << ptr)) >> ptr; | ||
119 | gpio_set_value(data->gpios[ptr].gpio, state); | ||
120 | } | ||
121 | data->state = target; | ||
122 | |||
123 | return 0; | ||
110 | } | 124 | } |
111 | 125 | ||
112 | static struct regulator_ops gpio_regulator_voltage_ops = { | 126 | static struct regulator_ops gpio_regulator_voltage_ops = { |
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 1d145a07ada9..d8ecf49a5777 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c | |||
@@ -73,13 +73,7 @@ static struct regulator_ops isl_core_ops = { | |||
73 | .map_voltage = regulator_map_voltage_linear, | 73 | .map_voltage = regulator_map_voltage_linear, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) | ||
77 | { | ||
78 | return dev->desc->min_uV; | ||
79 | } | ||
80 | |||
81 | static struct regulator_ops isl_fixed_ops = { | 76 | static struct regulator_ops isl_fixed_ops = { |
82 | .get_voltage = isl6271a_get_fixed_voltage, | ||
83 | .list_voltage = regulator_list_voltage_linear, | 77 | .list_voltage = regulator_list_voltage_linear, |
84 | }; | 78 | }; |
85 | 79 | ||
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 212c38eaba70..708f4b6a17dc 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c | |||
@@ -86,6 +86,10 @@ | |||
86 | #define EXTERN_DVS_USED 0 | 86 | #define EXTERN_DVS_USED 0 |
87 | #define MAX_DELAY 6 | 87 | #define MAX_DELAY 6 |
88 | 88 | ||
89 | /* Default DVS Mode */ | ||
90 | #define LP8720_DEFAULT_DVS 0 | ||
91 | #define LP8725_DEFAULT_DVS BIT(2) | ||
92 | |||
89 | /* dump registers in regmap-debugfs */ | 93 | /* dump registers in regmap-debugfs */ |
90 | #define MAX_REGISTERS 0x0F | 94 | #define MAX_REGISTERS 0x0F |
91 | 95 | ||
@@ -269,9 +273,9 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) | |||
269 | return val > MAX_DELAY ? 0 : val * time_step_us; | 273 | return val > MAX_DELAY ? 0 : val * time_step_us; |
270 | } | 274 | } |
271 | 275 | ||
272 | static void lp872x_set_dvs(struct lp872x *lp, int gpio) | 276 | static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel, |
277 | int gpio) | ||
273 | { | 278 | { |
274 | enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel; | ||
275 | enum lp872x_dvs_state state; | 279 | enum lp872x_dvs_state state; |
276 | 280 | ||
277 | state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; | 281 | state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW; |
@@ -339,10 +343,10 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, | |||
339 | struct lp872x *lp = rdev_get_drvdata(rdev); | 343 | struct lp872x *lp = rdev_get_drvdata(rdev); |
340 | enum lp872x_regulator_id buck = rdev_get_id(rdev); | 344 | enum lp872x_regulator_id buck = rdev_get_id(rdev); |
341 | u8 addr, mask = LP872X_VOUT_M; | 345 | u8 addr, mask = LP872X_VOUT_M; |
342 | struct lp872x_dvs *dvs = lp->pdata->dvs; | 346 | struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; |
343 | 347 | ||
344 | if (dvs && gpio_is_valid(dvs->gpio)) | 348 | if (dvs && gpio_is_valid(dvs->gpio)) |
345 | lp872x_set_dvs(lp, dvs->gpio); | 349 | lp872x_set_dvs(lp, dvs->vsel, dvs->gpio); |
346 | 350 | ||
347 | addr = lp872x_select_buck_vout_addr(lp, buck); | 351 | addr = lp872x_select_buck_vout_addr(lp, buck); |
348 | if (!lp872x_is_valid_buck_addr(addr)) | 352 | if (!lp872x_is_valid_buck_addr(addr)) |
@@ -374,8 +378,8 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, | |||
374 | { | 378 | { |
375 | struct lp872x *lp = rdev_get_drvdata(rdev); | 379 | struct lp872x *lp = rdev_get_drvdata(rdev); |
376 | enum lp872x_regulator_id buck = rdev_get_id(rdev); | 380 | enum lp872x_regulator_id buck = rdev_get_id(rdev); |
377 | int i, max = ARRAY_SIZE(lp8725_buck_uA); | 381 | int i; |
378 | u8 addr, val; | 382 | u8 addr; |
379 | 383 | ||
380 | switch (buck) { | 384 | switch (buck) { |
381 | case LP8725_ID_BUCK1: | 385 | case LP8725_ID_BUCK1: |
@@ -388,17 +392,15 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, | |||
388 | return -EINVAL; | 392 | return -EINVAL; |
389 | } | 393 | } |
390 | 394 | ||
391 | for (i = 0 ; i < max ; i++) | 395 | for (i = ARRAY_SIZE(lp8725_buck_uA) - 1 ; i >= 0; i--) { |
392 | if (lp8725_buck_uA[i] >= min_uA && | 396 | if (lp8725_buck_uA[i] >= min_uA && |
393 | lp8725_buck_uA[i] <= max_uA) | 397 | lp8725_buck_uA[i] <= max_uA) |
394 | break; | 398 | return lp872x_update_bits(lp, addr, |
395 | 399 | LP8725_BUCK_CL_M, | |
396 | if (i == max) | 400 | i << LP8725_BUCK_CL_S); |
397 | return -EINVAL; | 401 | } |
398 | |||
399 | val = i << LP8725_BUCK_CL_S; | ||
400 | 402 | ||
401 | return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val); | 403 | return -EINVAL; |
402 | } | 404 | } |
403 | 405 | ||
404 | static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) | 406 | static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) |
@@ -727,39 +729,16 @@ static struct regulator_desc lp8725_regulator_desc[] = { | |||
727 | }, | 729 | }, |
728 | }; | 730 | }; |
729 | 731 | ||
730 | static int lp872x_check_dvs_validity(struct lp872x *lp) | ||
731 | { | ||
732 | struct lp872x_dvs *dvs = lp->pdata->dvs; | ||
733 | u8 val = 0; | ||
734 | int ret; | ||
735 | |||
736 | ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); | ||
737 | if (ret) | ||
738 | return ret; | ||
739 | |||
740 | ret = 0; | ||
741 | if (lp->chipid == LP8720) { | ||
742 | if (val & LP8720_EXT_DVS_M) | ||
743 | ret = dvs ? 0 : -EINVAL; | ||
744 | } else { | ||
745 | if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED) | ||
746 | ret = dvs ? 0 : -EINVAL; | ||
747 | } | ||
748 | |||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | static int lp872x_init_dvs(struct lp872x *lp) | 732 | static int lp872x_init_dvs(struct lp872x *lp) |
753 | { | 733 | { |
754 | int ret, gpio; | 734 | int ret, gpio; |
755 | struct lp872x_dvs *dvs = lp->pdata->dvs; | 735 | struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; |
756 | enum lp872x_dvs_state pinstate; | 736 | enum lp872x_dvs_state pinstate; |
737 | u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M }; | ||
738 | u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS }; | ||
757 | 739 | ||
758 | ret = lp872x_check_dvs_validity(lp); | 740 | if (!dvs) |
759 | if (ret) { | 741 | goto set_default_dvs_mode; |
760 | dev_warn(lp->dev, "invalid dvs data: %d\n", ret); | ||
761 | return ret; | ||
762 | } | ||
763 | 742 | ||
764 | gpio = dvs->gpio; | 743 | gpio = dvs->gpio; |
765 | if (!gpio_is_valid(gpio)) { | 744 | if (!gpio_is_valid(gpio)) { |
@@ -778,6 +757,10 @@ static int lp872x_init_dvs(struct lp872x *lp) | |||
778 | lp->dvs_gpio = gpio; | 757 | lp->dvs_gpio = gpio; |
779 | 758 | ||
780 | return 0; | 759 | return 0; |
760 | |||
761 | set_default_dvs_mode: | ||
762 | return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid], | ||
763 | default_dvs_mode[lp->chipid]); | ||
781 | } | 764 | } |
782 | 765 | ||
783 | static int lp872x_config(struct lp872x *lp) | 766 | static int lp872x_config(struct lp872x *lp) |
@@ -785,24 +768,29 @@ static int lp872x_config(struct lp872x *lp) | |||
785 | struct lp872x_platform_data *pdata = lp->pdata; | 768 | struct lp872x_platform_data *pdata = lp->pdata; |
786 | int ret; | 769 | int ret; |
787 | 770 | ||
788 | if (!pdata->update_config) | 771 | if (!pdata || !pdata->update_config) |
789 | return 0; | 772 | goto init_dvs; |
790 | 773 | ||
791 | ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); | 774 | ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); |
792 | if (ret) | 775 | if (ret) |
793 | return ret; | 776 | return ret; |
794 | 777 | ||
778 | init_dvs: | ||
795 | return lp872x_init_dvs(lp); | 779 | return lp872x_init_dvs(lp); |
796 | } | 780 | } |
797 | 781 | ||
798 | static struct regulator_init_data | 782 | static struct regulator_init_data |
799 | *lp872x_find_regulator_init_data(int id, struct lp872x *lp) | 783 | *lp872x_find_regulator_init_data(int id, struct lp872x *lp) |
800 | { | 784 | { |
785 | struct lp872x_platform_data *pdata = lp->pdata; | ||
801 | int i; | 786 | int i; |
802 | 787 | ||
788 | if (!pdata) | ||
789 | return NULL; | ||
790 | |||
803 | for (i = 0; i < lp->num_regulators; i++) { | 791 | for (i = 0; i < lp->num_regulators; i++) { |
804 | if (lp->pdata->regulator_data[i].id == id) | 792 | if (pdata->regulator_data[i].id == id) |
805 | return lp->pdata->regulator_data[i].init_data; | 793 | return pdata->regulator_data[i].init_data; |
806 | } | 794 | } |
807 | 795 | ||
808 | return NULL; | 796 | return NULL; |
@@ -863,18 +851,12 @@ static const struct regmap_config lp872x_regmap_config = { | |||
863 | static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) | 851 | static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
864 | { | 852 | { |
865 | struct lp872x *lp; | 853 | struct lp872x *lp; |
866 | struct lp872x_platform_data *pdata = cl->dev.platform_data; | ||
867 | int ret, size, num_regulators; | 854 | int ret, size, num_regulators; |
868 | const int lp872x_num_regulators[] = { | 855 | const int lp872x_num_regulators[] = { |
869 | [LP8720] = LP8720_NUM_REGULATORS, | 856 | [LP8720] = LP8720_NUM_REGULATORS, |
870 | [LP8725] = LP8725_NUM_REGULATORS, | 857 | [LP8725] = LP8725_NUM_REGULATORS, |
871 | }; | 858 | }; |
872 | 859 | ||
873 | if (!pdata) { | ||
874 | dev_err(&cl->dev, "no platform data\n"); | ||
875 | return -EINVAL; | ||
876 | } | ||
877 | |||
878 | lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); | 860 | lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); |
879 | if (!lp) | 861 | if (!lp) |
880 | goto err_mem; | 862 | goto err_mem; |
@@ -894,7 +876,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) | |||
894 | } | 876 | } |
895 | 877 | ||
896 | lp->dev = &cl->dev; | 878 | lp->dev = &cl->dev; |
897 | lp->pdata = pdata; | 879 | lp->pdata = cl->dev.platform_data; |
898 | lp->chipid = id->driver_data; | 880 | lp->chipid = id->driver_data; |
899 | lp->num_regulators = num_regulators; | 881 | lp->num_regulators = num_regulators; |
900 | i2c_set_clientdata(cl, lp); | 882 | i2c_set_clientdata(cl, lp); |
diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index 6356e821400f..ba3e0aa402de 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c | |||
@@ -69,6 +69,9 @@ | |||
69 | #define PIN_HIGH 1 | 69 | #define PIN_HIGH 1 |
70 | #define ENABLE_TIME_USEC 32 | 70 | #define ENABLE_TIME_USEC 32 |
71 | 71 | ||
72 | #define BUCK_FPWM_MASK(x) (1 << (x)) | ||
73 | #define BUCK_FPWM_SHIFT(x) (x) | ||
74 | |||
72 | enum lp8788_dvs_state { | 75 | enum lp8788_dvs_state { |
73 | DVS_LOW = GPIOF_OUT_INIT_LOW, | 76 | DVS_LOW = GPIOF_OUT_INIT_LOW, |
74 | DVS_HIGH = GPIOF_OUT_INIT_HIGH, | 77 | DVS_HIGH = GPIOF_OUT_INIT_HIGH, |
@@ -86,15 +89,9 @@ enum lp8788_buck_id { | |||
86 | BUCK4, | 89 | BUCK4, |
87 | }; | 90 | }; |
88 | 91 | ||
89 | struct lp8788_pwm_map { | ||
90 | u8 mask; | ||
91 | u8 shift; | ||
92 | }; | ||
93 | |||
94 | struct lp8788_buck { | 92 | struct lp8788_buck { |
95 | struct lp8788 *lp; | 93 | struct lp8788 *lp; |
96 | struct regulator_dev *regulator; | 94 | struct regulator_dev *regulator; |
97 | struct lp8788_pwm_map *pmap; | ||
98 | void *dvs; | 95 | void *dvs; |
99 | }; | 96 | }; |
100 | 97 | ||
@@ -106,29 +103,6 @@ static const int lp8788_buck_vtbl[] = { | |||
106 | 1950000, 2000000, | 103 | 1950000, 2000000, |
107 | }; | 104 | }; |
108 | 105 | ||
109 | /* buck pwm mode selection : used for set/get_mode in regulator ops | ||
110 | * @forced pwm : fast mode | ||
111 | * @auto pwm : normal mode | ||
112 | */ | ||
113 | static struct lp8788_pwm_map buck_pmap[] = { | ||
114 | [BUCK1] = { | ||
115 | .mask = LP8788_FPWM_BUCK1_M, | ||
116 | .shift = LP8788_FPWM_BUCK1_S, | ||
117 | }, | ||
118 | [BUCK2] = { | ||
119 | .mask = LP8788_FPWM_BUCK2_M, | ||
120 | .shift = LP8788_FPWM_BUCK2_S, | ||
121 | }, | ||
122 | [BUCK3] = { | ||
123 | .mask = LP8788_FPWM_BUCK3_M, | ||
124 | .shift = LP8788_FPWM_BUCK3_S, | ||
125 | }, | ||
126 | [BUCK4] = { | ||
127 | .mask = LP8788_FPWM_BUCK4_M, | ||
128 | .shift = LP8788_FPWM_BUCK4_S, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static const u8 buck1_vout_addr[] = { | 106 | static const u8 buck1_vout_addr[] = { |
133 | LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1, | 107 | LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1, |
134 | LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3, | 108 | LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3, |
@@ -347,41 +321,37 @@ static int lp8788_buck_enable_time(struct regulator_dev *rdev) | |||
347 | static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) | 321 | static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) |
348 | { | 322 | { |
349 | struct lp8788_buck *buck = rdev_get_drvdata(rdev); | 323 | struct lp8788_buck *buck = rdev_get_drvdata(rdev); |
350 | struct lp8788_pwm_map *pmap = buck->pmap; | 324 | enum lp8788_buck_id id = rdev_get_id(rdev); |
351 | u8 val; | 325 | u8 mask, val; |
352 | |||
353 | if (!pmap) | ||
354 | return -EINVAL; | ||
355 | 326 | ||
327 | mask = BUCK_FPWM_MASK(id); | ||
356 | switch (mode) { | 328 | switch (mode) { |
357 | case REGULATOR_MODE_FAST: | 329 | case REGULATOR_MODE_FAST: |
358 | val = LP8788_FORCE_PWM << pmap->shift; | 330 | val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id); |
359 | break; | 331 | break; |
360 | case REGULATOR_MODE_NORMAL: | 332 | case REGULATOR_MODE_NORMAL: |
361 | val = LP8788_AUTO_PWM << pmap->shift; | 333 | val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id); |
362 | break; | 334 | break; |
363 | default: | 335 | default: |
364 | return -EINVAL; | 336 | return -EINVAL; |
365 | } | 337 | } |
366 | 338 | ||
367 | return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, pmap->mask, val); | 339 | return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val); |
368 | } | 340 | } |
369 | 341 | ||
370 | static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) | 342 | static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) |
371 | { | 343 | { |
372 | struct lp8788_buck *buck = rdev_get_drvdata(rdev); | 344 | struct lp8788_buck *buck = rdev_get_drvdata(rdev); |
373 | struct lp8788_pwm_map *pmap = buck->pmap; | 345 | enum lp8788_buck_id id = rdev_get_id(rdev); |
374 | u8 val; | 346 | u8 val; |
375 | int ret; | 347 | int ret; |
376 | 348 | ||
377 | if (!pmap) | ||
378 | return -EINVAL; | ||
379 | |||
380 | ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val); | 349 | ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val); |
381 | if (ret) | 350 | if (ret) |
382 | return ret; | 351 | return ret; |
383 | 352 | ||
384 | return val & pmap->mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; | 353 | return val & BUCK_FPWM_MASK(id) ? |
354 | REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; | ||
385 | } | 355 | } |
386 | 356 | ||
387 | static struct regulator_ops lp8788_buck12_ops = { | 357 | static struct regulator_ops lp8788_buck12_ops = { |
@@ -459,27 +429,6 @@ static struct regulator_desc lp8788_buck_desc[] = { | |||
459 | }, | 429 | }, |
460 | }; | 430 | }; |
461 | 431 | ||
462 | static int lp8788_set_default_dvs_ctrl_mode(struct lp8788 *lp, | ||
463 | enum lp8788_buck_id id) | ||
464 | { | ||
465 | u8 mask, val; | ||
466 | |||
467 | switch (id) { | ||
468 | case BUCK1: | ||
469 | mask = LP8788_BUCK1_DVS_SEL_M; | ||
470 | val = LP8788_BUCK1_DVS_I2C; | ||
471 | break; | ||
472 | case BUCK2: | ||
473 | mask = LP8788_BUCK2_DVS_SEL_M; | ||
474 | val = LP8788_BUCK2_DVS_I2C; | ||
475 | break; | ||
476 | default: | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | return lp8788_update_bits(lp, LP8788_BUCK_DVS_SEL, mask, val); | ||
481 | } | ||
482 | |||
483 | static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name) | 432 | static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name) |
484 | { | 433 | { |
485 | struct device *dev = buck->lp->dev; | 434 | struct device *dev = buck->lp->dev; |
@@ -530,6 +479,7 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) | |||
530 | struct lp8788_platform_data *pdata = buck->lp->pdata; | 479 | struct lp8788_platform_data *pdata = buck->lp->pdata; |
531 | u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M }; | 480 | u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M }; |
532 | u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN }; | 481 | u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN }; |
482 | u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C }; | ||
533 | 483 | ||
534 | /* no dvs for buck3, 4 */ | 484 | /* no dvs for buck3, 4 */ |
535 | if (id == BUCK3 || id == BUCK4) | 485 | if (id == BUCK3 || id == BUCK4) |
@@ -550,7 +500,8 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) | |||
550 | val[id]); | 500 | val[id]); |
551 | 501 | ||
552 | set_default_dvs_mode: | 502 | set_default_dvs_mode: |
553 | return lp8788_set_default_dvs_ctrl_mode(buck->lp, id); | 503 | return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id], |
504 | default_dvs_mode[id]); | ||
554 | } | 505 | } |
555 | 506 | ||
556 | static __devinit int lp8788_buck_probe(struct platform_device *pdev) | 507 | static __devinit int lp8788_buck_probe(struct platform_device *pdev) |
@@ -567,7 +518,6 @@ static __devinit int lp8788_buck_probe(struct platform_device *pdev) | |||
567 | return -ENOMEM; | 518 | return -ENOMEM; |
568 | 519 | ||
569 | buck->lp = lp; | 520 | buck->lp = lp; |
570 | buck->pmap = &buck_pmap[id]; | ||
571 | 521 | ||
572 | ret = lp8788_init_dvs(buck, id); | 522 | ret = lp8788_init_dvs(buck, id); |
573 | if (ret) | 523 | if (ret) |
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index d2122e41a96d..6796eeb47dc6 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c | |||
@@ -496,6 +496,7 @@ static struct regulator_desc lp8788_dldo_desc[] = { | |||
496 | .name = "dldo12", | 496 | .name = "dldo12", |
497 | .id = DLDO12, | 497 | .id = DLDO12, |
498 | .ops = &lp8788_ldo_voltage_fixed_ops, | 498 | .ops = &lp8788_ldo_voltage_fixed_ops, |
499 | .n_voltages = 1, | ||
499 | .type = REGULATOR_VOLTAGE, | 500 | .type = REGULATOR_VOLTAGE, |
500 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
501 | .enable_reg = LP8788_EN_LDO_B, | 502 | .enable_reg = LP8788_EN_LDO_B, |
@@ -521,6 +522,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
521 | .name = "aldo2", | 522 | .name = "aldo2", |
522 | .id = ALDO2, | 523 | .id = ALDO2, |
523 | .ops = &lp8788_ldo_voltage_fixed_ops, | 524 | .ops = &lp8788_ldo_voltage_fixed_ops, |
525 | .n_voltages = 1, | ||
524 | .type = REGULATOR_VOLTAGE, | 526 | .type = REGULATOR_VOLTAGE, |
525 | .owner = THIS_MODULE, | 527 | .owner = THIS_MODULE, |
526 | .enable_reg = LP8788_EN_LDO_B, | 528 | .enable_reg = LP8788_EN_LDO_B, |
@@ -530,6 +532,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
530 | .name = "aldo3", | 532 | .name = "aldo3", |
531 | .id = ALDO3, | 533 | .id = ALDO3, |
532 | .ops = &lp8788_ldo_voltage_fixed_ops, | 534 | .ops = &lp8788_ldo_voltage_fixed_ops, |
535 | .n_voltages = 1, | ||
533 | .type = REGULATOR_VOLTAGE, | 536 | .type = REGULATOR_VOLTAGE, |
534 | .owner = THIS_MODULE, | 537 | .owner = THIS_MODULE, |
535 | .enable_reg = LP8788_EN_LDO_B, | 538 | .enable_reg = LP8788_EN_LDO_B, |
@@ -539,6 +542,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
539 | .name = "aldo4", | 542 | .name = "aldo4", |
540 | .id = ALDO4, | 543 | .id = ALDO4, |
541 | .ops = &lp8788_ldo_voltage_fixed_ops, | 544 | .ops = &lp8788_ldo_voltage_fixed_ops, |
545 | .n_voltages = 1, | ||
542 | .type = REGULATOR_VOLTAGE, | 546 | .type = REGULATOR_VOLTAGE, |
543 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
544 | .enable_reg = LP8788_EN_LDO_B, | 548 | .enable_reg = LP8788_EN_LDO_B, |
@@ -548,6 +552,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
548 | .name = "aldo5", | 552 | .name = "aldo5", |
549 | .id = ALDO5, | 553 | .id = ALDO5, |
550 | .ops = &lp8788_ldo_voltage_fixed_ops, | 554 | .ops = &lp8788_ldo_voltage_fixed_ops, |
555 | .n_voltages = 1, | ||
551 | .type = REGULATOR_VOLTAGE, | 556 | .type = REGULATOR_VOLTAGE, |
552 | .owner = THIS_MODULE, | 557 | .owner = THIS_MODULE, |
553 | .enable_reg = LP8788_EN_LDO_C, | 558 | .enable_reg = LP8788_EN_LDO_C, |
@@ -583,6 +588,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
583 | .name = "aldo8", | 588 | .name = "aldo8", |
584 | .id = ALDO8, | 589 | .id = ALDO8, |
585 | .ops = &lp8788_ldo_voltage_fixed_ops, | 590 | .ops = &lp8788_ldo_voltage_fixed_ops, |
591 | .n_voltages = 1, | ||
586 | .type = REGULATOR_VOLTAGE, | 592 | .type = REGULATOR_VOLTAGE, |
587 | .owner = THIS_MODULE, | 593 | .owner = THIS_MODULE, |
588 | .enable_reg = LP8788_EN_LDO_C, | 594 | .enable_reg = LP8788_EN_LDO_C, |
@@ -592,6 +598,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
592 | .name = "aldo9", | 598 | .name = "aldo9", |
593 | .id = ALDO9, | 599 | .id = ALDO9, |
594 | .ops = &lp8788_ldo_voltage_fixed_ops, | 600 | .ops = &lp8788_ldo_voltage_fixed_ops, |
601 | .n_voltages = 1, | ||
595 | .type = REGULATOR_VOLTAGE, | 602 | .type = REGULATOR_VOLTAGE, |
596 | .owner = THIS_MODULE, | 603 | .owner = THIS_MODULE, |
597 | .enable_reg = LP8788_EN_LDO_C, | 604 | .enable_reg = LP8788_EN_LDO_C, |
@@ -601,6 +608,7 @@ static struct regulator_desc lp8788_aldo_desc[] = { | |||
601 | .name = "aldo10", | 608 | .name = "aldo10", |
602 | .id = ALDO10, | 609 | .id = ALDO10, |
603 | .ops = &lp8788_ldo_voltage_fixed_ops, | 610 | .ops = &lp8788_ldo_voltage_fixed_ops, |
611 | .n_voltages = 1, | ||
604 | .type = REGULATOR_VOLTAGE, | 612 | .type = REGULATOR_VOLTAGE, |
605 | .owner = THIS_MODULE, | 613 | .owner = THIS_MODULE, |
606 | .enable_reg = LP8788_EN_LDO_C, | 614 | .enable_reg = LP8788_EN_LDO_C, |
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index c564af6f05a3..2a67d08658ad 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
@@ -66,7 +66,7 @@ enum max77686_ramp_rate { | |||
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct max77686_data { | 68 | struct max77686_data { |
69 | struct regulator_dev **rdev; | 69 | struct regulator_dev *rdev[MAX77686_REGULATORS]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | 72 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) |
@@ -265,6 +265,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | |||
265 | rmatch.of_node = NULL; | 265 | rmatch.of_node = NULL; |
266 | of_regulator_match(iodev->dev, regulators_np, &rmatch, 1); | 266 | of_regulator_match(iodev->dev, regulators_np, &rmatch, 1); |
267 | rdata[i].initdata = rmatch.init_data; | 267 | rdata[i].initdata = rmatch.init_data; |
268 | rdata[i].of_node = rmatch.of_node; | ||
268 | } | 269 | } |
269 | 270 | ||
270 | pdata->regulators = rdata; | 271 | pdata->regulators = rdata; |
@@ -283,10 +284,8 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) | |||
283 | { | 284 | { |
284 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 285 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
285 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); | 286 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); |
286 | struct regulator_dev **rdev; | ||
287 | struct max77686_data *max77686; | 287 | struct max77686_data *max77686; |
288 | int i, size; | 288 | int i, ret = 0; |
289 | int ret = 0; | ||
290 | struct regulator_config config = { }; | 289 | struct regulator_config config = { }; |
291 | 290 | ||
292 | dev_dbg(&pdev->dev, "%s\n", __func__); | 291 | dev_dbg(&pdev->dev, "%s\n", __func__); |
@@ -313,45 +312,38 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) | |||
313 | if (!max77686) | 312 | if (!max77686) |
314 | return -ENOMEM; | 313 | return -ENOMEM; |
315 | 314 | ||
316 | size = sizeof(struct regulator_dev *) * MAX77686_REGULATORS; | ||
317 | max77686->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
318 | if (!max77686->rdev) | ||
319 | return -ENOMEM; | ||
320 | |||
321 | rdev = max77686->rdev; | ||
322 | config.dev = &pdev->dev; | 315 | config.dev = &pdev->dev; |
323 | config.regmap = iodev->regmap; | 316 | config.regmap = iodev->regmap; |
324 | platform_set_drvdata(pdev, max77686); | 317 | platform_set_drvdata(pdev, max77686); |
325 | 318 | ||
326 | for (i = 0; i < MAX77686_REGULATORS; i++) { | 319 | for (i = 0; i < MAX77686_REGULATORS; i++) { |
327 | config.init_data = pdata->regulators[i].initdata; | 320 | config.init_data = pdata->regulators[i].initdata; |
321 | config.of_node = pdata->regulators[i].of_node; | ||
328 | 322 | ||
329 | rdev[i] = regulator_register(®ulators[i], &config); | 323 | max77686->rdev[i] = regulator_register(®ulators[i], &config); |
330 | if (IS_ERR(rdev[i])) { | 324 | if (IS_ERR(max77686->rdev[i])) { |
331 | ret = PTR_ERR(rdev[i]); | 325 | ret = PTR_ERR(max77686->rdev[i]); |
332 | dev_err(&pdev->dev, | 326 | dev_err(&pdev->dev, |
333 | "regulator init failed for %d\n", i); | 327 | "regulator init failed for %d\n", i); |
334 | rdev[i] = NULL; | 328 | max77686->rdev[i] = NULL; |
335 | goto err; | 329 | goto err; |
336 | } | 330 | } |
337 | } | 331 | } |
338 | 332 | ||
339 | return 0; | 333 | return 0; |
340 | err: | 334 | err: |
341 | while (--i >= 0) | 335 | while (--i >= 0) |
342 | regulator_unregister(rdev[i]); | 336 | regulator_unregister(max77686->rdev[i]); |
343 | return ret; | 337 | return ret; |
344 | } | 338 | } |
345 | 339 | ||
346 | static int __devexit max77686_pmic_remove(struct platform_device *pdev) | 340 | static int __devexit max77686_pmic_remove(struct platform_device *pdev) |
347 | { | 341 | { |
348 | struct max77686_data *max77686 = platform_get_drvdata(pdev); | 342 | struct max77686_data *max77686 = platform_get_drvdata(pdev); |
349 | struct regulator_dev **rdev = max77686->rdev; | ||
350 | int i; | 343 | int i; |
351 | 344 | ||
352 | for (i = 0; i < MAX77686_REGULATORS; i++) | 345 | for (i = 0; i < MAX77686_REGULATORS; i++) |
353 | if (rdev[i]) | 346 | regulator_unregister(max77686->rdev[i]); |
354 | regulator_unregister(rdev[i]); | ||
355 | 347 | ||
356 | return 0; | 348 | return 0; |
357 | } | 349 | } |
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c new file mode 100644 index 000000000000..af7607515ab9 --- /dev/null +++ b/drivers/regulator/max8907-regulator.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * max8907-regulator.c -- support regulators in max8907 | ||
3 | * | ||
4 | * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com> | ||
5 | * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * Portions based on drivers/regulator/tps65910-regulator.c, | ||
8 | * Copyright 2010 Texas Instruments Inc. | ||
9 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | ||
10 | * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/err.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/mfd/core.h> | ||
20 | #include <linux/mfd/max8907.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/regulator/driver.h> | ||
25 | #include <linux/regulator/machine.h> | ||
26 | #include <linux/regulator/of_regulator.h> | ||
27 | #include <linux/regmap.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #define MAX8907_II2RR_VERSION_MASK 0xF0 | ||
31 | #define MAX8907_II2RR_VERSION_REV_A 0x00 | ||
32 | #define MAX8907_II2RR_VERSION_REV_B 0x10 | ||
33 | #define MAX8907_II2RR_VERSION_REV_C 0x30 | ||
34 | |||
35 | struct max8907_regulator { | ||
36 | struct regulator_desc desc[MAX8907_NUM_REGULATORS]; | ||
37 | struct regulator_dev *rdev[MAX8907_NUM_REGULATORS]; | ||
38 | }; | ||
39 | |||
40 | #define REG_MBATT() \ | ||
41 | [MAX8907_MBATT] = { \ | ||
42 | .name = "MBATT", \ | ||
43 | .supply_name = "mbatt", \ | ||
44 | .id = MAX8907_MBATT, \ | ||
45 | .ops = &max8907_mbatt_ops, \ | ||
46 | .type = REGULATOR_VOLTAGE, \ | ||
47 | .owner = THIS_MODULE, \ | ||
48 | } | ||
49 | |||
50 | #define REG_LDO(ids, supply, base, min, max, step) \ | ||
51 | [MAX8907_##ids] = { \ | ||
52 | .name = #ids, \ | ||
53 | .supply_name = supply, \ | ||
54 | .id = MAX8907_##ids, \ | ||
55 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
56 | .ops = &max8907_ldo_ops, \ | ||
57 | .type = REGULATOR_VOLTAGE, \ | ||
58 | .owner = THIS_MODULE, \ | ||
59 | .min_uV = (min), \ | ||
60 | .uV_step = (step), \ | ||
61 | .vsel_reg = (base) + MAX8907_VOUT, \ | ||
62 | .vsel_mask = 0x3f, \ | ||
63 | .enable_reg = (base) + MAX8907_CTL, \ | ||
64 | .enable_mask = MAX8907_MASK_LDO_EN, \ | ||
65 | } | ||
66 | |||
67 | #define REG_FIXED(ids, supply, voltage) \ | ||
68 | [MAX8907_##ids] = { \ | ||
69 | .name = #ids, \ | ||
70 | .supply_name = supply, \ | ||
71 | .id = MAX8907_##ids, \ | ||
72 | .n_voltages = 1, \ | ||
73 | .ops = &max8907_fixed_ops, \ | ||
74 | .type = REGULATOR_VOLTAGE, \ | ||
75 | .owner = THIS_MODULE, \ | ||
76 | .min_uV = (voltage), \ | ||
77 | } | ||
78 | |||
79 | #define REG_OUT5V(ids, supply, base, voltage) \ | ||
80 | [MAX8907_##ids] = { \ | ||
81 | .name = #ids, \ | ||
82 | .supply_name = supply, \ | ||
83 | .id = MAX8907_##ids, \ | ||
84 | .n_voltages = 1, \ | ||
85 | .ops = &max8907_out5v_ops, \ | ||
86 | .type = REGULATOR_VOLTAGE, \ | ||
87 | .owner = THIS_MODULE, \ | ||
88 | .min_uV = (voltage), \ | ||
89 | .enable_reg = (base), \ | ||
90 | .enable_mask = MAX8907_MASK_OUT5V_EN, \ | ||
91 | } | ||
92 | |||
93 | #define REG_BBAT(ids, supply, base, min, max, step) \ | ||
94 | [MAX8907_##ids] = { \ | ||
95 | .name = #ids, \ | ||
96 | .supply_name = supply, \ | ||
97 | .id = MAX8907_##ids, \ | ||
98 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
99 | .ops = &max8907_bbat_ops, \ | ||
100 | .type = REGULATOR_VOLTAGE, \ | ||
101 | .owner = THIS_MODULE, \ | ||
102 | .min_uV = (min), \ | ||
103 | .uV_step = (step), \ | ||
104 | .vsel_reg = (base), \ | ||
105 | .vsel_mask = MAX8907_MASK_VBBATTCV, \ | ||
106 | } | ||
107 | |||
108 | #define LDO_750_50(id, supply, base) REG_LDO(id, supply, (base), \ | ||
109 | 750000, 3900000, 50000) | ||
110 | #define LDO_650_25(id, supply, base) REG_LDO(id, supply, (base), \ | ||
111 | 650000, 2225000, 25000) | ||
112 | |||
113 | static struct regulator_ops max8907_mbatt_ops = { | ||
114 | }; | ||
115 | |||
116 | static struct regulator_ops max8907_ldo_ops = { | ||
117 | .list_voltage = regulator_list_voltage_linear, | ||
118 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
119 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
120 | .enable = regulator_enable_regmap, | ||
121 | .disable = regulator_disable_regmap, | ||
122 | .is_enabled = regulator_is_enabled_regmap, | ||
123 | }; | ||
124 | |||
125 | static struct regulator_ops max8907_ldo_hwctl_ops = { | ||
126 | .list_voltage = regulator_list_voltage_linear, | ||
127 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
128 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
129 | }; | ||
130 | |||
131 | static struct regulator_ops max8907_fixed_ops = { | ||
132 | .list_voltage = regulator_list_voltage_linear, | ||
133 | }; | ||
134 | |||
135 | static struct regulator_ops max8907_out5v_ops = { | ||
136 | .list_voltage = regulator_list_voltage_linear, | ||
137 | .enable = regulator_enable_regmap, | ||
138 | .disable = regulator_disable_regmap, | ||
139 | .is_enabled = regulator_is_enabled_regmap, | ||
140 | }; | ||
141 | |||
142 | static struct regulator_ops max8907_out5v_hwctl_ops = { | ||
143 | .list_voltage = regulator_list_voltage_linear, | ||
144 | }; | ||
145 | |||
146 | static struct regulator_ops max8907_bbat_ops = { | ||
147 | .list_voltage = regulator_list_voltage_linear, | ||
148 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
149 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
150 | }; | ||
151 | |||
152 | static struct regulator_desc max8907_regulators[] = { | ||
153 | REG_MBATT(), | ||
154 | REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000), | ||
155 | REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500), | ||
156 | REG_LDO(SD3, "in-v3", MAX8907_REG_SDCTL3, 750000, 3900000, 50000), | ||
157 | LDO_750_50(LDO1, "in1", MAX8907_REG_LDOCTL1), | ||
158 | LDO_650_25(LDO2, "in2", MAX8907_REG_LDOCTL2), | ||
159 | LDO_650_25(LDO3, "in3", MAX8907_REG_LDOCTL3), | ||
160 | LDO_750_50(LDO4, "in4", MAX8907_REG_LDOCTL4), | ||
161 | LDO_750_50(LDO5, "in5", MAX8907_REG_LDOCTL5), | ||
162 | LDO_750_50(LDO6, "in6", MAX8907_REG_LDOCTL6), | ||
163 | LDO_750_50(LDO7, "in7", MAX8907_REG_LDOCTL7), | ||
164 | LDO_750_50(LDO8, "in8", MAX8907_REG_LDOCTL8), | ||
165 | LDO_750_50(LDO9, "in9", MAX8907_REG_LDOCTL9), | ||
166 | LDO_750_50(LDO10, "in10", MAX8907_REG_LDOCTL10), | ||
167 | LDO_750_50(LDO11, "in11", MAX8907_REG_LDOCTL11), | ||
168 | LDO_750_50(LDO12, "in12", MAX8907_REG_LDOCTL12), | ||
169 | LDO_750_50(LDO13, "in13", MAX8907_REG_LDOCTL13), | ||
170 | LDO_750_50(LDO14, "in14", MAX8907_REG_LDOCTL14), | ||
171 | LDO_750_50(LDO15, "in15", MAX8907_REG_LDOCTL15), | ||
172 | LDO_750_50(LDO16, "in16", MAX8907_REG_LDOCTL16), | ||
173 | LDO_650_25(LDO17, "in17", MAX8907_REG_LDOCTL17), | ||
174 | LDO_650_25(LDO18, "in18", MAX8907_REG_LDOCTL18), | ||
175 | LDO_750_50(LDO19, "in19", MAX8907_REG_LDOCTL19), | ||
176 | LDO_750_50(LDO20, "in20", MAX8907_REG_LDOCTL20), | ||
177 | REG_OUT5V(OUT5V, "mbatt", MAX8907_REG_OUT5VEN, 5000000), | ||
178 | REG_OUT5V(OUT33V, "mbatt", MAX8907_REG_OUT33VEN, 3300000), | ||
179 | REG_BBAT(BBAT, "MBATT", MAX8907_REG_BBAT_CNFG, | ||
180 | 2400000, 3000000, 200000), | ||
181 | REG_FIXED(SDBY, "MBATT", 1200000), | ||
182 | REG_FIXED(VRTC, "MBATT", 3300000), | ||
183 | }; | ||
184 | |||
185 | #ifdef CONFIG_OF | ||
186 | |||
187 | #define MATCH(_name, _id) \ | ||
188 | [MAX8907_##_id] = { \ | ||
189 | .name = #_name, \ | ||
190 | .driver_data = (void *)&max8907_regulators[MAX8907_##_id], \ | ||
191 | } | ||
192 | |||
193 | static struct of_regulator_match max8907_matches[] = { | ||
194 | MATCH(mbatt, MBATT), | ||
195 | MATCH(sd1, SD1), | ||
196 | MATCH(sd2, SD2), | ||
197 | MATCH(sd3, SD3), | ||
198 | MATCH(ldo1, LDO1), | ||
199 | MATCH(ldo2, LDO2), | ||
200 | MATCH(ldo3, LDO3), | ||
201 | MATCH(ldo4, LDO4), | ||
202 | MATCH(ldo5, LDO5), | ||
203 | MATCH(ldo6, LDO6), | ||
204 | MATCH(ldo7, LDO7), | ||
205 | MATCH(ldo8, LDO8), | ||
206 | MATCH(ldo9, LDO9), | ||
207 | MATCH(ldo10, LDO10), | ||
208 | MATCH(ldo11, LDO11), | ||
209 | MATCH(ldo12, LDO12), | ||
210 | MATCH(ldo13, LDO13), | ||
211 | MATCH(ldo14, LDO14), | ||
212 | MATCH(ldo15, LDO15), | ||
213 | MATCH(ldo16, LDO16), | ||
214 | MATCH(ldo17, LDO17), | ||
215 | MATCH(ldo18, LDO18), | ||
216 | MATCH(ldo19, LDO19), | ||
217 | MATCH(ldo20, LDO20), | ||
218 | MATCH(out5v, OUT5V), | ||
219 | MATCH(out33v, OUT33V), | ||
220 | MATCH(bbat, BBAT), | ||
221 | MATCH(sdby, SDBY), | ||
222 | MATCH(vrtc, VRTC), | ||
223 | }; | ||
224 | |||
225 | static int max8907_regulator_parse_dt(struct platform_device *pdev) | ||
226 | { | ||
227 | struct device_node *np = pdev->dev.parent->of_node; | ||
228 | struct device_node *regulators; | ||
229 | int ret; | ||
230 | |||
231 | if (!pdev->dev.parent->of_node) | ||
232 | return 0; | ||
233 | |||
234 | regulators = of_find_node_by_name(np, "regulators"); | ||
235 | if (!regulators) { | ||
236 | dev_err(&pdev->dev, "regulators node not found\n"); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | ret = of_regulator_match(pdev->dev.parent, regulators, | ||
241 | max8907_matches, | ||
242 | ARRAY_SIZE(max8907_matches)); | ||
243 | if (ret < 0) { | ||
244 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | ||
245 | ret); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static inline struct regulator_init_data *match_init_data(int index) | ||
253 | { | ||
254 | return max8907_matches[index].init_data; | ||
255 | } | ||
256 | |||
257 | static inline struct device_node *match_of_node(int index) | ||
258 | { | ||
259 | return max8907_matches[index].of_node; | ||
260 | } | ||
261 | #else | ||
262 | static int max8907_regulator_parse_dt(struct platform_device *pdev) | ||
263 | { | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static inline struct regulator_init_data *match_init_data(int index) | ||
268 | { | ||
269 | return NULL; | ||
270 | } | ||
271 | |||
272 | static inline struct device_node *match_of_node(int index) | ||
273 | { | ||
274 | return NULL; | ||
275 | } | ||
276 | #endif | ||
277 | |||
278 | static __devinit int max8907_regulator_probe(struct platform_device *pdev) | ||
279 | { | ||
280 | struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent); | ||
281 | struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev); | ||
282 | int ret; | ||
283 | struct max8907_regulator *pmic; | ||
284 | unsigned int val; | ||
285 | int i; | ||
286 | struct regulator_config config = {}; | ||
287 | struct regulator_init_data *idata; | ||
288 | const char *mbatt_rail_name = NULL; | ||
289 | |||
290 | ret = max8907_regulator_parse_dt(pdev); | ||
291 | if (ret) | ||
292 | return ret; | ||
293 | |||
294 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | ||
295 | if (!pmic) { | ||
296 | dev_err(&pdev->dev, "Failed to alloc pmic\n"); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | platform_set_drvdata(pdev, pmic); | ||
300 | |||
301 | memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); | ||
302 | |||
303 | /* Backwards compatibility with MAX8907B; SD1 uses different voltages */ | ||
304 | regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); | ||
305 | if ((val & MAX8907_II2RR_VERSION_MASK) == | ||
306 | MAX8907_II2RR_VERSION_REV_B) { | ||
307 | pmic->desc[MAX8907_SD1].min_uV = 637500; | ||
308 | pmic->desc[MAX8907_SD1].uV_step = 12500; | ||
309 | pmic->desc[MAX8907_SD1].n_voltages = | ||
310 | (1425000 - 637500) / 12500 + 1; | ||
311 | } | ||
312 | |||
313 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) { | ||
314 | config.dev = pdev->dev.parent; | ||
315 | if (pdata) | ||
316 | idata = pdata->init_data[i]; | ||
317 | else | ||
318 | idata = match_init_data(i); | ||
319 | config.init_data = idata; | ||
320 | config.driver_data = pmic; | ||
321 | config.regmap = max8907->regmap_gen; | ||
322 | config.of_node = match_of_node(i); | ||
323 | |||
324 | switch (pmic->desc[i].id) { | ||
325 | case MAX8907_MBATT: | ||
326 | if (idata && idata->constraints.name) | ||
327 | mbatt_rail_name = idata->constraints.name; | ||
328 | else | ||
329 | mbatt_rail_name = pmic->desc[i].name; | ||
330 | break; | ||
331 | case MAX8907_BBAT: | ||
332 | case MAX8907_SDBY: | ||
333 | case MAX8907_VRTC: | ||
334 | idata->supply_regulator = mbatt_rail_name; | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | if (pmic->desc[i].ops == &max8907_ldo_ops) { | ||
339 | regmap_read(config.regmap, pmic->desc[i].enable_reg, | ||
340 | &val); | ||
341 | if ((val & MAX8907_MASK_LDO_SEQ) != | ||
342 | MAX8907_MASK_LDO_SEQ) | ||
343 | pmic->desc[i].ops = &max8907_ldo_hwctl_ops; | ||
344 | } else if (pmic->desc[i].ops == &max8907_out5v_ops) { | ||
345 | regmap_read(config.regmap, pmic->desc[i].enable_reg, | ||
346 | &val); | ||
347 | if ((val & (MAX8907_MASK_OUT5V_VINEN | | ||
348 | MAX8907_MASK_OUT5V_ENSRC)) != | ||
349 | MAX8907_MASK_OUT5V_ENSRC) | ||
350 | pmic->desc[i].ops = &max8907_out5v_hwctl_ops; | ||
351 | } | ||
352 | |||
353 | pmic->rdev[i] = regulator_register(&pmic->desc[i], &config); | ||
354 | if (IS_ERR(pmic->rdev[i])) { | ||
355 | dev_err(&pdev->dev, | ||
356 | "failed to register %s regulator\n", | ||
357 | pmic->desc[i].name); | ||
358 | ret = PTR_ERR(pmic->rdev[i]); | ||
359 | goto err_unregister_regulator; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | return 0; | ||
364 | |||
365 | err_unregister_regulator: | ||
366 | while (--i >= 0) | ||
367 | regulator_unregister(pmic->rdev[i]); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | static __devexit int max8907_regulator_remove(struct platform_device *pdev) | ||
372 | { | ||
373 | struct max8907_regulator *pmic = platform_get_drvdata(pdev); | ||
374 | int i; | ||
375 | |||
376 | for (i = 0; i < MAX8907_NUM_REGULATORS; i++) | ||
377 | regulator_unregister(pmic->rdev[i]); | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static struct platform_driver max8907_regulator_driver = { | ||
383 | .driver = { | ||
384 | .name = "max8907-regulator", | ||
385 | .owner = THIS_MODULE, | ||
386 | }, | ||
387 | .probe = max8907_regulator_probe, | ||
388 | .remove = __devexit_p(max8907_regulator_remove), | ||
389 | }; | ||
390 | |||
391 | static int __init max8907_regulator_init(void) | ||
392 | { | ||
393 | return platform_driver_register(&max8907_regulator_driver); | ||
394 | } | ||
395 | |||
396 | subsys_initcall(max8907_regulator_init); | ||
397 | |||
398 | static void __exit max8907_reg_exit(void) | ||
399 | { | ||
400 | platform_driver_unregister(&max8907_regulator_driver); | ||
401 | } | ||
402 | |||
403 | module_exit(max8907_reg_exit); | ||
404 | |||
405 | MODULE_DESCRIPTION("MAX8907 regulator driver"); | ||
406 | MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>"); | ||
407 | MODULE_LICENSE("GPL v2"); | ||
408 | MODULE_ALIAS("platform:max8907-regulator"); | ||
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 4932e3449fe1..0801a6d0c122 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -21,6 +21,30 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include "mc13xxx.h" | 22 | #include "mc13xxx.h" |
23 | 23 | ||
24 | #define MC13783_REG_SWITCHERS0 24 | ||
25 | /* Enable does not exist for SW1A */ | ||
26 | #define MC13783_REG_SWITCHERS0_SW1AEN 0 | ||
27 | #define MC13783_REG_SWITCHERS0_SW1AVSEL 0 | ||
28 | #define MC13783_REG_SWITCHERS0_SW1AVSEL_M (63 << 0) | ||
29 | |||
30 | #define MC13783_REG_SWITCHERS1 25 | ||
31 | /* Enable does not exist for SW1B */ | ||
32 | #define MC13783_REG_SWITCHERS1_SW1BEN 0 | ||
33 | #define MC13783_REG_SWITCHERS1_SW1BVSEL 0 | ||
34 | #define MC13783_REG_SWITCHERS1_SW1BVSEL_M (63 << 0) | ||
35 | |||
36 | #define MC13783_REG_SWITCHERS2 26 | ||
37 | /* Enable does not exist for SW2A */ | ||
38 | #define MC13783_REG_SWITCHERS2_SW2AEN 0 | ||
39 | #define MC13783_REG_SWITCHERS2_SW2AVSEL 0 | ||
40 | #define MC13783_REG_SWITCHERS2_SW2AVSEL_M (63 << 0) | ||
41 | |||
42 | #define MC13783_REG_SWITCHERS3 27 | ||
43 | /* Enable does not exist for SW2B */ | ||
44 | #define MC13783_REG_SWITCHERS3_SW2BEN 0 | ||
45 | #define MC13783_REG_SWITCHERS3_SW2BVSEL 0 | ||
46 | #define MC13783_REG_SWITCHERS3_SW2BVSEL_M (63 << 0) | ||
47 | |||
24 | #define MC13783_REG_SWITCHERS5 29 | 48 | #define MC13783_REG_SWITCHERS5 29 |
25 | #define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) | 49 | #define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) |
26 | #define MC13783_REG_SWITCHERS5_SW3VSEL 18 | 50 | #define MC13783_REG_SWITCHERS5_SW3VSEL 18 |
@@ -93,6 +117,44 @@ | |||
93 | 117 | ||
94 | 118 | ||
95 | /* Voltage Values */ | 119 | /* Voltage Values */ |
120 | static const int mc13783_sw1x_val[] = { | ||
121 | 900000, 925000, 950000, 975000, | ||
122 | 1000000, 1025000, 1050000, 1075000, | ||
123 | 1100000, 1125000, 1150000, 1175000, | ||
124 | 1200000, 1225000, 1250000, 1275000, | ||
125 | 1300000, 1325000, 1350000, 1375000, | ||
126 | 1400000, 1425000, 1450000, 1475000, | ||
127 | 1500000, 1525000, 1550000, 1575000, | ||
128 | 1600000, 1625000, 1650000, 1675000, | ||
129 | 1700000, 1700000, 1700000, 1700000, | ||
130 | 1800000, 1800000, 1800000, 1800000, | ||
131 | 1850000, 1850000, 1850000, 1850000, | ||
132 | 2000000, 2000000, 2000000, 2000000, | ||
133 | 2100000, 2100000, 2100000, 2100000, | ||
134 | 2200000, 2200000, 2200000, 2200000, | ||
135 | 2200000, 2200000, 2200000, 2200000, | ||
136 | 2200000, 2200000, 2200000, 2200000, | ||
137 | }; | ||
138 | |||
139 | static const int mc13783_sw2x_val[] = { | ||
140 | 900000, 925000, 950000, 975000, | ||
141 | 1000000, 1025000, 1050000, 1075000, | ||
142 | 1100000, 1125000, 1150000, 1175000, | ||
143 | 1200000, 1225000, 1250000, 1275000, | ||
144 | 1300000, 1325000, 1350000, 1375000, | ||
145 | 1400000, 1425000, 1450000, 1475000, | ||
146 | 1500000, 1525000, 1550000, 1575000, | ||
147 | 1600000, 1625000, 1650000, 1675000, | ||
148 | 1700000, 1700000, 1700000, 1700000, | ||
149 | 1800000, 1800000, 1800000, 1800000, | ||
150 | 1900000, 1900000, 1900000, 1900000, | ||
151 | 2000000, 2000000, 2000000, 2000000, | ||
152 | 2100000, 2100000, 2100000, 2100000, | ||
153 | 2200000, 2200000, 2200000, 2200000, | ||
154 | 2200000, 2200000, 2200000, 2200000, | ||
155 | 2200000, 2200000, 2200000, 2200000, | ||
156 | }; | ||
157 | |||
96 | static const unsigned int mc13783_sw3_val[] = { | 158 | static const unsigned int mc13783_sw3_val[] = { |
97 | 5000000, 5000000, 5000000, 5500000, | 159 | 5000000, 5000000, 5000000, 5500000, |
98 | }; | 160 | }; |
@@ -188,6 +250,10 @@ static struct regulator_ops mc13783_gpo_regulator_ops; | |||
188 | MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) | 250 | MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) |
189 | 251 | ||
190 | static struct mc13xxx_regulator mc13783_regulators[] = { | 252 | static struct mc13xxx_regulator mc13783_regulators[] = { |
253 | MC13783_DEFINE_SW(SW1A, SWITCHERS0, SWITCHERS0, mc13783_sw1x_val), | ||
254 | MC13783_DEFINE_SW(SW1B, SWITCHERS1, SWITCHERS1, mc13783_sw1x_val), | ||
255 | MC13783_DEFINE_SW(SW2A, SWITCHERS2, SWITCHERS2, mc13783_sw2x_val), | ||
256 | MC13783_DEFINE_SW(SW2B, SWITCHERS3, SWITCHERS3, mc13783_sw2x_val), | ||
191 | MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), | 257 | MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), |
192 | 258 | ||
193 | MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), | 259 | MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), |
@@ -238,9 +304,10 @@ static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, | |||
238 | 304 | ||
239 | BUG_ON(val & ~mask); | 305 | BUG_ON(val & ~mask); |
240 | 306 | ||
307 | mc13xxx_lock(priv->mc13xxx); | ||
241 | ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); | 308 | ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); |
242 | if (ret) | 309 | if (ret) |
243 | return ret; | 310 | goto out; |
244 | 311 | ||
245 | /* Update the stored state for Power Gates. */ | 312 | /* Update the stored state for Power Gates. */ |
246 | priv->powermisc_pwgt_state = | 313 | priv->powermisc_pwgt_state = |
@@ -253,7 +320,10 @@ static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, | |||
253 | valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | | 320 | valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | |
254 | priv->powermisc_pwgt_state; | 321 | priv->powermisc_pwgt_state; |
255 | 322 | ||
256 | return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread); | 323 | ret = mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread); |
324 | out: | ||
325 | mc13xxx_unlock(priv->mc13xxx); | ||
326 | return ret; | ||
257 | } | 327 | } |
258 | 328 | ||
259 | static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) | 329 | static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) |
@@ -261,7 +331,6 @@ static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) | |||
261 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 331 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
262 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | 332 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; |
263 | int id = rdev_get_id(rdev); | 333 | int id = rdev_get_id(rdev); |
264 | int ret; | ||
265 | u32 en_val = mc13xxx_regulators[id].enable_bit; | 334 | u32 en_val = mc13xxx_regulators[id].enable_bit; |
266 | 335 | ||
267 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 336 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
@@ -271,12 +340,8 @@ static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev) | |||
271 | id == MC13783_REG_PWGT2SPI) | 340 | id == MC13783_REG_PWGT2SPI) |
272 | en_val = 0; | 341 | en_val = 0; |
273 | 342 | ||
274 | mc13xxx_lock(priv->mc13xxx); | 343 | return mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, |
275 | ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, | ||
276 | en_val); | 344 | en_val); |
277 | mc13xxx_unlock(priv->mc13xxx); | ||
278 | |||
279 | return ret; | ||
280 | } | 345 | } |
281 | 346 | ||
282 | static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | 347 | static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) |
@@ -284,7 +349,6 @@ static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | |||
284 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 349 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
285 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; | 350 | struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; |
286 | int id = rdev_get_id(rdev); | 351 | int id = rdev_get_id(rdev); |
287 | int ret; | ||
288 | u32 dis_val = 0; | 352 | u32 dis_val = 0; |
289 | 353 | ||
290 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 354 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
@@ -294,12 +358,8 @@ static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev) | |||
294 | id == MC13783_REG_PWGT2SPI) | 358 | id == MC13783_REG_PWGT2SPI) |
295 | dis_val = mc13xxx_regulators[id].enable_bit; | 359 | dis_val = mc13xxx_regulators[id].enable_bit; |
296 | 360 | ||
297 | mc13xxx_lock(priv->mc13xxx); | 361 | return mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, |
298 | ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit, | ||
299 | dis_val); | 362 | dis_val); |
300 | mc13xxx_unlock(priv->mc13xxx); | ||
301 | |||
302 | return ret; | ||
303 | } | 363 | } |
304 | 364 | ||
305 | static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) | 365 | static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) |
@@ -330,7 +390,6 @@ static struct regulator_ops mc13783_gpo_regulator_ops = { | |||
330 | .is_enabled = mc13783_gpo_regulator_is_enabled, | 390 | .is_enabled = mc13783_gpo_regulator_is_enabled, |
331 | .list_voltage = regulator_list_voltage_table, | 391 | .list_voltage = regulator_list_voltage_table, |
332 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, | 392 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, |
333 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, | ||
334 | }; | 393 | }; |
335 | 394 | ||
336 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | 395 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index b388b746452e..1fa63812f7ac 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c | |||
@@ -305,9 +305,10 @@ static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, | |||
305 | 305 | ||
306 | BUG_ON(val & ~mask); | 306 | BUG_ON(val & ~mask); |
307 | 307 | ||
308 | mc13xxx_lock(priv->mc13xxx); | ||
308 | ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread); | 309 | ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread); |
309 | if (ret) | 310 | if (ret) |
310 | return ret; | 311 | goto out; |
311 | 312 | ||
312 | /* Update the stored state for Power Gates. */ | 313 | /* Update the stored state for Power Gates. */ |
313 | priv->powermisc_pwgt_state = | 314 | priv->powermisc_pwgt_state = |
@@ -320,14 +321,16 @@ static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, | |||
320 | valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) | | 321 | valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) | |
321 | priv->powermisc_pwgt_state; | 322 | priv->powermisc_pwgt_state; |
322 | 323 | ||
323 | return mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread); | 324 | ret = mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread); |
325 | out: | ||
326 | mc13xxx_unlock(priv->mc13xxx); | ||
327 | return ret; | ||
324 | } | 328 | } |
325 | 329 | ||
326 | static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev) | 330 | static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev) |
327 | { | 331 | { |
328 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 332 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
329 | int id = rdev_get_id(rdev); | 333 | int id = rdev_get_id(rdev); |
330 | int ret; | ||
331 | u32 en_val = mc13892_regulators[id].enable_bit; | 334 | u32 en_val = mc13892_regulators[id].enable_bit; |
332 | u32 mask = mc13892_regulators[id].enable_bit; | 335 | u32 mask = mc13892_regulators[id].enable_bit; |
333 | 336 | ||
@@ -340,18 +343,13 @@ static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev) | |||
340 | if (id == MC13892_GPO4) | 343 | if (id == MC13892_GPO4) |
341 | mask |= MC13892_POWERMISC_GPO4ADINEN; | 344 | mask |= MC13892_POWERMISC_GPO4ADINEN; |
342 | 345 | ||
343 | mc13xxx_lock(priv->mc13xxx); | 346 | return mc13892_powermisc_rmw(priv, mask, en_val); |
344 | ret = mc13892_powermisc_rmw(priv, mask, en_val); | ||
345 | mc13xxx_unlock(priv->mc13xxx); | ||
346 | |||
347 | return ret; | ||
348 | } | 347 | } |
349 | 348 | ||
350 | static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev) | 349 | static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev) |
351 | { | 350 | { |
352 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 351 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
353 | int id = rdev_get_id(rdev); | 352 | int id = rdev_get_id(rdev); |
354 | int ret; | ||
355 | u32 dis_val = 0; | 353 | u32 dis_val = 0; |
356 | 354 | ||
357 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 355 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
@@ -360,12 +358,8 @@ static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev) | |||
360 | if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) | 358 | if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI) |
361 | dis_val = mc13892_regulators[id].enable_bit; | 359 | dis_val = mc13892_regulators[id].enable_bit; |
362 | 360 | ||
363 | mc13xxx_lock(priv->mc13xxx); | 361 | return mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit, |
364 | ret = mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit, | ||
365 | dis_val); | 362 | dis_val); |
366 | mc13xxx_unlock(priv->mc13xxx); | ||
367 | |||
368 | return ret; | ||
369 | } | 363 | } |
370 | 364 | ||
371 | static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) | 365 | static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) |
@@ -396,14 +390,13 @@ static struct regulator_ops mc13892_gpo_regulator_ops = { | |||
396 | .is_enabled = mc13892_gpo_regulator_is_enabled, | 390 | .is_enabled = mc13892_gpo_regulator_is_enabled, |
397 | .list_voltage = regulator_list_voltage_table, | 391 | .list_voltage = regulator_list_voltage_table, |
398 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, | 392 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, |
399 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, | ||
400 | }; | 393 | }; |
401 | 394 | ||
402 | static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev) | 395 | static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev) |
403 | { | 396 | { |
404 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 397 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
405 | int ret, id = rdev_get_id(rdev); | 398 | int ret, id = rdev_get_id(rdev); |
406 | unsigned int val, hi; | 399 | unsigned int val; |
407 | 400 | ||
408 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | 401 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); |
409 | 402 | ||
@@ -414,17 +407,11 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev) | |||
414 | if (ret) | 407 | if (ret) |
415 | return ret; | 408 | return ret; |
416 | 409 | ||
417 | hi = val & MC13892_SWITCHERS0_SWxHI; | ||
418 | val = (val & mc13892_regulators[id].vsel_mask) | 410 | val = (val & mc13892_regulators[id].vsel_mask) |
419 | >> mc13892_regulators[id].vsel_shift; | 411 | >> mc13892_regulators[id].vsel_shift; |
420 | 412 | ||
421 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | 413 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); |
422 | 414 | ||
423 | if (hi) | ||
424 | val = (25000 * val) + 1100000; | ||
425 | else | ||
426 | val = (25000 * val) + 600000; | ||
427 | |||
428 | return val; | 415 | return val; |
429 | } | 416 | } |
430 | 417 | ||
@@ -432,37 +419,25 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
432 | unsigned selector) | 419 | unsigned selector) |
433 | { | 420 | { |
434 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); | 421 | struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); |
435 | int hi, value, mask, id = rdev_get_id(rdev); | 422 | int volt, mask, id = rdev_get_id(rdev); |
436 | u32 valread; | 423 | u32 reg_value; |
437 | int ret; | 424 | int ret; |
438 | 425 | ||
439 | value = rdev->desc->volt_table[selector]; | 426 | volt = rdev->desc->volt_table[selector]; |
427 | mask = mc13892_regulators[id].vsel_mask; | ||
428 | reg_value = selector << mc13892_regulators[id].vsel_shift; | ||
429 | |||
430 | if (volt > 1375000) { | ||
431 | mask |= MC13892_SWITCHERS0_SWxHI; | ||
432 | reg_value |= MC13892_SWITCHERS0_SWxHI; | ||
433 | } else if (volt < 1100000) { | ||
434 | mask |= MC13892_SWITCHERS0_SWxHI; | ||
435 | reg_value &= ~MC13892_SWITCHERS0_SWxHI; | ||
436 | } | ||
440 | 437 | ||
441 | mc13xxx_lock(priv->mc13xxx); | 438 | mc13xxx_lock(priv->mc13xxx); |
442 | ret = mc13xxx_reg_read(priv->mc13xxx, | 439 | ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg, mask, |
443 | mc13892_regulators[id].vsel_reg, &valread); | 440 | reg_value); |
444 | if (ret) | ||
445 | goto err; | ||
446 | |||
447 | if (value > 1375000) | ||
448 | hi = 1; | ||
449 | else if (value < 1100000) | ||
450 | hi = 0; | ||
451 | else | ||
452 | hi = valread & MC13892_SWITCHERS0_SWxHI; | ||
453 | |||
454 | if (hi) { | ||
455 | value = (value - 1100000) / 25000; | ||
456 | value |= MC13892_SWITCHERS0_SWxHI; | ||
457 | } else | ||
458 | value = (value - 600000) / 25000; | ||
459 | |||
460 | mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; | ||
461 | valread = (valread & ~mask) | | ||
462 | (value << mc13892_regulators[id].vsel_shift); | ||
463 | ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg, | ||
464 | valread); | ||
465 | err: | ||
466 | mc13xxx_unlock(priv->mc13xxx); | 441 | mc13xxx_unlock(priv->mc13xxx); |
467 | 442 | ||
468 | return ret; | 443 | return ret; |
@@ -471,7 +446,7 @@ err: | |||
471 | static struct regulator_ops mc13892_sw_regulator_ops = { | 446 | static struct regulator_ops mc13892_sw_regulator_ops = { |
472 | .list_voltage = regulator_list_voltage_table, | 447 | .list_voltage = regulator_list_voltage_table, |
473 | .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, | 448 | .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, |
474 | .get_voltage = mc13892_sw_regulator_get_voltage, | 449 | .get_voltage_sel = mc13892_sw_regulator_get_voltage_sel, |
475 | }; | 450 | }; |
476 | 451 | ||
477 | static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode) | 452 | static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode) |
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index d6eda28ca5d0..88cbb832d555 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
@@ -143,30 +143,21 @@ int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, | |||
143 | __func__, id, min_uV, max_uV); | 143 | __func__, id, min_uV, max_uV); |
144 | 144 | ||
145 | if (min_uV <= rdev->desc->volt_table[0] && | 145 | if (min_uV <= rdev->desc->volt_table[0] && |
146 | rdev->desc->volt_table[0] <= max_uV) | 146 | rdev->desc->volt_table[0] <= max_uV) { |
147 | *selector = 0; | ||
147 | return 0; | 148 | return 0; |
148 | else | 149 | } else { |
149 | return -EINVAL; | 150 | return -EINVAL; |
151 | } | ||
150 | } | 152 | } |
151 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); | 153 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); |
152 | 154 | ||
153 | int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) | ||
154 | { | ||
155 | int id = rdev_get_id(rdev); | ||
156 | |||
157 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | ||
158 | |||
159 | return rdev->desc->volt_table[0]; | ||
160 | } | ||
161 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); | ||
162 | |||
163 | struct regulator_ops mc13xxx_fixed_regulator_ops = { | 155 | struct regulator_ops mc13xxx_fixed_regulator_ops = { |
164 | .enable = mc13xxx_regulator_enable, | 156 | .enable = mc13xxx_regulator_enable, |
165 | .disable = mc13xxx_regulator_disable, | 157 | .disable = mc13xxx_regulator_disable, |
166 | .is_enabled = mc13xxx_regulator_is_enabled, | 158 | .is_enabled = mc13xxx_regulator_is_enabled, |
167 | .list_voltage = regulator_list_voltage_table, | 159 | .list_voltage = regulator_list_voltage_table, |
168 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, | 160 | .set_voltage = mc13xxx_fixed_regulator_set_voltage, |
169 | .get_voltage = mc13xxx_fixed_regulator_get_voltage, | ||
170 | }; | 161 | }; |
171 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); | 162 | EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); |
172 | 163 | ||
diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h index eaff5510b6df..06c8903f182a 100644 --- a/drivers/regulator/mc13xxx.h +++ b/drivers/regulator/mc13xxx.h | |||
@@ -34,7 +34,6 @@ struct mc13xxx_regulator_priv { | |||
34 | 34 | ||
35 | extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, | 35 | extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, |
36 | int min_uV, int max_uV, unsigned *selector); | 36 | int min_uV, int max_uV, unsigned *selector); |
37 | extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev); | ||
38 | 37 | ||
39 | #ifdef CONFIG_OF | 38 | #ifdef CONFIG_OF |
40 | extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev); | 39 | extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev); |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 3e4106f2bda9..6f684916fd79 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -92,16 +92,18 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, | |||
92 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); | 92 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * of_regulator_match - extract regulator init data when node | 95 | * of_regulator_match - extract multiple regulator init data from device tree. |
96 | * property "regulator-compatible" matches with the regulator name. | ||
97 | * @dev: device requesting the data | 96 | * @dev: device requesting the data |
98 | * @node: parent device node of the regulators | 97 | * @node: parent device node of the regulators |
99 | * @matches: match table for the regulators | 98 | * @matches: match table for the regulators |
100 | * @num_matches: number of entries in match table | 99 | * @num_matches: number of entries in match table |
101 | * | 100 | * |
102 | * This function uses a match table specified by the regulator driver and | 101 | * This function uses a match table specified by the regulator driver to |
103 | * looks up the corresponding init data in the device tree if | 102 | * parse regulator init data from the device tree. @node is expected to |
104 | * regulator-compatible matches. Note that the match table is modified | 103 | * contain a set of child nodes, each providing the init data for one |
104 | * regulator. The data parsed from a child node will be matched to a regulator | ||
105 | * based on either the deprecated property regulator-compatible if present, | ||
106 | * or otherwise the child node's name. Note that the match table is modified | ||
105 | * in place. | 107 | * in place. |
106 | * | 108 | * |
107 | * Returns the number of matches found or a negative error code on failure. | 109 | * Returns the number of matches found or a negative error code on failure. |
@@ -112,26 +114,23 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
112 | { | 114 | { |
113 | unsigned int count = 0; | 115 | unsigned int count = 0; |
114 | unsigned int i; | 116 | unsigned int i; |
115 | const char *regulator_comp; | 117 | const char *name; |
116 | struct device_node *child; | 118 | struct device_node *child; |
117 | 119 | ||
118 | if (!dev || !node) | 120 | if (!dev || !node) |
119 | return -EINVAL; | 121 | return -EINVAL; |
120 | 122 | ||
121 | for_each_child_of_node(node, child) { | 123 | for_each_child_of_node(node, child) { |
122 | regulator_comp = of_get_property(child, | 124 | name = of_get_property(child, |
123 | "regulator-compatible", NULL); | 125 | "regulator-compatible", NULL); |
124 | if (!regulator_comp) { | 126 | if (!name) |
125 | dev_err(dev, "regulator-compatible is missing for node %s\n", | 127 | name = child->name; |
126 | child->name); | ||
127 | continue; | ||
128 | } | ||
129 | for (i = 0; i < num_matches; i++) { | 128 | for (i = 0; i < num_matches; i++) { |
130 | struct of_regulator_match *match = &matches[i]; | 129 | struct of_regulator_match *match = &matches[i]; |
131 | if (match->of_node) | 130 | if (match->of_node) |
132 | continue; | 131 | continue; |
133 | 132 | ||
134 | if (strcmp(match->name, regulator_comp)) | 133 | if (strcmp(match->name, name)) |
135 | continue; | 134 | continue; |
136 | 135 | ||
137 | match->init_data = | 136 | match->init_data = |
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..2ba7502fa3b2 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -443,52 +443,17 @@ static int palmas_list_voltage_ldo(struct regulator_dev *dev, | |||
443 | return 850000 + (selector * 50000); | 443 | return 850000 + (selector * 50000); |
444 | } | 444 | } |
445 | 445 | ||
446 | static int palmas_get_voltage_ldo_sel(struct regulator_dev *dev) | ||
447 | { | ||
448 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
449 | int id = rdev_get_id(dev); | ||
450 | int selector; | ||
451 | unsigned int reg; | ||
452 | unsigned int addr; | ||
453 | |||
454 | addr = palmas_regs_info[id].vsel_addr; | ||
455 | |||
456 | palmas_ldo_read(pmic->palmas, addr, ®); | ||
457 | |||
458 | selector = reg & PALMAS_LDO1_VOLTAGE_VSEL_MASK; | ||
459 | |||
460 | /* Adjust selector to match list_voltage ranges */ | ||
461 | if (selector > 49) | ||
462 | selector = 49; | ||
463 | |||
464 | return selector; | ||
465 | } | ||
466 | |||
467 | static int palmas_set_voltage_ldo_sel(struct regulator_dev *dev, | ||
468 | unsigned selector) | ||
469 | { | ||
470 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
471 | int id = rdev_get_id(dev); | ||
472 | unsigned int reg = 0; | ||
473 | unsigned int addr; | ||
474 | |||
475 | addr = palmas_regs_info[id].vsel_addr; | ||
476 | |||
477 | reg = selector; | ||
478 | |||
479 | palmas_ldo_write(pmic->palmas, addr, reg); | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | static int palmas_map_voltage_ldo(struct regulator_dev *rdev, | 446 | static int palmas_map_voltage_ldo(struct regulator_dev *rdev, |
485 | int min_uV, int max_uV) | 447 | int min_uV, int max_uV) |
486 | { | 448 | { |
487 | int ret, voltage; | 449 | int ret, voltage; |
488 | 450 | ||
489 | ret = ((min_uV - 900000) / 50000) + 1; | 451 | if (min_uV == 0) |
490 | if (ret < 0) | 452 | return 0; |
491 | return ret; | 453 | |
454 | if (min_uV < 900000) | ||
455 | min_uV = 900000; | ||
456 | ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; | ||
492 | 457 | ||
493 | /* Map back into a voltage to verify we're still in bounds */ | 458 | /* Map back into a voltage to verify we're still in bounds */ |
494 | voltage = palmas_list_voltage_ldo(rdev, ret); | 459 | voltage = palmas_list_voltage_ldo(rdev, ret); |
@@ -502,8 +467,8 @@ static struct regulator_ops palmas_ops_ldo = { | |||
502 | .is_enabled = palmas_is_enabled_ldo, | 467 | .is_enabled = palmas_is_enabled_ldo, |
503 | .enable = regulator_enable_regmap, | 468 | .enable = regulator_enable_regmap, |
504 | .disable = regulator_disable_regmap, | 469 | .disable = regulator_disable_regmap, |
505 | .get_voltage_sel = palmas_get_voltage_ldo_sel, | 470 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
506 | .set_voltage_sel = palmas_set_voltage_ldo_sel, | 471 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
507 | .list_voltage = palmas_list_voltage_ldo, | 472 | .list_voltage = palmas_list_voltage_ldo, |
508 | .map_voltage = palmas_map_voltage_ldo, | 473 | .map_voltage = palmas_map_voltage_ldo, |
509 | }; | 474 | }; |
@@ -586,7 +551,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
586 | 551 | ||
587 | addr = palmas_regs_info[id].ctrl_addr; | 552 | addr = palmas_regs_info[id].ctrl_addr; |
588 | 553 | ||
589 | ret = palmas_smps_read(palmas, addr, ®); | 554 | ret = palmas_ldo_read(palmas, addr, ®); |
590 | if (ret) | 555 | if (ret) |
591 | return ret; | 556 | return ret; |
592 | 557 | ||
@@ -596,7 +561,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
596 | if (reg_init->mode_sleep) | 561 | if (reg_init->mode_sleep) |
597 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; | 562 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; |
598 | 563 | ||
599 | ret = palmas_smps_write(palmas, addr, reg); | 564 | ret = palmas_ldo_write(palmas, addr, reg); |
600 | if (ret) | 565 | if (ret) |
601 | return ret; | 566 | return ret; |
602 | 567 | ||
@@ -630,7 +595,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
630 | 595 | ||
631 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); | 596 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); |
632 | if (ret) | 597 | if (ret) |
633 | goto err_unregister_regulator; | 598 | return ret; |
634 | 599 | ||
635 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) | 600 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) |
636 | pmic->smps123 = 1; | 601 | pmic->smps123 = 1; |
@@ -676,7 +641,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
676 | case PALMAS_REG_SMPS10: | 641 | case PALMAS_REG_SMPS10: |
677 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; | 642 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; |
678 | pmic->desc[id].ops = &palmas_ops_smps10; | 643 | pmic->desc[id].ops = &palmas_ops_smps10; |
679 | pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; | 644 | pmic->desc[id].vsel_reg = |
645 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | ||
646 | PALMAS_SMPS10_CTRL); | ||
680 | pmic->desc[id].vsel_mask = SMPS10_VSEL; | 647 | pmic->desc[id].vsel_mask = SMPS10_VSEL; |
681 | pmic->desc[id].enable_reg = | 648 | pmic->desc[id].enable_reg = |
682 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | 649 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, |
@@ -752,6 +719,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
752 | 719 | ||
753 | pmic->desc[id].type = REGULATOR_VOLTAGE; | 720 | pmic->desc[id].type = REGULATOR_VOLTAGE; |
754 | pmic->desc[id].owner = THIS_MODULE; | 721 | pmic->desc[id].owner = THIS_MODULE; |
722 | pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, | ||
723 | palmas_regs_info[id].vsel_addr); | ||
724 | pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; | ||
755 | pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, | 725 | pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, |
756 | palmas_regs_info[id].ctrl_addr); | 726 | palmas_regs_info[id].ctrl_addr); |
757 | pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; | 727 | pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; |
@@ -778,8 +748,10 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
778 | reg_init = pdata->reg_init[id]; | 748 | reg_init = pdata->reg_init[id]; |
779 | if (reg_init) { | 749 | if (reg_init) { |
780 | ret = palmas_ldo_init(palmas, id, reg_init); | 750 | ret = palmas_ldo_init(palmas, id, reg_init); |
781 | if (ret) | 751 | if (ret) { |
752 | regulator_unregister(pmic->rdev[id]); | ||
782 | goto err_unregister_regulator; | 753 | goto err_unregister_regulator; |
754 | } | ||
783 | } | 755 | } |
784 | } | 756 | } |
785 | } | 757 | } |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 4669dc9ac74a..926f9c8f2fac 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/mfd/samsung/s2mps11.h> | 24 | #include <linux/mfd/samsung/s2mps11.h> |
25 | 25 | ||
26 | struct s2mps11_info { | 26 | struct s2mps11_info { |
27 | struct regulator_dev **rdev; | 27 | struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX]; |
28 | 28 | ||
29 | int ramp_delay2; | 29 | int ramp_delay2; |
30 | int ramp_delay34; | 30 | int ramp_delay34; |
@@ -236,9 +236,8 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) | |||
236 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 236 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
237 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | 237 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); |
238 | struct regulator_config config = { }; | 238 | struct regulator_config config = { }; |
239 | struct regulator_dev **rdev; | ||
240 | struct s2mps11_info *s2mps11; | 239 | struct s2mps11_info *s2mps11; |
241 | int i, ret, size; | 240 | int i, ret; |
242 | unsigned char ramp_enable, ramp_reg = 0; | 241 | unsigned char ramp_enable, ramp_reg = 0; |
243 | 242 | ||
244 | if (!pdata) { | 243 | if (!pdata) { |
@@ -251,13 +250,6 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) | |||
251 | if (!s2mps11) | 250 | if (!s2mps11) |
252 | return -ENOMEM; | 251 | return -ENOMEM; |
253 | 252 | ||
254 | size = sizeof(struct regulator_dev *) * S2MPS11_REGULATOR_MAX; | ||
255 | s2mps11->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
256 | if (!s2mps11->rdev) { | ||
257 | return -ENOMEM; | ||
258 | } | ||
259 | |||
260 | rdev = s2mps11->rdev; | ||
261 | platform_set_drvdata(pdev, s2mps11); | 253 | platform_set_drvdata(pdev, s2mps11); |
262 | 254 | ||
263 | s2mps11->ramp_delay2 = pdata->buck2_ramp_delay; | 255 | s2mps11->ramp_delay2 = pdata->buck2_ramp_delay; |
@@ -297,12 +289,12 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) | |||
297 | config.init_data = pdata->regulators[i].initdata; | 289 | config.init_data = pdata->regulators[i].initdata; |
298 | config.driver_data = s2mps11; | 290 | config.driver_data = s2mps11; |
299 | 291 | ||
300 | rdev[i] = regulator_register(®ulators[i], &config); | 292 | s2mps11->rdev[i] = regulator_register(®ulators[i], &config); |
301 | if (IS_ERR(rdev[i])) { | 293 | if (IS_ERR(s2mps11->rdev[i])) { |
302 | ret = PTR_ERR(rdev[i]); | 294 | ret = PTR_ERR(s2mps11->rdev[i]); |
303 | dev_err(&pdev->dev, "regulator init failed for %d\n", | 295 | dev_err(&pdev->dev, "regulator init failed for %d\n", |
304 | i); | 296 | i); |
305 | rdev[i] = NULL; | 297 | s2mps11->rdev[i] = NULL; |
306 | goto err; | 298 | goto err; |
307 | } | 299 | } |
308 | } | 300 | } |
@@ -310,8 +302,7 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) | |||
310 | return 0; | 302 | return 0; |
311 | err: | 303 | err: |
312 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) | 304 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) |
313 | if (rdev[i]) | 305 | regulator_unregister(s2mps11->rdev[i]); |
314 | regulator_unregister(rdev[i]); | ||
315 | 306 | ||
316 | return ret; | 307 | return ret; |
317 | } | 308 | } |
@@ -319,12 +310,10 @@ err: | |||
319 | static int __devexit s2mps11_pmic_remove(struct platform_device *pdev) | 310 | static int __devexit s2mps11_pmic_remove(struct platform_device *pdev) |
320 | { | 311 | { |
321 | struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev); | 312 | struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev); |
322 | struct regulator_dev **rdev = s2mps11->rdev; | ||
323 | int i; | 313 | int i; |
324 | 314 | ||
325 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) | 315 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) |
326 | if (rdev[i]) | 316 | regulator_unregister(s2mps11->rdev[i]); |
327 | regulator_unregister(rdev[i]); | ||
328 | 317 | ||
329 | return 0; | 318 | return 0; |
330 | } | 319 | } |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77a..ab00cab905b7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/regulator/of_regulator.h> | ||
25 | #include <linux/regulator/driver.h> | 26 | #include <linux/regulator/driver.h> |
26 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
27 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
@@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = { | |||
281 | NULL), | 282 | NULL), |
282 | }; | 283 | }; |
283 | 284 | ||
285 | #ifdef CONFIG_OF | ||
286 | static struct of_regulator_match reg_matches[] = { | ||
287 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
288 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
289 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
290 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
291 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
292 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
293 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
294 | }; | ||
295 | |||
296 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
297 | { | ||
298 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
299 | struct device_node *node = tps->dev->of_node; | ||
300 | struct tps65217_board *pdata; | ||
301 | struct device_node *regs; | ||
302 | int i, count; | ||
303 | |||
304 | regs = of_find_node_by_name(node, "regulators"); | ||
305 | if (!regs) | ||
306 | return NULL; | ||
307 | |||
308 | count = of_regulator_match(pdev->dev.parent, regs, | ||
309 | reg_matches, TPS65217_NUM_REGULATOR); | ||
310 | of_node_put(regs); | ||
311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | ||
312 | return NULL; | ||
313 | |||
314 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
315 | if (!pdata) | ||
316 | return NULL; | ||
317 | |||
318 | for (i = 0; i < count; i++) { | ||
319 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
320 | continue; | ||
321 | |||
322 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
323 | pdata->of_node[i] = reg_matches[i].of_node; | ||
324 | } | ||
325 | |||
326 | return pdata; | ||
327 | } | ||
328 | #else | ||
329 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
330 | { | ||
331 | return NULL; | ||
332 | } | ||
333 | #endif | ||
334 | |||
284 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | 335 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) |
285 | { | 336 | { |
337 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
338 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | ||
339 | struct regulator_init_data *reg_data; | ||
286 | struct regulator_dev *rdev; | 340 | struct regulator_dev *rdev; |
287 | struct tps65217 *tps; | ||
288 | struct tps_info *info = &tps65217_pmic_regs[pdev->id]; | ||
289 | struct regulator_config config = { }; | 341 | struct regulator_config config = { }; |
342 | int i, ret; | ||
290 | 343 | ||
291 | /* Already set by core driver */ | 344 | if (tps->dev->of_node) |
292 | tps = dev_to_tps65217(pdev->dev.parent); | 345 | pdata = tps65217_parse_dt(pdev); |
293 | tps->info[pdev->id] = info; | ||
294 | 346 | ||
295 | config.dev = &pdev->dev; | 347 | if (!pdata) { |
296 | config.of_node = pdev->dev.of_node; | 348 | dev_err(&pdev->dev, "Platform data not found\n"); |
297 | config.init_data = pdev->dev.platform_data; | 349 | return -EINVAL; |
298 | config.driver_data = tps; | 350 | } |
299 | 351 | ||
300 | rdev = regulator_register(®ulators[pdev->id], &config); | 352 | if (tps65217_chip_id(tps) != TPS65217) { |
301 | if (IS_ERR(rdev)) | 353 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
302 | return PTR_ERR(rdev); | 354 | return -ENODEV; |
355 | } | ||
303 | 356 | ||
304 | platform_set_drvdata(pdev, rdev); | 357 | platform_set_drvdata(pdev, tps); |
305 | 358 | ||
359 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
360 | |||
361 | reg_data = pdata->tps65217_init_data[i]; | ||
362 | |||
363 | /* | ||
364 | * Regulator API handles empty constraints but not NULL | ||
365 | * constraints | ||
366 | */ | ||
367 | if (!reg_data) | ||
368 | continue; | ||
369 | |||
370 | /* Register the regulators */ | ||
371 | tps->info[i] = &tps65217_pmic_regs[i]; | ||
372 | |||
373 | config.dev = tps->dev; | ||
374 | config.init_data = reg_data; | ||
375 | config.driver_data = tps; | ||
376 | config.regmap = tps->regmap; | ||
377 | if (tps->dev->of_node) | ||
378 | config.of_node = pdata->of_node[i]; | ||
379 | |||
380 | rdev = regulator_register(®ulators[i], &config); | ||
381 | if (IS_ERR(rdev)) { | ||
382 | dev_err(tps->dev, "failed to register %s regulator\n", | ||
383 | pdev->name); | ||
384 | ret = PTR_ERR(rdev); | ||
385 | goto err_unregister_regulator; | ||
386 | } | ||
387 | |||
388 | /* Save regulator for cleanup */ | ||
389 | tps->rdev[i] = rdev; | ||
390 | } | ||
306 | return 0; | 391 | return 0; |
392 | |||
393 | err_unregister_regulator: | ||
394 | while (--i >= 0) | ||
395 | regulator_unregister(tps->rdev[i]); | ||
396 | |||
397 | return ret; | ||
307 | } | 398 | } |
308 | 399 | ||
309 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) | 400 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) |
310 | { | 401 | { |
311 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | 402 | struct tps65217 *tps = platform_get_drvdata(pdev); |
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | ||
406 | regulator_unregister(tps->rdev[i]); | ||
312 | 407 | ||
313 | platform_set_drvdata(pdev, NULL); | 408 | platform_set_drvdata(pdev, NULL); |
314 | regulator_unregister(rdev); | ||
315 | 409 | ||
316 | return 0; | 410 | return 0; |
317 | } | 411 | } |
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 947ece933d90..058d2f2675e9 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c | |||
@@ -502,15 +502,13 @@ static int set_current_limit(struct regulator_dev *rdev, int min_uA, | |||
502 | if (info->n_ilimsels == 1) | 502 | if (info->n_ilimsels == 1) |
503 | return -EINVAL; | 503 | return -EINVAL; |
504 | 504 | ||
505 | for (i = 0; i < info->n_ilimsels; i++) | 505 | for (i = info->n_ilimsels - 1; i >= 0; i--) { |
506 | if (min_uA <= info->ilimsels[i] && | 506 | if (min_uA <= info->ilimsels[i] && |
507 | max_uA >= info->ilimsels[i]) | 507 | max_uA >= info->ilimsels[i]) |
508 | break; | 508 | return write_field(hw, &info->ilimsel, i); |
509 | 509 | } | |
510 | if (i >= info->n_ilimsels) | ||
511 | return -EINVAL; | ||
512 | 510 | ||
513 | return write_field(hw, &info->ilimsel, i); | 511 | return -EINVAL; |
514 | } | 512 | } |
515 | 513 | ||
516 | static int get_current_limit(struct regulator_dev *rdev) | 514 | static int get_current_limit(struct regulator_dev *rdev) |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index e6da90ab5153..ce1e7cb8d513 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -57,9 +57,6 @@ | |||
57 | struct tps6586x_regulator { | 57 | struct tps6586x_regulator { |
58 | struct regulator_desc desc; | 58 | struct regulator_desc desc; |
59 | 59 | ||
60 | int volt_reg; | ||
61 | int volt_shift; | ||
62 | int volt_nbits; | ||
63 | int enable_bit[2]; | 60 | int enable_bit[2]; |
64 | int enable_reg[2]; | 61 | int enable_reg[2]; |
65 | 62 | ||
@@ -81,10 +78,10 @@ static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, | |||
81 | int ret, val, rid = rdev_get_id(rdev); | 78 | int ret, val, rid = rdev_get_id(rdev); |
82 | uint8_t mask; | 79 | uint8_t mask; |
83 | 80 | ||
84 | val = selector << ri->volt_shift; | 81 | val = selector << (ffs(rdev->desc->vsel_mask) - 1); |
85 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | 82 | mask = rdev->desc->vsel_mask; |
86 | 83 | ||
87 | ret = tps6586x_update(parent, ri->volt_reg, val, mask); | 84 | ret = tps6586x_update(parent, rdev->desc->vsel_reg, val, mask); |
88 | if (ret) | 85 | if (ret) |
89 | return ret; | 86 | return ret; |
90 | 87 | ||
@@ -100,66 +97,17 @@ static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, | |||
100 | return ret; | 97 | return ret; |
101 | } | 98 | } |
102 | 99 | ||
103 | static int tps6586x_get_voltage_sel(struct regulator_dev *rdev) | ||
104 | { | ||
105 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
106 | struct device *parent = to_tps6586x_dev(rdev); | ||
107 | uint8_t val, mask; | ||
108 | int ret; | ||
109 | |||
110 | ret = tps6586x_read(parent, ri->volt_reg, &val); | ||
111 | if (ret) | ||
112 | return ret; | ||
113 | |||
114 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | ||
115 | val = (val & mask) >> ri->volt_shift; | ||
116 | |||
117 | if (val >= ri->desc.n_voltages) | ||
118 | BUG(); | ||
119 | |||
120 | return val; | ||
121 | } | ||
122 | |||
123 | static int tps6586x_regulator_enable(struct regulator_dev *rdev) | ||
124 | { | ||
125 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
126 | struct device *parent = to_tps6586x_dev(rdev); | ||
127 | |||
128 | return tps6586x_set_bits(parent, ri->enable_reg[0], | ||
129 | 1 << ri->enable_bit[0]); | ||
130 | } | ||
131 | |||
132 | static int tps6586x_regulator_disable(struct regulator_dev *rdev) | ||
133 | { | ||
134 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
135 | struct device *parent = to_tps6586x_dev(rdev); | ||
136 | |||
137 | return tps6586x_clr_bits(parent, ri->enable_reg[0], | ||
138 | 1 << ri->enable_bit[0]); | ||
139 | } | ||
140 | |||
141 | static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev) | ||
142 | { | ||
143 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
144 | struct device *parent = to_tps6586x_dev(rdev); | ||
145 | uint8_t reg_val; | ||
146 | int ret; | ||
147 | |||
148 | ret = tps6586x_read(parent, ri->enable_reg[0], ®_val); | ||
149 | if (ret) | ||
150 | return ret; | ||
151 | |||
152 | return !!(reg_val & (1 << ri->enable_bit[0])); | ||
153 | } | ||
154 | |||
155 | static struct regulator_ops tps6586x_regulator_ops = { | 100 | static struct regulator_ops tps6586x_regulator_ops = { |
156 | .list_voltage = regulator_list_voltage_table, | 101 | .list_voltage = regulator_list_voltage_table, |
157 | .get_voltage_sel = tps6586x_get_voltage_sel, | 102 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
158 | .set_voltage_sel = tps6586x_set_voltage_sel, | 103 | .set_voltage_sel = tps6586x_set_voltage_sel, |
159 | 104 | ||
160 | .is_enabled = tps6586x_regulator_is_enabled, | 105 | .is_enabled = regulator_is_enabled_regmap, |
161 | .enable = tps6586x_regulator_enable, | 106 | .enable = regulator_enable_regmap, |
162 | .disable = tps6586x_regulator_disable, | 107 | .disable = regulator_disable_regmap, |
108 | }; | ||
109 | |||
110 | static struct regulator_ops tps6586x_sys_regulator_ops = { | ||
163 | }; | 111 | }; |
164 | 112 | ||
165 | static const unsigned int tps6586x_ldo0_voltages[] = { | 113 | static const unsigned int tps6586x_ldo0_voltages[] = { |
@@ -202,10 +150,11 @@ static const unsigned int tps6586x_dvm_voltages[] = { | |||
202 | .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ | 150 | .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ |
203 | .volt_table = tps6586x_##vdata##_voltages, \ | 151 | .volt_table = tps6586x_##vdata##_voltages, \ |
204 | .owner = THIS_MODULE, \ | 152 | .owner = THIS_MODULE, \ |
153 | .enable_reg = TPS6586X_SUPPLY##ereg0, \ | ||
154 | .enable_mask = 1 << (ebit0), \ | ||
155 | .vsel_reg = TPS6586X_##vreg, \ | ||
156 | .vsel_mask = ((1 << (nbits)) - 1) << (shift), \ | ||
205 | }, \ | 157 | }, \ |
206 | .volt_reg = TPS6586X_##vreg, \ | ||
207 | .volt_shift = (shift), \ | ||
208 | .volt_nbits = (nbits), \ | ||
209 | .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ | 158 | .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ |
210 | .enable_bit[0] = (ebit0), \ | 159 | .enable_bit[0] = (ebit0), \ |
211 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ | 160 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ |
@@ -230,24 +179,39 @@ static const unsigned int tps6586x_dvm_voltages[] = { | |||
230 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | 179 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ |
231 | } | 180 | } |
232 | 181 | ||
182 | #define TPS6586X_SYS_REGULATOR() \ | ||
183 | { \ | ||
184 | .desc = { \ | ||
185 | .supply_name = "sys", \ | ||
186 | .name = "REG-SYS", \ | ||
187 | .ops = &tps6586x_sys_regulator_ops, \ | ||
188 | .type = REGULATOR_VOLTAGE, \ | ||
189 | .id = TPS6586X_ID_SYS, \ | ||
190 | .owner = THIS_MODULE, \ | ||
191 | }, \ | ||
192 | } | ||
193 | |||
233 | static struct tps6586x_regulator tps6586x_regulator[] = { | 194 | static struct tps6586x_regulator tps6586x_regulator[] = { |
195 | TPS6586X_SYS_REGULATOR(), | ||
234 | TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), | 196 | TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), |
235 | TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), | 197 | TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), |
236 | TPS6586X_LDO(LDO_5, NULL, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | 198 | TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), |
237 | TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | 199 | TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), |
238 | TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | 200 | TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), |
239 | TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), | 201 | TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), |
240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 202 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), | 203 | TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 204 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
243 | TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), | 205 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
244 | 206 | ||
245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, | 207 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, |
246 | ENB, 3, VCC2, 6), | 208 | ENB, 3, VCC2, 6), |
247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, | 209 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, |
248 | END, 3, VCC1, 6), | 210 | END, 3, VCC1, 6), |
249 | TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), | 211 | TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1, |
250 | TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), | 212 | ENB, 1, VCC1, 2), |
213 | TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0, | ||
214 | ENB, 0, VCC1, 0), | ||
251 | }; | 215 | }; |
252 | 216 | ||
253 | /* | 217 | /* |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 242fe90dc565..7eb986a40746 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -10,6 +10,8 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/string.h> | ||
14 | #include <linux/slab.h> | ||
13 | #include <linux/init.h> | 15 | #include <linux/init.h> |
14 | #include <linux/err.h> | 16 | #include <linux/err.h> |
15 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
@@ -624,18 +626,9 @@ static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
624 | return info->min_mV * 1000; | 626 | return info->min_mV * 1000; |
625 | } | 627 | } |
626 | 628 | ||
627 | static int twlfixed_get_voltage(struct regulator_dev *rdev) | ||
628 | { | ||
629 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
630 | |||
631 | return info->min_mV * 1000; | ||
632 | } | ||
633 | |||
634 | static struct regulator_ops twl4030fixed_ops = { | 629 | static struct regulator_ops twl4030fixed_ops = { |
635 | .list_voltage = twlfixed_list_voltage, | 630 | .list_voltage = twlfixed_list_voltage, |
636 | 631 | ||
637 | .get_voltage = twlfixed_get_voltage, | ||
638 | |||
639 | .enable = twl4030reg_enable, | 632 | .enable = twl4030reg_enable, |
640 | .disable = twl4030reg_disable, | 633 | .disable = twl4030reg_disable, |
641 | .is_enabled = twl4030reg_is_enabled, | 634 | .is_enabled = twl4030reg_is_enabled, |
@@ -648,8 +641,6 @@ static struct regulator_ops twl4030fixed_ops = { | |||
648 | static struct regulator_ops twl6030fixed_ops = { | 641 | static struct regulator_ops twl6030fixed_ops = { |
649 | .list_voltage = twlfixed_list_voltage, | 642 | .list_voltage = twlfixed_list_voltage, |
650 | 643 | ||
651 | .get_voltage = twlfixed_get_voltage, | ||
652 | |||
653 | .enable = twl6030reg_enable, | 644 | .enable = twl6030reg_enable, |
654 | .disable = twl6030reg_disable, | 645 | .disable = twl6030reg_disable, |
655 | .is_enabled = twl6030reg_is_enabled, | 646 | .is_enabled = twl6030reg_is_enabled, |
@@ -659,13 +650,6 @@ static struct regulator_ops twl6030fixed_ops = { | |||
659 | .get_status = twl6030reg_get_status, | 650 | .get_status = twl6030reg_get_status, |
660 | }; | 651 | }; |
661 | 652 | ||
662 | static struct regulator_ops twl6030_fixed_resource = { | ||
663 | .enable = twl6030reg_enable, | ||
664 | .disable = twl6030reg_disable, | ||
665 | .is_enabled = twl6030reg_is_enabled, | ||
666 | .get_status = twl6030reg_get_status, | ||
667 | }; | ||
668 | |||
669 | /* | 653 | /* |
670 | * SMPS status and control | 654 | * SMPS status and control |
671 | */ | 655 | */ |
@@ -757,37 +741,32 @@ static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
757 | return voltage; | 741 | return voltage; |
758 | } | 742 | } |
759 | 743 | ||
760 | static int | 744 | static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV, |
761 | twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | 745 | int max_uV) |
762 | unsigned int *selector) | ||
763 | { | 746 | { |
764 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 747 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
765 | int vsel = 0; | 748 | int vsel = 0; |
766 | 749 | ||
767 | switch (info->flags) { | 750 | switch (info->flags) { |
768 | case 0: | 751 | case 0: |
769 | if (min_uV == 0) | 752 | if (min_uV == 0) |
770 | vsel = 0; | 753 | vsel = 0; |
771 | else if ((min_uV >= 600000) && (min_uV <= 1300000)) { | 754 | else if ((min_uV >= 600000) && (min_uV <= 1300000)) { |
772 | int calc_uV; | ||
773 | vsel = DIV_ROUND_UP(min_uV - 600000, 12500); | 755 | vsel = DIV_ROUND_UP(min_uV - 600000, 12500); |
774 | vsel++; | 756 | vsel++; |
775 | calc_uV = twl6030smps_list_voltage(rdev, vsel); | ||
776 | if (calc_uV > max_uV) | ||
777 | return -EINVAL; | ||
778 | } | 757 | } |
779 | /* Values 1..57 for vsel are linear and can be calculated | 758 | /* Values 1..57 for vsel are linear and can be calculated |
780 | * values 58..62 are non linear. | 759 | * values 58..62 are non linear. |
781 | */ | 760 | */ |
782 | else if ((min_uV > 1900000) && (max_uV >= 2100000)) | 761 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) |
783 | vsel = 62; | 762 | vsel = 62; |
784 | else if ((min_uV > 1800000) && (max_uV >= 1900000)) | 763 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) |
785 | vsel = 61; | 764 | vsel = 61; |
786 | else if ((min_uV > 1500000) && (max_uV >= 1800000)) | 765 | else if ((min_uV > 1500000) && (min_uV <= 1800000)) |
787 | vsel = 60; | 766 | vsel = 60; |
788 | else if ((min_uV > 1350000) && (max_uV >= 1500000)) | 767 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) |
789 | vsel = 59; | 768 | vsel = 59; |
790 | else if ((min_uV > 1300000) && (max_uV >= 1350000)) | 769 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) |
791 | vsel = 58; | 770 | vsel = 58; |
792 | else | 771 | else |
793 | return -EINVAL; | 772 | return -EINVAL; |
@@ -796,25 +775,21 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
796 | if (min_uV == 0) | 775 | if (min_uV == 0) |
797 | vsel = 0; | 776 | vsel = 0; |
798 | else if ((min_uV >= 700000) && (min_uV <= 1420000)) { | 777 | else if ((min_uV >= 700000) && (min_uV <= 1420000)) { |
799 | int calc_uV; | ||
800 | vsel = DIV_ROUND_UP(min_uV - 700000, 12500); | 778 | vsel = DIV_ROUND_UP(min_uV - 700000, 12500); |
801 | vsel++; | 779 | vsel++; |
802 | calc_uV = twl6030smps_list_voltage(rdev, vsel); | ||
803 | if (calc_uV > max_uV) | ||
804 | return -EINVAL; | ||
805 | } | 780 | } |
806 | /* Values 1..57 for vsel are linear and can be calculated | 781 | /* Values 1..57 for vsel are linear and can be calculated |
807 | * values 58..62 are non linear. | 782 | * values 58..62 are non linear. |
808 | */ | 783 | */ |
809 | else if ((min_uV > 1900000) && (max_uV >= 2100000)) | 784 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) |
810 | vsel = 62; | 785 | vsel = 62; |
811 | else if ((min_uV > 1800000) && (max_uV >= 1900000)) | 786 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) |
812 | vsel = 61; | 787 | vsel = 61; |
813 | else if ((min_uV > 1350000) && (max_uV >= 1800000)) | 788 | else if ((min_uV > 1350000) && (min_uV <= 1800000)) |
814 | vsel = 60; | 789 | vsel = 60; |
815 | else if ((min_uV > 1350000) && (max_uV >= 1500000)) | 790 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) |
816 | vsel = 59; | 791 | vsel = 59; |
817 | else if ((min_uV > 1300000) && (max_uV >= 1350000)) | 792 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) |
818 | vsel = 58; | 793 | vsel = 58; |
819 | else | 794 | else |
820 | return -EINVAL; | 795 | return -EINVAL; |
@@ -830,17 +805,23 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
830 | case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: | 805 | case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: |
831 | if (min_uV == 0) { | 806 | if (min_uV == 0) { |
832 | vsel = 0; | 807 | vsel = 0; |
833 | } else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { | 808 | } else if ((min_uV >= 2161000) && (min_uV <= 4321000)) { |
834 | vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); | 809 | vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); |
835 | vsel++; | 810 | vsel++; |
836 | } | 811 | } |
837 | break; | 812 | break; |
838 | } | 813 | } |
839 | 814 | ||
840 | *selector = vsel; | 815 | return vsel; |
816 | } | ||
817 | |||
818 | static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev, | ||
819 | unsigned int selector) | ||
820 | { | ||
821 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
841 | 822 | ||
842 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS, | 823 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS, |
843 | vsel); | 824 | selector); |
844 | } | 825 | } |
845 | 826 | ||
846 | static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) | 827 | static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) |
@@ -852,8 +833,9 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) | |||
852 | 833 | ||
853 | static struct regulator_ops twlsmps_ops = { | 834 | static struct regulator_ops twlsmps_ops = { |
854 | .list_voltage = twl6030smps_list_voltage, | 835 | .list_voltage = twl6030smps_list_voltage, |
836 | .map_voltage = twl6030smps_map_voltage, | ||
855 | 837 | ||
856 | .set_voltage = twl6030smps_set_voltage, | 838 | .set_voltage_sel = twl6030smps_set_voltage_sel, |
857 | .get_voltage_sel = twl6030smps_get_voltage_sel, | 839 | .get_voltage_sel = twl6030smps_get_voltage_sel, |
858 | 840 | ||
859 | .enable = twl6030reg_enable, | 841 | .enable = twl6030reg_enable, |
@@ -876,7 +858,7 @@ static struct regulator_ops twlsmps_ops = { | |||
876 | 0x0, TWL6030, twl6030fixed_ops) | 858 | 0x0, TWL6030, twl6030fixed_ops) |
877 | 859 | ||
878 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ | 860 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ |
879 | static struct twlreg_info TWL4030_INFO_##label = { \ | 861 | static const struct twlreg_info TWL4030_INFO_##label = { \ |
880 | .base = offset, \ | 862 | .base = offset, \ |
881 | .id = num, \ | 863 | .id = num, \ |
882 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ | 864 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ |
@@ -894,7 +876,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ | |||
894 | } | 876 | } |
895 | 877 | ||
896 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ | 878 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ |
897 | static struct twlreg_info TWL4030_INFO_##label = { \ | 879 | static const struct twlreg_info TWL4030_INFO_##label = { \ |
898 | .base = offset, \ | 880 | .base = offset, \ |
899 | .id = num, \ | 881 | .id = num, \ |
900 | .remap = remap_conf, \ | 882 | .remap = remap_conf, \ |
@@ -909,7 +891,7 @@ static struct twlreg_info TWL4030_INFO_##label = { \ | |||
909 | } | 891 | } |
910 | 892 | ||
911 | #define TWL6030_ADJUSTABLE_SMPS(label) \ | 893 | #define TWL6030_ADJUSTABLE_SMPS(label) \ |
912 | static struct twlreg_info TWL6030_INFO_##label = { \ | 894 | static const struct twlreg_info TWL6030_INFO_##label = { \ |
913 | .desc = { \ | 895 | .desc = { \ |
914 | .name = #label, \ | 896 | .name = #label, \ |
915 | .id = TWL6030_REG_##label, \ | 897 | .id = TWL6030_REG_##label, \ |
@@ -920,7 +902,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \ | |||
920 | } | 902 | } |
921 | 903 | ||
922 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ | 904 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ |
923 | static struct twlreg_info TWL6030_INFO_##label = { \ | 905 | static const struct twlreg_info TWL6030_INFO_##label = { \ |
924 | .base = offset, \ | 906 | .base = offset, \ |
925 | .min_mV = min_mVolts, \ | 907 | .min_mV = min_mVolts, \ |
926 | .max_mV = max_mVolts, \ | 908 | .max_mV = max_mVolts, \ |
@@ -935,7 +917,7 @@ static struct twlreg_info TWL6030_INFO_##label = { \ | |||
935 | } | 917 | } |
936 | 918 | ||
937 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ | 919 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ |
938 | static struct twlreg_info TWL6025_INFO_##label = { \ | 920 | static const struct twlreg_info TWL6025_INFO_##label = { \ |
939 | .base = offset, \ | 921 | .base = offset, \ |
940 | .min_mV = min_mVolts, \ | 922 | .min_mV = min_mVolts, \ |
941 | .max_mV = max_mVolts, \ | 923 | .max_mV = max_mVolts, \ |
@@ -951,7 +933,7 @@ static struct twlreg_info TWL6025_INFO_##label = { \ | |||
951 | 933 | ||
952 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ | 934 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ |
953 | family, operations) \ | 935 | family, operations) \ |
954 | static struct twlreg_info TWLFIXED_INFO_##label = { \ | 936 | static const struct twlreg_info TWLFIXED_INFO_##label = { \ |
955 | .base = offset, \ | 937 | .base = offset, \ |
956 | .id = num, \ | 938 | .id = num, \ |
957 | .min_mV = mVolts, \ | 939 | .min_mV = mVolts, \ |
@@ -981,7 +963,7 @@ static struct twlreg_info TWLRES_INFO_##label = { \ | |||
981 | } | 963 | } |
982 | 964 | ||
983 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ | 965 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ |
984 | static struct twlreg_info TWLSMPS_INFO_##label = { \ | 966 | static const struct twlreg_info TWLSMPS_INFO_##label = { \ |
985 | .base = offset, \ | 967 | .base = offset, \ |
986 | .min_mV = 600, \ | 968 | .min_mV = 600, \ |
987 | .max_mV = 2100, \ | 969 | .max_mV = 2100, \ |
@@ -1037,7 +1019,7 @@ TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); | |||
1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); | 1019 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); | 1020 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | 1021 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); |
1040 | TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08); | 1022 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); |
1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); | 1023 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); | 1024 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); | 1025 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
@@ -1048,7 +1030,6 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); | |||
1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); | 1030 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); | 1031 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | 1032 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); |
1051 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0); | ||
1052 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); | 1033 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
1053 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); | 1034 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
1054 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); | 1035 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
@@ -1117,7 +1098,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { | |||
1117 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | 1098 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), |
1118 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | 1099 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), |
1119 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | 1100 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), |
1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | 1101 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), |
1121 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | 1102 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), |
1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | 1103 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), |
1123 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | 1104 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), |
@@ -1139,6 +1120,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1139 | { | 1120 | { |
1140 | int i, id; | 1121 | int i, id; |
1141 | struct twlreg_info *info; | 1122 | struct twlreg_info *info; |
1123 | const struct twlreg_info *template; | ||
1142 | struct regulator_init_data *initdata; | 1124 | struct regulator_init_data *initdata; |
1143 | struct regulation_constraints *c; | 1125 | struct regulation_constraints *c; |
1144 | struct regulator_dev *rdev; | 1126 | struct regulator_dev *rdev; |
@@ -1148,17 +1130,17 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1148 | 1130 | ||
1149 | match = of_match_device(twl_of_match, &pdev->dev); | 1131 | match = of_match_device(twl_of_match, &pdev->dev); |
1150 | if (match) { | 1132 | if (match) { |
1151 | info = match->data; | 1133 | template = match->data; |
1152 | id = info->desc.id; | 1134 | id = template->desc.id; |
1153 | initdata = of_get_regulator_init_data(&pdev->dev, | 1135 | initdata = of_get_regulator_init_data(&pdev->dev, |
1154 | pdev->dev.of_node); | 1136 | pdev->dev.of_node); |
1155 | drvdata = NULL; | 1137 | drvdata = NULL; |
1156 | } else { | 1138 | } else { |
1157 | id = pdev->id; | 1139 | id = pdev->id; |
1158 | initdata = pdev->dev.platform_data; | 1140 | initdata = pdev->dev.platform_data; |
1159 | for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { | 1141 | for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) { |
1160 | info = twl_of_match[i].data; | 1142 | template = twl_of_match[i].data; |
1161 | if (info && info->desc.id == id) | 1143 | if (template && template->desc.id == id) |
1162 | break; | 1144 | break; |
1163 | } | 1145 | } |
1164 | if (i == ARRAY_SIZE(twl_of_match)) | 1146 | if (i == ARRAY_SIZE(twl_of_match)) |
@@ -1169,12 +1151,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1169 | return -EINVAL; | 1151 | return -EINVAL; |
1170 | } | 1152 | } |
1171 | 1153 | ||
1172 | if (!info) | 1154 | if (!template) |
1173 | return -ENODEV; | 1155 | return -ENODEV; |
1174 | 1156 | ||
1175 | if (!initdata) | 1157 | if (!initdata) |
1176 | return -EINVAL; | 1158 | return -EINVAL; |
1177 | 1159 | ||
1160 | info = kmemdup(template, sizeof (*info), GFP_KERNEL); | ||
1161 | if (!info) | ||
1162 | return -ENOMEM; | ||
1163 | |||
1178 | if (drvdata) { | 1164 | if (drvdata) { |
1179 | /* copy the driver data into regulator data */ | 1165 | /* copy the driver data into regulator data */ |
1180 | info->features = drvdata->features; | 1166 | info->features = drvdata->features; |
@@ -1235,6 +1221,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1235 | if (IS_ERR(rdev)) { | 1221 | if (IS_ERR(rdev)) { |
1236 | dev_err(&pdev->dev, "can't register %s, %ld\n", | 1222 | dev_err(&pdev->dev, "can't register %s, %ld\n", |
1237 | info->desc.name, PTR_ERR(rdev)); | 1223 | info->desc.name, PTR_ERR(rdev)); |
1224 | kfree(info); | ||
1238 | return PTR_ERR(rdev); | 1225 | return PTR_ERR(rdev); |
1239 | } | 1226 | } |
1240 | platform_set_drvdata(pdev, rdev); | 1227 | platform_set_drvdata(pdev, rdev); |
@@ -1256,7 +1243,11 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1256 | 1243 | ||
1257 | static int __devexit twlreg_remove(struct platform_device *pdev) | 1244 | static int __devexit twlreg_remove(struct platform_device *pdev) |
1258 | { | 1245 | { |
1259 | regulator_unregister(platform_get_drvdata(pdev)); | 1246 | struct regulator_dev *rdev = platform_get_drvdata(pdev); |
1247 | struct twlreg_info *info = rdev->reg_data; | ||
1248 | |||
1249 | regulator_unregister(rdev); | ||
1250 | kfree(info); | ||
1260 | return 0; | 1251 | return 0; |
1261 | } | 1252 | } |
1262 | 1253 | ||
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 7413885be01b..90cbcc683704 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -339,16 +339,15 @@ static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, | |||
339 | u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2; | 339 | u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2; |
340 | int i; | 340 | int i; |
341 | 341 | ||
342 | for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) { | 342 | for (i = ARRAY_SIZE(wm831x_dcdc_ilim) - 1; i >= 0; i--) { |
343 | if ((min_uA <= wm831x_dcdc_ilim[i]) && | 343 | if ((min_uA <= wm831x_dcdc_ilim[i]) && |
344 | (wm831x_dcdc_ilim[i] <= max_uA)) | 344 | (wm831x_dcdc_ilim[i] <= max_uA)) |
345 | break; | 345 | return wm831x_set_bits(wm831x, reg, |
346 | WM831X_DC1_HC_THR_MASK, | ||
347 | i << WM831X_DC1_HC_THR_SHIFT); | ||
346 | } | 348 | } |
347 | if (i == ARRAY_SIZE(wm831x_dcdc_ilim)) | ||
348 | return -EINVAL; | ||
349 | 349 | ||
350 | return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, | 350 | return -EINVAL; |
351 | i << WM831X_DC1_HC_THR_SHIFT); | ||
352 | } | 351 | } |
353 | 352 | ||
354 | static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) | 353 | static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) |
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 5cb70ca1e98d..9af512672be1 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
@@ -205,6 +205,8 @@ static int wm831x_gp_ldo_get_status(struct regulator_dev *rdev) | |||
205 | 205 | ||
206 | /* Is it reporting under voltage? */ | 206 | /* Is it reporting under voltage? */ |
207 | ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS); | 207 | ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS); |
208 | if (ret < 0) | ||
209 | return ret; | ||
208 | if (ret & mask) | 210 | if (ret & mask) |
209 | return REGULATOR_STATUS_ERROR; | 211 | return REGULATOR_STATUS_ERROR; |
210 | 212 | ||
@@ -237,6 +239,8 @@ static struct regulator_ops wm831x_gp_ldo_ops = { | |||
237 | .set_mode = wm831x_gp_ldo_set_mode, | 239 | .set_mode = wm831x_gp_ldo_set_mode, |
238 | .get_status = wm831x_gp_ldo_get_status, | 240 | .get_status = wm831x_gp_ldo_get_status, |
239 | .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode, | 241 | .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode, |
242 | .get_bypass = regulator_get_bypass_regmap, | ||
243 | .set_bypass = regulator_set_bypass_regmap, | ||
240 | 244 | ||
241 | .is_enabled = regulator_is_enabled_regmap, | 245 | .is_enabled = regulator_is_enabled_regmap, |
242 | .enable = regulator_enable_regmap, | 246 | .enable = regulator_enable_regmap, |
@@ -293,6 +297,8 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) | |||
293 | ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK; | 297 | ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK; |
294 | ldo->desc.enable_reg = WM831X_LDO_ENABLE; | 298 | ldo->desc.enable_reg = WM831X_LDO_ENABLE; |
295 | ldo->desc.enable_mask = 1 << id; | 299 | ldo->desc.enable_mask = 1 << id; |
300 | ldo->desc.bypass_reg = ldo->base; | ||
301 | ldo->desc.bypass_mask = WM831X_LDO1_SWI; | ||
296 | 302 | ||
297 | config.dev = pdev->dev.parent; | 303 | config.dev = pdev->dev.parent; |
298 | if (pdata) | 304 | if (pdata) |
@@ -469,6 +475,8 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) | |||
469 | 475 | ||
470 | /* Is it reporting under voltage? */ | 476 | /* Is it reporting under voltage? */ |
471 | ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS); | 477 | ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS); |
478 | if (ret < 0) | ||
479 | return ret; | ||
472 | if (ret & mask) | 480 | if (ret & mask) |
473 | return REGULATOR_STATUS_ERROR; | 481 | return REGULATOR_STATUS_ERROR; |
474 | 482 | ||
@@ -488,6 +496,8 @@ static struct regulator_ops wm831x_aldo_ops = { | |||
488 | .get_mode = wm831x_aldo_get_mode, | 496 | .get_mode = wm831x_aldo_get_mode, |
489 | .set_mode = wm831x_aldo_set_mode, | 497 | .set_mode = wm831x_aldo_set_mode, |
490 | .get_status = wm831x_aldo_get_status, | 498 | .get_status = wm831x_aldo_get_status, |
499 | .set_bypass = regulator_set_bypass_regmap, | ||
500 | .get_bypass = regulator_get_bypass_regmap, | ||
491 | 501 | ||
492 | .is_enabled = regulator_is_enabled_regmap, | 502 | .is_enabled = regulator_is_enabled_regmap, |
493 | .enable = regulator_enable_regmap, | 503 | .enable = regulator_enable_regmap, |
@@ -544,6 +554,8 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) | |||
544 | ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK; | 554 | ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK; |
545 | ldo->desc.enable_reg = WM831X_LDO_ENABLE; | 555 | ldo->desc.enable_reg = WM831X_LDO_ENABLE; |
546 | ldo->desc.enable_mask = 1 << id; | 556 | ldo->desc.enable_mask = 1 << id; |
557 | ldo->desc.bypass_reg = ldo->base; | ||
558 | ldo->desc.bypass_mask = WM831X_LDO7_SWI; | ||
547 | 559 | ||
548 | config.dev = pdev->dev.parent; | 560 | config.dev = pdev->dev.parent; |
549 | if (pdata) | 561 | if (pdata) |
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 9035dd053611..27c746ef0636 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c | |||
@@ -120,13 +120,8 @@ static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode) | |||
120 | 120 | ||
121 | case REGULATOR_MODE_IDLE: | 121 | case REGULATOR_MODE_IDLE: |
122 | /* Datasheet: standby */ | 122 | /* Datasheet: standby */ |
123 | ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, | ||
124 | WM8400_DC1_ACTIVE, 0); | ||
125 | if (ret != 0) | ||
126 | return ret; | ||
127 | return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, | 123 | return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, |
128 | WM8400_DC1_SLEEP, 0); | 124 | WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0); |
129 | |||
130 | default: | 125 | default: |
131 | return -EINVAL; | 126 | return -EINVAL; |
132 | } | 127 | } |