diff options
Diffstat (limited to 'drivers')
36 files changed, 3456 insertions, 1038 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 54727ef005d6..806680d1bbb4 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -618,6 +618,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
618 | unsigned num_consumers, unsigned long features) | 618 | unsigned num_consumers, unsigned long features) |
619 | { | 619 | { |
620 | unsigned sub_chip_id; | 620 | unsigned sub_chip_id; |
621 | struct twl_regulator_driver_data drv_data; | ||
622 | |||
621 | /* regulator framework demands init_data ... */ | 623 | /* regulator framework demands init_data ... */ |
622 | if (!pdata) | 624 | if (!pdata) |
623 | return NULL; | 625 | return NULL; |
@@ -627,7 +629,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
627 | pdata->num_consumer_supplies = num_consumers; | 629 | pdata->num_consumer_supplies = num_consumers; |
628 | } | 630 | } |
629 | 631 | ||
630 | pdata->driver_data = (void *)features; | 632 | if (pdata->driver_data) { |
633 | /* If we have existing drv_data, just add the flags */ | ||
634 | struct twl_regulator_driver_data *tmp; | ||
635 | tmp = pdata->driver_data; | ||
636 | tmp->features |= features; | ||
637 | } else { | ||
638 | /* add new driver data struct, used only during init */ | ||
639 | drv_data.features = features; | ||
640 | drv_data.set_voltage = NULL; | ||
641 | drv_data.get_voltage = NULL; | ||
642 | drv_data.data = NULL; | ||
643 | pdata->driver_data = &drv_data; | ||
644 | } | ||
631 | 645 | ||
632 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ | 646 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ |
633 | sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; | 647 | sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; |
@@ -750,9 +764,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
750 | 764 | ||
751 | /* we need to connect regulators to this transceiver */ | 765 | /* we need to connect regulators to this transceiver */ |
752 | if (twl_has_regulator() && child) { | 766 | if (twl_has_regulator() && child) { |
753 | usb1v5.dev = child; | 767 | usb1v5.dev_name = dev_name(child); |
754 | usb1v8.dev = child; | 768 | usb1v8.dev_name = dev_name(child); |
755 | usb3v1.dev = child; | 769 | usb3v1.dev_name = dev_name(child); |
756 | } | 770 | } |
757 | } | 771 | } |
758 | if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { | 772 | if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { |
@@ -798,7 +812,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
798 | return PTR_ERR(child); | 812 | return PTR_ERR(child); |
799 | /* we need to connect regulators to this transceiver */ | 813 | /* we need to connect regulators to this transceiver */ |
800 | if (twl_has_regulator() && child) | 814 | if (twl_has_regulator() && child) |
801 | usb3v3.dev = child; | 815 | usb3v3.dev_name = dev_name(child); |
802 | } else if (twl_has_regulator() && twl_class_is_6030()) { | 816 | } else if (twl_has_regulator() && twl_class_is_6030()) { |
803 | if (features & TWL6025_SUBCLASS) | 817 | if (features & TWL6025_SUBCLASS) |
804 | child = add_regulator(TWL6025_REG_LDOUSB, | 818 | child = add_regulator(TWL6025_REG_LDOUSB, |
@@ -934,6 +948,31 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
934 | /* twl6030 regulators */ | 948 | /* twl6030 regulators */ |
935 | if (twl_has_regulator() && twl_class_is_6030() && | 949 | if (twl_has_regulator() && twl_class_is_6030() && |
936 | !(features & TWL6025_SUBCLASS)) { | 950 | !(features & TWL6025_SUBCLASS)) { |
951 | child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1, | ||
952 | features); | ||
953 | if (IS_ERR(child)) | ||
954 | return PTR_ERR(child); | ||
955 | |||
956 | child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2, | ||
957 | features); | ||
958 | if (IS_ERR(child)) | ||
959 | return PTR_ERR(child); | ||
960 | |||
961 | child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3, | ||
962 | features); | ||
963 | if (IS_ERR(child)) | ||
964 | return PTR_ERR(child); | ||
965 | |||
966 | child = add_regulator(TWL6030_REG_V1V8, pdata->v1v8, | ||
967 | features); | ||
968 | if (IS_ERR(child)) | ||
969 | return PTR_ERR(child); | ||
970 | |||
971 | child = add_regulator(TWL6030_REG_V2V1, pdata->v2v1, | ||
972 | features); | ||
973 | if (IS_ERR(child)) | ||
974 | return PTR_ERR(child); | ||
975 | |||
937 | child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc, | 976 | child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc, |
938 | features); | 977 | features); |
939 | if (IS_ERR(child)) | 978 | if (IS_ERR(child)) |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 7a61b17ddd04..a229de98ae6f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -74,13 +74,72 @@ config REGULATOR_GPIO | |||
74 | and the platform has to provide a mapping of GPIO-states | 74 | and the platform has to provide a mapping of GPIO-states |
75 | to target volts/amps. | 75 | to target volts/amps. |
76 | 76 | ||
77 | config REGULATOR_BQ24022 | 77 | config REGULATOR_AD5398 |
78 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" | 78 | tristate "Analog Devices AD5398/AD5821 regulators" |
79 | depends on I2C | ||
79 | help | 80 | help |
80 | This driver controls a TI bq24022 Charger attached via | 81 | This driver supports AD5398 and AD5821 current regulator chips. |
81 | GPIOs. The provided current regulator can enable/disable | 82 | If building into module, its name is ad5398.ko. |
82 | charging select between 100 mA and 500 mA charging current | 83 | |
83 | limit. | 84 | config REGULATOR_AAT2870 |
85 | tristate "AnalogicTech AAT2870 Regulators" | ||
86 | depends on MFD_AAT2870_CORE | ||
87 | help | ||
88 | If you have a AnalogicTech AAT2870 say Y to enable the | ||
89 | regulator driver. | ||
90 | |||
91 | config REGULATOR_DA903X | ||
92 | tristate "Dialog Semiconductor DA9030/DA9034 regulators" | ||
93 | depends on PMIC_DA903X | ||
94 | help | ||
95 | Say y here to support the BUCKs and LDOs regulators found on | ||
96 | Dialog Semiconductor DA9030/DA9034 PMIC. | ||
97 | |||
98 | config REGULATOR_DA9052 | ||
99 | tristate "Dialog Semiconductor DA9052/DA9053 regulators" | ||
100 | depends on PMIC_DA9052 | ||
101 | help | ||
102 | This driver supports the voltage regulators of DA9052-BC and | ||
103 | DA9053-AA/Bx PMIC. | ||
104 | |||
105 | config REGULATOR_ANATOP | ||
106 | tristate "Freescale i.MX on-chip ANATOP LDO regulators" | ||
107 | depends on MFD_ANATOP | ||
108 | help | ||
109 | Say y here to support Freescale i.MX on-chip ANATOP LDOs | ||
110 | regulators. It is recommended that this option be | ||
111 | enabled on i.MX6 platform. | ||
112 | |||
113 | config REGULATOR_MC13XXX_CORE | ||
114 | tristate | ||
115 | |||
116 | config REGULATOR_MC13783 | ||
117 | tristate "Freescale MC13783 regulator driver" | ||
118 | depends on MFD_MC13783 | ||
119 | select REGULATOR_MC13XXX_CORE | ||
120 | help | ||
121 | Say y here to support the regulators found on the Freescale MC13783 | ||
122 | PMIC. | ||
123 | |||
124 | config REGULATOR_MC13892 | ||
125 | tristate "Freescale MC13892 regulator driver" | ||
126 | depends on MFD_MC13XXX | ||
127 | select REGULATOR_MC13XXX_CORE | ||
128 | help | ||
129 | Say y here to support the regulators found on the Freescale MC13892 | ||
130 | PMIC. | ||
131 | |||
132 | config REGULATOR_ISL6271A | ||
133 | tristate "Intersil ISL6271A Power regulator" | ||
134 | depends on I2C | ||
135 | help | ||
136 | This driver supports ISL6271A voltage regulator chip. | ||
137 | |||
138 | config REGULATOR_88PM8607 | ||
139 | bool "Marvell 88PM8607 Power regulators" | ||
140 | depends on MFD_88PM860X=y | ||
141 | help | ||
142 | This driver supports 88PM8607 voltage regulator chips. | ||
84 | 143 | ||
85 | config REGULATOR_MAX1586 | 144 | config REGULATOR_MAX1586 |
86 | tristate "Maxim 1586/1587 voltage regulator" | 145 | tristate "Maxim 1586/1587 voltage regulator" |
@@ -136,61 +195,12 @@ config REGULATOR_MAX8998 | |||
136 | via I2C bus. The provided regulator is suitable for S3C6410 | 195 | via I2C bus. The provided regulator is suitable for S3C6410 |
137 | and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. | 196 | and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. |
138 | 197 | ||
139 | config REGULATOR_TWL4030 | 198 | config REGULATOR_PCAP |
140 | bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" | 199 | tristate "Motorola PCAP2 regulator driver" |
141 | depends on TWL4030_CORE | 200 | depends on EZX_PCAP |
142 | help | ||
143 | This driver supports the voltage regulators provided by | ||
144 | this family of companion chips. | ||
145 | |||
146 | config REGULATOR_WM831X | ||
147 | tristate "Wolfson Microelcronics WM831x PMIC regulators" | ||
148 | depends on MFD_WM831X | ||
149 | help | ||
150 | Support the voltage and current regulators of the WM831x series | ||
151 | of PMIC devices. | ||
152 | |||
153 | config REGULATOR_WM8350 | ||
154 | tristate "Wolfson Microelectronics WM8350 AudioPlus PMIC" | ||
155 | depends on MFD_WM8350 | ||
156 | help | ||
157 | This driver provides support for the voltage and current regulators | ||
158 | of the WM8350 AudioPlus PMIC. | ||
159 | |||
160 | config REGULATOR_WM8400 | ||
161 | tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC" | ||
162 | depends on MFD_WM8400 | ||
163 | help | ||
164 | This driver provides support for the voltage regulators of the | ||
165 | WM8400 AudioPlus PMIC. | ||
166 | |||
167 | config REGULATOR_WM8994 | ||
168 | tristate "Wolfson Microelectronics WM8994 CODEC" | ||
169 | depends on MFD_WM8994 | ||
170 | help | ||
171 | This driver provides support for the voltage regulators on the | ||
172 | WM8994 CODEC. | ||
173 | |||
174 | config REGULATOR_DA903X | ||
175 | tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" | ||
176 | depends on PMIC_DA903X | ||
177 | help | ||
178 | Say y here to support the BUCKs and LDOs regulators found on | ||
179 | Dialog Semiconductor DA9030/DA9034 PMIC. | ||
180 | |||
181 | config REGULATOR_DA9052 | ||
182 | tristate "Dialog DA9052/DA9053 regulators" | ||
183 | depends on PMIC_DA9052 | ||
184 | help | ||
185 | This driver supports the voltage regulators of DA9052-BC and | ||
186 | DA9053-AA/Bx PMIC. | ||
187 | |||
188 | config REGULATOR_PCF50633 | ||
189 | tristate "PCF50633 regulator driver" | ||
190 | depends on MFD_PCF50633 | ||
191 | help | 201 | help |
192 | Say Y here to support the voltage regulators and convertors | 202 | This driver provides support for the voltage regulators of the |
193 | on PCF50633 | 203 | PCAP2 PMIC. |
194 | 204 | ||
195 | config REGULATOR_LP3971 | 205 | config REGULATOR_LP3971 |
196 | tristate "National Semiconductors LP3971 PMIC regulator driver" | 206 | tristate "National Semiconductors LP3971 PMIC regulator driver" |
@@ -206,31 +216,20 @@ config REGULATOR_LP3972 | |||
206 | Say Y here to support the voltage regulators and convertors | 216 | Say Y here to support the voltage regulators and convertors |
207 | on National Semiconductors LP3972 PMIC | 217 | on National Semiconductors LP3972 PMIC |
208 | 218 | ||
209 | config REGULATOR_PCAP | 219 | config REGULATOR_PCF50633 |
210 | tristate "PCAP2 regulator driver" | 220 | tristate "NXP PCF50633 regulator driver" |
211 | depends on EZX_PCAP | 221 | depends on MFD_PCF50633 |
212 | help | ||
213 | This driver provides support for the voltage regulators of the | ||
214 | PCAP2 PMIC. | ||
215 | |||
216 | config REGULATOR_MC13XXX_CORE | ||
217 | tristate | ||
218 | |||
219 | config REGULATOR_MC13783 | ||
220 | tristate "Support regulators on Freescale MC13783 PMIC" | ||
221 | depends on MFD_MC13783 | ||
222 | select REGULATOR_MC13XXX_CORE | ||
223 | help | 222 | help |
224 | Say y here to support the regulators found on the Freescale MC13783 | 223 | Say Y here to support the voltage regulators and convertors |
225 | PMIC. | 224 | on PCF50633 |
226 | 225 | ||
227 | config REGULATOR_MC13892 | 226 | config REGULATOR_S5M8767 |
228 | tristate "Support regulators on Freescale MC13892 PMIC" | 227 | tristate "Samsung S5M8767A voltage regulator" |
229 | depends on MFD_MC13XXX | 228 | depends on MFD_S5M_CORE |
230 | select REGULATOR_MC13XXX_CORE | ||
231 | help | 229 | help |
232 | Say y here to support the regulators found on the Freescale MC13892 | 230 | This driver supports a Samsung S5M8767A voltage output regulator |
233 | PMIC. | 231 | via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and |
232 | supports DVS mode with 8bits of output voltage control. | ||
234 | 233 | ||
235 | config REGULATOR_AB3100 | 234 | config REGULATOR_AB3100 |
236 | tristate "ST-Ericsson AB3100 Regulator functions" | 235 | tristate "ST-Ericsson AB3100 Regulator functions" |
@@ -241,6 +240,32 @@ config REGULATOR_AB3100 | |||
241 | AB3100 analog baseband dealing with power regulators | 240 | AB3100 analog baseband dealing with power regulators |
242 | for the system. | 241 | for the system. |
243 | 242 | ||
243 | config REGULATOR_AB8500 | ||
244 | bool "ST-Ericsson AB8500 Power Regulators" | ||
245 | depends on AB8500_CORE | ||
246 | help | ||
247 | This driver supports the regulators found on the ST-Ericsson mixed | ||
248 | signal AB8500 PMIC | ||
249 | |||
250 | config REGULATOR_DBX500_PRCMU | ||
251 | bool | ||
252 | |||
253 | config REGULATOR_DB8500_PRCMU | ||
254 | bool "ST-Ericsson DB8500 Voltage Domain Regulators" | ||
255 | depends on MFD_DB8500_PRCMU | ||
256 | select REGULATOR_DBX500_PRCMU | ||
257 | help | ||
258 | This driver supports the voltage domain regulators controlled by the | ||
259 | DB8500 PRCMU | ||
260 | |||
261 | config REGULATOR_BQ24022 | ||
262 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" | ||
263 | help | ||
264 | This driver controls a TI bq24022 Charger attached via | ||
265 | GPIOs. The provided current regulator can enable/disable | ||
266 | charging select between 100 mA and 500 mA charging current | ||
267 | limit. | ||
268 | |||
244 | config REGULATOR_TPS6105X | 269 | config REGULATOR_TPS6105X |
245 | tristate "TI TPS6105X Power regulators" | 270 | tristate "TI TPS6105X Power regulators" |
246 | depends on TPS6105X | 271 | depends on TPS6105X |
@@ -250,6 +275,16 @@ config REGULATOR_TPS6105X | |||
250 | It is a single boost converter primarily for white LEDs and | 275 | It is a single boost converter primarily for white LEDs and |
251 | audio amplifiers. | 276 | audio amplifiers. |
252 | 277 | ||
278 | config REGULATOR_TPS62360 | ||
279 | tristate "TI TPS62360 Power Regulator" | ||
280 | depends on I2C | ||
281 | select REGMAP_I2C | ||
282 | help | ||
283 | This driver supports TPS62360 voltage regulator chip. This | ||
284 | regulator is meant for processor core supply. This chip is | ||
285 | high-frequency synchronous step down dc-dc converter optimized | ||
286 | for battery-powered portable applications. | ||
287 | |||
253 | config REGULATOR_TPS65023 | 288 | config REGULATOR_TPS65023 |
254 | tristate "TI TPS65023 Power regulators" | 289 | tristate "TI TPS65023 Power regulators" |
255 | depends on I2C | 290 | depends on I2C |
@@ -267,73 +302,77 @@ config REGULATOR_TPS6507X | |||
267 | three step-down converters and two general-purpose LDO voltage regulators. | 302 | three step-down converters and two general-purpose LDO voltage regulators. |
268 | It supports TI's software based Class-2 SmartReflex implementation. | 303 | It supports TI's software based Class-2 SmartReflex implementation. |
269 | 304 | ||
270 | config REGULATOR_TPS65912 | 305 | config REGULATOR_TPS65217 |
271 | tristate "TI TPS65912 Power regulator" | 306 | tristate "TI TPS65217 Power regulators" |
272 | depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) | 307 | depends on MFD_TPS65217 |
273 | help | 308 | help |
274 | This driver supports TPS65912 voltage regulator chip. | 309 | This driver supports TPS65217 voltage regulator chips. TPS65217 |
310 | provides three step-down converters and four general-purpose LDO | ||
311 | voltage regulators. It supports software based voltage control | ||
312 | for different voltage domains | ||
275 | 313 | ||
276 | config REGULATOR_88PM8607 | 314 | config REGULATOR_TPS6524X |
277 | bool "Marvell 88PM8607 Power regulators" | 315 | tristate "TI TPS6524X Power regulators" |
278 | depends on MFD_88PM860X=y | 316 | depends on SPI |
279 | help | 317 | help |
280 | This driver supports 88PM8607 voltage regulator chips. | 318 | This driver supports TPS6524X voltage regulator chips. TPS6524X |
319 | provides three step-down converters and two general-purpose LDO | ||
320 | voltage regulators. This device is interfaced using a customized | ||
321 | serial interface currently supported on the sequencer serial | ||
322 | port controller. | ||
281 | 323 | ||
282 | config REGULATOR_ISL6271A | 324 | config REGULATOR_TPS6586X |
283 | tristate "Intersil ISL6271A Power regulator" | 325 | tristate "TI TPS6586X Power regulators" |
284 | depends on I2C | 326 | depends on MFD_TPS6586X |
285 | help | 327 | help |
286 | This driver supports ISL6271A voltage regulator chip. | 328 | This driver supports TPS6586X voltage regulator chips. |
287 | 329 | ||
288 | config REGULATOR_AD5398 | 330 | config REGULATOR_TPS65910 |
289 | tristate "Analog Devices AD5398/AD5821 regulators" | 331 | tristate "TI TPS65910/TPS65911 Power Regulators" |
290 | depends on I2C | 332 | depends on MFD_TPS65910 |
291 | help | 333 | help |
292 | This driver supports AD5398 and AD5821 current regulator chips. | 334 | This driver supports TPS65910/TPS65911 voltage regulator chips. |
293 | If building into module, its name is ad5398.ko. | ||
294 | 335 | ||
295 | config REGULATOR_AB8500 | 336 | config REGULATOR_TPS65912 |
296 | bool "ST-Ericsson AB8500 Power Regulators" | 337 | tristate "TI TPS65912 Power regulator" |
297 | depends on AB8500_CORE | 338 | depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) |
298 | help | 339 | help |
299 | This driver supports the regulators found on the ST-Ericsson mixed | 340 | This driver supports TPS65912 voltage regulator chip. |
300 | signal AB8500 PMIC | ||
301 | 341 | ||
302 | config REGULATOR_DB8500_PRCMU | 342 | config REGULATOR_TWL4030 |
303 | bool "ST-Ericsson DB8500 Voltage Domain Regulators" | 343 | bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" |
304 | depends on MFD_DB8500_PRCMU | 344 | depends on TWL4030_CORE |
305 | help | 345 | help |
306 | This driver supports the voltage domain regulators controlled by the | 346 | This driver supports the voltage regulators provided by |
307 | DB8500 PRCMU | 347 | this family of companion chips. |
308 | 348 | ||
309 | config REGULATOR_TPS6586X | 349 | config REGULATOR_WM831X |
310 | tristate "TI TPS6586X Power regulators" | 350 | tristate "Wolfson Microelectronics WM831x PMIC regulators" |
311 | depends on MFD_TPS6586X | 351 | depends on MFD_WM831X |
312 | help | 352 | help |
313 | This driver supports TPS6586X voltage regulator chips. | 353 | Support the voltage and current regulators of the WM831x series |
354 | of PMIC devices. | ||
314 | 355 | ||
315 | config REGULATOR_TPS6524X | 356 | config REGULATOR_WM8350 |
316 | tristate "TI TPS6524X Power regulators" | 357 | tristate "Wolfson Microelectronics WM8350 AudioPlus PMIC" |
317 | depends on SPI | 358 | depends on MFD_WM8350 |
318 | help | 359 | help |
319 | This driver supports TPS6524X voltage regulator chips. TPS6524X | 360 | This driver provides support for the voltage and current regulators |
320 | provides three step-down converters and two general-purpose LDO | 361 | of the WM8350 AudioPlus PMIC. |
321 | voltage regulators. This device is interfaced using a customized | ||
322 | serial interface currently supported on the sequencer serial | ||
323 | port controller. | ||
324 | 362 | ||
325 | config REGULATOR_TPS65910 | 363 | config REGULATOR_WM8400 |
326 | tristate "TI TPS65910 Power Regulator" | 364 | tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC" |
327 | depends on MFD_TPS65910 | 365 | depends on MFD_WM8400 |
328 | help | 366 | help |
329 | This driver supports TPS65910 voltage regulator chips. | 367 | This driver provides support for the voltage regulators of the |
368 | WM8400 AudioPlus PMIC. | ||
330 | 369 | ||
331 | config REGULATOR_AAT2870 | 370 | config REGULATOR_WM8994 |
332 | tristate "AnalogicTech AAT2870 Regulators" | 371 | tristate "Wolfson Microelectronics WM8994 CODEC" |
333 | depends on MFD_AAT2870_CORE | 372 | depends on MFD_WM8994 |
334 | help | 373 | help |
335 | If you have a AnalogicTech AAT2870 say Y to enable the | 374 | This driver provides support for the voltage regulators on the |
336 | regulator driver. | 375 | WM8994 CODEC. |
337 | 376 | ||
338 | endif | 377 | endif |
339 | 378 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 503bac87715e..b5042c885d89 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -3,50 +3,56 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | 5 | ||
6 | obj-$(CONFIG_REGULATOR) += core.o dummy.o | 6 | obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o |
7 | obj-$(CONFIG_OF) += of_regulator.o | 7 | obj-$(CONFIG_OF) += of_regulator.o |
8 | obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o | 8 | obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o |
9 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o | 9 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o |
10 | obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o | 10 | obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o |
11 | 11 | ||
12 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o | 12 | obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o |
13 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o | ||
14 | obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o | ||
15 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o | ||
16 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | ||
13 | obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o | 17 | obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o |
18 | obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | ||
14 | obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o | 19 | obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o |
20 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | ||
21 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | ||
22 | obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o | ||
23 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | ||
24 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | ||
15 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o | 25 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o |
16 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o | 26 | obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o |
17 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o | 27 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o |
18 | obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o | ||
19 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 28 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
20 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o | 29 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o |
21 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o | 30 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o |
22 | obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o | 31 | obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o |
23 | obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o | 32 | obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o |
24 | obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o | 33 | obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o |
25 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o | ||
26 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o | ||
27 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o | ||
28 | obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o | ||
29 | obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o | ||
30 | obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o | ||
31 | obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o | ||
32 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | ||
33 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | ||
34 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | ||
35 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | ||
36 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o | 34 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o |
37 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | 35 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o |
38 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | 36 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o |
39 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o | 37 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
38 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | ||
39 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | ||
40 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o | 40 | obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o |
41 | obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o | ||
41 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o | 42 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o |
42 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o | 43 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o |
44 | obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o | ||
43 | obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o | 45 | obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o |
44 | obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o | 46 | obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o |
45 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o | ||
46 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | ||
47 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | ||
48 | obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | ||
49 | obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o | 47 | obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o |
50 | obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o | 48 | obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o |
49 | obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o | ||
50 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o | ||
51 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o | ||
52 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o | ||
53 | obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o | ||
54 | obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o | ||
55 | obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o | ||
56 | |||
51 | 57 | ||
52 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG | 58 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG |
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 685ad43b0749..9ed5c5d84e12 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/mfd/aat2870.h> | 31 | #include <linux/mfd/aat2870.h> |
32 | 32 | ||
33 | struct aat2870_regulator { | 33 | struct aat2870_regulator { |
34 | struct platform_device *pdev; | 34 | struct aat2870_data *aat2870; |
35 | struct regulator_desc desc; | 35 | struct regulator_desc desc; |
36 | 36 | ||
37 | const int *voltages; /* uV */ | 37 | const int *voltages; /* uV */ |
@@ -60,7 +60,7 @@ static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev, | |||
60 | unsigned selector) | 60 | unsigned selector) |
61 | { | 61 | { |
62 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); | 62 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); |
63 | struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent); | 63 | struct aat2870_data *aat2870 = ri->aat2870; |
64 | 64 | ||
65 | return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask, | 65 | return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask, |
66 | selector << ri->voltage_shift); | 66 | selector << ri->voltage_shift); |
@@ -69,7 +69,7 @@ static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev, | |||
69 | static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev) | 69 | static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev) |
70 | { | 70 | { |
71 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); | 71 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); |
72 | struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent); | 72 | struct aat2870_data *aat2870 = ri->aat2870; |
73 | u8 val; | 73 | u8 val; |
74 | int ret; | 74 | int ret; |
75 | 75 | ||
@@ -83,7 +83,7 @@ static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev) | |||
83 | static int aat2870_ldo_enable(struct regulator_dev *rdev) | 83 | static int aat2870_ldo_enable(struct regulator_dev *rdev) |
84 | { | 84 | { |
85 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); | 85 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); |
86 | struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent); | 86 | struct aat2870_data *aat2870 = ri->aat2870; |
87 | 87 | ||
88 | return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, | 88 | return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, |
89 | ri->enable_mask); | 89 | ri->enable_mask); |
@@ -92,7 +92,7 @@ static int aat2870_ldo_enable(struct regulator_dev *rdev) | |||
92 | static int aat2870_ldo_disable(struct regulator_dev *rdev) | 92 | static int aat2870_ldo_disable(struct regulator_dev *rdev) |
93 | { | 93 | { |
94 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); | 94 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); |
95 | struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent); | 95 | struct aat2870_data *aat2870 = ri->aat2870; |
96 | 96 | ||
97 | return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0); | 97 | return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0); |
98 | } | 98 | } |
@@ -100,7 +100,7 @@ static int aat2870_ldo_disable(struct regulator_dev *rdev) | |||
100 | static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) | 100 | static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) |
101 | { | 101 | { |
102 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); | 102 | struct aat2870_regulator *ri = rdev_get_drvdata(rdev); |
103 | struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent); | 103 | struct aat2870_data *aat2870 = ri->aat2870; |
104 | u8 val; | 104 | u8 val; |
105 | int ret; | 105 | int ret; |
106 | 106 | ||
@@ -185,7 +185,7 @@ static int aat2870_regulator_probe(struct platform_device *pdev) | |||
185 | dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id); | 185 | dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id); |
186 | return -EINVAL; | 186 | return -EINVAL; |
187 | } | 187 | } |
188 | ri->pdev = pdev; | 188 | ri->aat2870 = dev_get_drvdata(pdev->dev.parent); |
189 | 189 | ||
190 | rdev = regulator_register(&ri->desc, &pdev->dev, | 190 | rdev = regulator_register(&ri->desc, &pdev->dev, |
191 | pdev->dev.platform_data, ri, NULL); | 191 | pdev->dev.platform_data, ri, NULL); |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index c9b92531ae60..c7ee4c15d6f5 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -201,7 +201,7 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) | |||
201 | return info->voltages[selector]; | 201 | return info->voltages[selector]; |
202 | } | 202 | } |
203 | 203 | ||
204 | static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) | 204 | static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) |
205 | { | 205 | { |
206 | int ret, val; | 206 | int ret, val; |
207 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | 207 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); |
@@ -229,11 +229,9 @@ static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) | |||
229 | /* vintcore has a different layout */ | 229 | /* vintcore has a different layout */ |
230 | val = regval & info->voltage_mask; | 230 | val = regval & info->voltage_mask; |
231 | if (info->desc.id == AB8500_LDO_INTCORE) | 231 | if (info->desc.id == AB8500_LDO_INTCORE) |
232 | ret = info->voltages[val >> 0x3]; | 232 | return val >> 0x3; |
233 | else | 233 | else |
234 | ret = info->voltages[val]; | 234 | return val; |
235 | |||
236 | return ret; | ||
237 | } | 235 | } |
238 | 236 | ||
239 | static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, | 237 | static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, |
@@ -320,7 +318,7 @@ static struct regulator_ops ab8500_regulator_ops = { | |||
320 | .enable = ab8500_regulator_enable, | 318 | .enable = ab8500_regulator_enable, |
321 | .disable = ab8500_regulator_disable, | 319 | .disable = ab8500_regulator_disable, |
322 | .is_enabled = ab8500_regulator_is_enabled, | 320 | .is_enabled = ab8500_regulator_is_enabled, |
323 | .get_voltage = ab8500_regulator_get_voltage, | 321 | .get_voltage_sel = ab8500_regulator_get_voltage_sel, |
324 | .set_voltage = ab8500_regulator_set_voltage, | 322 | .set_voltage = ab8500_regulator_set_voltage, |
325 | .list_voltage = ab8500_list_voltage, | 323 | .list_voltage = ab8500_list_voltage, |
326 | .enable_time = ab8500_regulator_enable_time, | 324 | .enable_time = ab8500_regulator_enable_time, |
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index 483c80930852..26d23adfc66f 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c | |||
@@ -94,8 +94,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int | |||
94 | if (max_uA > chip->max_uA || max_uA < chip->min_uA) | 94 | if (max_uA > chip->max_uA || max_uA < chip->min_uA) |
95 | return -EINVAL; | 95 | return -EINVAL; |
96 | 96 | ||
97 | selector = ((min_uA - chip->min_uA) * chip->current_level + | 97 | selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level, |
98 | range_uA - 1) / range_uA; | 98 | range_uA); |
99 | if (ad5398_calc_current(chip, selector) > max_uA) | 99 | if (ad5398_calc_current(chip, selector) > max_uA) |
100 | return -EINVAL; | 100 | return -EINVAL; |
101 | 101 | ||
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c new file mode 100644 index 000000000000..17499a55113d --- /dev/null +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | |||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/slab.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/mfd/anatop.h> | ||
30 | #include <linux/regulator/driver.h> | ||
31 | #include <linux/regulator/of_regulator.h> | ||
32 | |||
33 | struct anatop_regulator { | ||
34 | const char *name; | ||
35 | u32 control_reg; | ||
36 | struct anatop *mfd; | ||
37 | int vol_bit_shift; | ||
38 | int vol_bit_width; | ||
39 | int min_bit_val; | ||
40 | int min_voltage; | ||
41 | int max_voltage; | ||
42 | struct regulator_desc rdesc; | ||
43 | struct regulator_init_data *initdata; | ||
44 | }; | ||
45 | |||
46 | static int anatop_set_voltage(struct regulator_dev *reg, int min_uV, | ||
47 | int max_uV, unsigned *selector) | ||
48 | { | ||
49 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
50 | u32 val, sel; | ||
51 | int uv; | ||
52 | |||
53 | uv = min_uV; | ||
54 | dev_dbg(®->dev, "%s: uv %d, min %d, max %d\n", __func__, | ||
55 | uv, anatop_reg->min_voltage, | ||
56 | anatop_reg->max_voltage); | ||
57 | |||
58 | if (uv < anatop_reg->min_voltage) { | ||
59 | if (max_uV > anatop_reg->min_voltage) | ||
60 | uv = anatop_reg->min_voltage; | ||
61 | else | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | |||
65 | if (!anatop_reg->control_reg) | ||
66 | return -ENOTSUPP; | ||
67 | |||
68 | sel = DIV_ROUND_UP(uv - anatop_reg->min_voltage, 25000); | ||
69 | if (sel * 25000 + anatop_reg->min_voltage > anatop_reg->max_voltage) | ||
70 | return -EINVAL; | ||
71 | val = anatop_reg->min_bit_val + sel; | ||
72 | *selector = sel; | ||
73 | dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); | ||
74 | anatop_set_bits(anatop_reg->mfd, | ||
75 | anatop_reg->control_reg, | ||
76 | anatop_reg->vol_bit_shift, | ||
77 | anatop_reg->vol_bit_width, | ||
78 | val); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int anatop_get_voltage_sel(struct regulator_dev *reg) | ||
84 | { | ||
85 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
86 | u32 val; | ||
87 | |||
88 | if (!anatop_reg->control_reg) | ||
89 | return -ENOTSUPP; | ||
90 | |||
91 | val = anatop_get_bits(anatop_reg->mfd, | ||
92 | anatop_reg->control_reg, | ||
93 | anatop_reg->vol_bit_shift, | ||
94 | anatop_reg->vol_bit_width); | ||
95 | |||
96 | return val - anatop_reg->min_bit_val; | ||
97 | } | ||
98 | |||
99 | static int anatop_list_voltage(struct regulator_dev *reg, unsigned selector) | ||
100 | { | ||
101 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | ||
102 | int uv; | ||
103 | |||
104 | uv = anatop_reg->min_voltage + selector * 25000; | ||
105 | dev_dbg(®->dev, "vddio = %d, selector = %u\n", uv, selector); | ||
106 | |||
107 | return uv; | ||
108 | } | ||
109 | |||
110 | static struct regulator_ops anatop_rops = { | ||
111 | .set_voltage = anatop_set_voltage, | ||
112 | .get_voltage_sel = anatop_get_voltage_sel, | ||
113 | .list_voltage = anatop_list_voltage, | ||
114 | }; | ||
115 | |||
116 | static int __devinit anatop_regulator_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct device *dev = &pdev->dev; | ||
119 | struct device_node *np = dev->of_node; | ||
120 | struct regulator_desc *rdesc; | ||
121 | struct regulator_dev *rdev; | ||
122 | struct anatop_regulator *sreg; | ||
123 | struct regulator_init_data *initdata; | ||
124 | struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent); | ||
125 | int ret = 0; | ||
126 | |||
127 | initdata = of_get_regulator_init_data(dev, np); | ||
128 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); | ||
129 | if (!sreg) | ||
130 | return -ENOMEM; | ||
131 | sreg->initdata = initdata; | ||
132 | sreg->name = kstrdup(of_get_property(np, "regulator-name", NULL), | ||
133 | GFP_KERNEL); | ||
134 | rdesc = &sreg->rdesc; | ||
135 | memset(rdesc, 0, sizeof(*rdesc)); | ||
136 | rdesc->name = sreg->name; | ||
137 | rdesc->ops = &anatop_rops; | ||
138 | rdesc->type = REGULATOR_VOLTAGE; | ||
139 | rdesc->owner = THIS_MODULE; | ||
140 | sreg->mfd = anatopmfd; | ||
141 | ret = of_property_read_u32(np, "reg", &sreg->control_reg); | ||
142 | if (ret) { | ||
143 | dev_err(dev, "no reg property set\n"); | ||
144 | goto anatop_probe_end; | ||
145 | } | ||
146 | ret = of_property_read_u32(np, "anatop-vol-bit-width", | ||
147 | &sreg->vol_bit_width); | ||
148 | if (ret) { | ||
149 | dev_err(dev, "no anatop-vol-bit-width property set\n"); | ||
150 | goto anatop_probe_end; | ||
151 | } | ||
152 | ret = of_property_read_u32(np, "anatop-vol-bit-shift", | ||
153 | &sreg->vol_bit_shift); | ||
154 | if (ret) { | ||
155 | dev_err(dev, "no anatop-vol-bit-shift property set\n"); | ||
156 | goto anatop_probe_end; | ||
157 | } | ||
158 | ret = of_property_read_u32(np, "anatop-min-bit-val", | ||
159 | &sreg->min_bit_val); | ||
160 | if (ret) { | ||
161 | dev_err(dev, "no anatop-min-bit-val property set\n"); | ||
162 | goto anatop_probe_end; | ||
163 | } | ||
164 | ret = of_property_read_u32(np, "anatop-min-voltage", | ||
165 | &sreg->min_voltage); | ||
166 | if (ret) { | ||
167 | dev_err(dev, "no anatop-min-voltage property set\n"); | ||
168 | goto anatop_probe_end; | ||
169 | } | ||
170 | ret = of_property_read_u32(np, "anatop-max-voltage", | ||
171 | &sreg->max_voltage); | ||
172 | if (ret) { | ||
173 | dev_err(dev, "no anatop-max-voltage property set\n"); | ||
174 | goto anatop_probe_end; | ||
175 | } | ||
176 | |||
177 | rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) | ||
178 | / 25000 + 1; | ||
179 | |||
180 | /* register regulator */ | ||
181 | rdev = regulator_register(rdesc, dev, | ||
182 | initdata, sreg, pdev->dev.of_node); | ||
183 | if (IS_ERR(rdev)) { | ||
184 | dev_err(dev, "failed to register %s\n", | ||
185 | rdesc->name); | ||
186 | ret = PTR_ERR(rdev); | ||
187 | goto anatop_probe_end; | ||
188 | } | ||
189 | |||
190 | platform_set_drvdata(pdev, rdev); | ||
191 | |||
192 | anatop_probe_end: | ||
193 | if (ret) | ||
194 | kfree(sreg->name); | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static int __devexit anatop_regulator_remove(struct platform_device *pdev) | ||
200 | { | ||
201 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
202 | struct anatop_regulator *sreg = rdev_get_drvdata(rdev); | ||
203 | const char *name = sreg->name; | ||
204 | |||
205 | regulator_unregister(rdev); | ||
206 | kfree(name); | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static struct of_device_id __devinitdata of_anatop_regulator_match_tbl[] = { | ||
212 | { .compatible = "fsl,anatop-regulator", }, | ||
213 | { /* end */ } | ||
214 | }; | ||
215 | |||
216 | static struct platform_driver anatop_regulator = { | ||
217 | .driver = { | ||
218 | .name = "anatop_regulator", | ||
219 | .owner = THIS_MODULE, | ||
220 | .of_match_table = of_anatop_regulator_match_tbl, | ||
221 | }, | ||
222 | .probe = anatop_regulator_probe, | ||
223 | .remove = anatop_regulator_remove, | ||
224 | }; | ||
225 | |||
226 | static int __init anatop_regulator_init(void) | ||
227 | { | ||
228 | return platform_driver_register(&anatop_regulator); | ||
229 | } | ||
230 | postcore_initcall(anatop_regulator_init); | ||
231 | |||
232 | static void __exit anatop_regulator_exit(void) | ||
233 | { | ||
234 | platform_driver_unregister(&anatop_regulator); | ||
235 | } | ||
236 | module_exit(anatop_regulator_exit); | ||
237 | |||
238 | MODULE_AUTHOR("Nancy Chen <Nancy.Chen@freescale.com>, " | ||
239 | "Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>"); | ||
240 | MODULE_DESCRIPTION("ANATOP Regulator driver"); | ||
241 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index fcde037b3461..c056abd7562a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -13,8 +13,6 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
17 | |||
18 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 17 | #include <linux/init.h> |
20 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
@@ -54,9 +52,7 @@ static LIST_HEAD(regulator_map_list); | |||
54 | static bool has_full_constraints; | 52 | static bool has_full_constraints; |
55 | static bool board_wants_dummy_regulator; | 53 | static bool board_wants_dummy_regulator; |
56 | 54 | ||
57 | #ifdef CONFIG_DEBUG_FS | ||
58 | static struct dentry *debugfs_root; | 55 | static struct dentry *debugfs_root; |
59 | #endif | ||
60 | 56 | ||
61 | /* | 57 | /* |
62 | * struct regulator_map | 58 | * struct regulator_map |
@@ -84,9 +80,7 @@ struct regulator { | |||
84 | char *supply_name; | 80 | char *supply_name; |
85 | struct device_attribute dev_attr; | 81 | struct device_attribute dev_attr; |
86 | struct regulator_dev *rdev; | 82 | struct regulator_dev *rdev; |
87 | #ifdef CONFIG_DEBUG_FS | ||
88 | struct dentry *debugfs; | 83 | struct dentry *debugfs; |
89 | #endif | ||
90 | }; | 84 | }; |
91 | 85 | ||
92 | static int _regulator_is_enabled(struct regulator_dev *rdev); | 86 | static int _regulator_is_enabled(struct regulator_dev *rdev); |
@@ -154,7 +148,7 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp | |||
154 | regnode = of_parse_phandle(dev->of_node, prop_name, 0); | 148 | regnode = of_parse_phandle(dev->of_node, prop_name, 0); |
155 | 149 | ||
156 | if (!regnode) { | 150 | if (!regnode) { |
157 | dev_warn(dev, "%s property in node %s references invalid phandle", | 151 | dev_dbg(dev, "Looking up %s property in node %s failed", |
158 | prop_name, dev->of_node->full_name); | 152 | prop_name, dev->of_node->full_name); |
159 | return NULL; | 153 | return NULL; |
160 | } | 154 | } |
@@ -807,6 +801,11 @@ static void print_constraints(struct regulator_dev *rdev) | |||
807 | count += sprintf(buf + count, "standby"); | 801 | count += sprintf(buf + count, "standby"); |
808 | 802 | ||
809 | rdev_info(rdev, "%s\n", buf); | 803 | rdev_info(rdev, "%s\n", buf); |
804 | |||
805 | if ((constraints->min_uV != constraints->max_uV) && | ||
806 | !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) | ||
807 | rdev_warn(rdev, | ||
808 | "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n"); | ||
810 | } | 809 | } |
811 | 810 | ||
812 | static int machine_constraints_voltage(struct regulator_dev *rdev, | 811 | static int machine_constraints_voltage(struct regulator_dev *rdev, |
@@ -996,7 +995,6 @@ static int set_supply(struct regulator_dev *rdev, | |||
996 | /** | 995 | /** |
997 | * set_consumer_device_supply - Bind a regulator to a symbolic supply | 996 | * set_consumer_device_supply - Bind a regulator to a symbolic supply |
998 | * @rdev: regulator source | 997 | * @rdev: regulator source |
999 | * @consumer_dev: device the supply applies to | ||
1000 | * @consumer_dev_name: dev_name() string for device supply applies to | 998 | * @consumer_dev_name: dev_name() string for device supply applies to |
1001 | * @supply: symbolic name for supply | 999 | * @supply: symbolic name for supply |
1002 | * | 1000 | * |
@@ -1004,22 +1002,14 @@ static int set_supply(struct regulator_dev *rdev, | |||
1004 | * sources to symbolic names for supplies for use by devices. Devices | 1002 | * sources to symbolic names for supplies for use by devices. Devices |
1005 | * should use these symbolic names to request regulators, avoiding the | 1003 | * should use these symbolic names to request regulators, avoiding the |
1006 | * need to provide board-specific regulator names as platform data. | 1004 | * need to provide board-specific regulator names as platform data. |
1007 | * | ||
1008 | * Only one of consumer_dev and consumer_dev_name may be specified. | ||
1009 | */ | 1005 | */ |
1010 | static int set_consumer_device_supply(struct regulator_dev *rdev, | 1006 | static int set_consumer_device_supply(struct regulator_dev *rdev, |
1011 | struct device *consumer_dev, const char *consumer_dev_name, | 1007 | const char *consumer_dev_name, |
1012 | const char *supply) | 1008 | const char *supply) |
1013 | { | 1009 | { |
1014 | struct regulator_map *node; | 1010 | struct regulator_map *node; |
1015 | int has_dev; | 1011 | int has_dev; |
1016 | 1012 | ||
1017 | if (consumer_dev && consumer_dev_name) | ||
1018 | return -EINVAL; | ||
1019 | |||
1020 | if (!consumer_dev_name && consumer_dev) | ||
1021 | consumer_dev_name = dev_name(consumer_dev); | ||
1022 | |||
1023 | if (supply == NULL) | 1013 | if (supply == NULL) |
1024 | return -EINVAL; | 1014 | return -EINVAL; |
1025 | 1015 | ||
@@ -1039,11 +1029,12 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, | |||
1039 | if (strcmp(node->supply, supply) != 0) | 1029 | if (strcmp(node->supply, supply) != 0) |
1040 | continue; | 1030 | continue; |
1041 | 1031 | ||
1042 | dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n", | 1032 | pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n", |
1043 | dev_name(&node->regulator->dev), | 1033 | consumer_dev_name, |
1044 | node->regulator->desc->name, | 1034 | dev_name(&node->regulator->dev), |
1045 | supply, | 1035 | node->regulator->desc->name, |
1046 | dev_name(&rdev->dev), rdev_get_name(rdev)); | 1036 | supply, |
1037 | dev_name(&rdev->dev), rdev_get_name(rdev)); | ||
1047 | return -EBUSY; | 1038 | return -EBUSY; |
1048 | } | 1039 | } |
1049 | 1040 | ||
@@ -1142,12 +1133,10 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1142 | goto attr_err; | 1133 | goto attr_err; |
1143 | } | 1134 | } |
1144 | 1135 | ||
1145 | #ifdef CONFIG_DEBUG_FS | ||
1146 | regulator->debugfs = debugfs_create_dir(regulator->supply_name, | 1136 | regulator->debugfs = debugfs_create_dir(regulator->supply_name, |
1147 | rdev->debugfs); | 1137 | rdev->debugfs); |
1148 | if (IS_ERR_OR_NULL(regulator->debugfs)) { | 1138 | if (!regulator->debugfs) { |
1149 | rdev_warn(rdev, "Failed to create debugfs directory\n"); | 1139 | rdev_warn(rdev, "Failed to create debugfs directory\n"); |
1150 | regulator->debugfs = NULL; | ||
1151 | } else { | 1140 | } else { |
1152 | debugfs_create_u32("uA_load", 0444, regulator->debugfs, | 1141 | debugfs_create_u32("uA_load", 0444, regulator->debugfs, |
1153 | ®ulator->uA_load); | 1142 | ®ulator->uA_load); |
@@ -1156,7 +1145,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, | |||
1156 | debugfs_create_u32("max_uV", 0444, regulator->debugfs, | 1145 | debugfs_create_u32("max_uV", 0444, regulator->debugfs, |
1157 | ®ulator->max_uV); | 1146 | ®ulator->max_uV); |
1158 | } | 1147 | } |
1159 | #endif | ||
1160 | 1148 | ||
1161 | mutex_unlock(&rdev->mutex); | 1149 | mutex_unlock(&rdev->mutex); |
1162 | return regulator; | 1150 | return regulator; |
@@ -1320,6 +1308,40 @@ struct regulator *regulator_get(struct device *dev, const char *id) | |||
1320 | } | 1308 | } |
1321 | EXPORT_SYMBOL_GPL(regulator_get); | 1309 | EXPORT_SYMBOL_GPL(regulator_get); |
1322 | 1310 | ||
1311 | static void devm_regulator_release(struct device *dev, void *res) | ||
1312 | { | ||
1313 | regulator_put(*(struct regulator **)res); | ||
1314 | } | ||
1315 | |||
1316 | /** | ||
1317 | * devm_regulator_get - Resource managed regulator_get() | ||
1318 | * @dev: device for regulator "consumer" | ||
1319 | * @id: Supply name or regulator ID. | ||
1320 | * | ||
1321 | * Managed regulator_get(). Regulators returned from this function are | ||
1322 | * automatically regulator_put() on driver detach. See regulator_get() for more | ||
1323 | * information. | ||
1324 | */ | ||
1325 | struct regulator *devm_regulator_get(struct device *dev, const char *id) | ||
1326 | { | ||
1327 | struct regulator **ptr, *regulator; | ||
1328 | |||
1329 | ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); | ||
1330 | if (!ptr) | ||
1331 | return ERR_PTR(-ENOMEM); | ||
1332 | |||
1333 | regulator = regulator_get(dev, id); | ||
1334 | if (!IS_ERR(regulator)) { | ||
1335 | *ptr = regulator; | ||
1336 | devres_add(dev, ptr); | ||
1337 | } else { | ||
1338 | devres_free(ptr); | ||
1339 | } | ||
1340 | |||
1341 | return regulator; | ||
1342 | } | ||
1343 | EXPORT_SYMBOL_GPL(devm_regulator_get); | ||
1344 | |||
1323 | /** | 1345 | /** |
1324 | * regulator_get_exclusive - obtain exclusive access to a regulator. | 1346 | * regulator_get_exclusive - obtain exclusive access to a regulator. |
1325 | * @dev: device for regulator "consumer" | 1347 | * @dev: device for regulator "consumer" |
@@ -1365,9 +1387,7 @@ void regulator_put(struct regulator *regulator) | |||
1365 | mutex_lock(®ulator_list_mutex); | 1387 | mutex_lock(®ulator_list_mutex); |
1366 | rdev = regulator->rdev; | 1388 | rdev = regulator->rdev; |
1367 | 1389 | ||
1368 | #ifdef CONFIG_DEBUG_FS | ||
1369 | debugfs_remove_recursive(regulator->debugfs); | 1390 | debugfs_remove_recursive(regulator->debugfs); |
1370 | #endif | ||
1371 | 1391 | ||
1372 | /* remove any sysfs entries */ | 1392 | /* remove any sysfs entries */ |
1373 | if (regulator->dev) { | 1393 | if (regulator->dev) { |
@@ -1387,6 +1407,34 @@ void regulator_put(struct regulator *regulator) | |||
1387 | } | 1407 | } |
1388 | EXPORT_SYMBOL_GPL(regulator_put); | 1408 | EXPORT_SYMBOL_GPL(regulator_put); |
1389 | 1409 | ||
1410 | static int devm_regulator_match(struct device *dev, void *res, void *data) | ||
1411 | { | ||
1412 | struct regulator **r = res; | ||
1413 | if (!r || !*r) { | ||
1414 | WARN_ON(!r || !*r); | ||
1415 | return 0; | ||
1416 | } | ||
1417 | return *r == data; | ||
1418 | } | ||
1419 | |||
1420 | /** | ||
1421 | * devm_regulator_put - Resource managed regulator_put() | ||
1422 | * @regulator: regulator to free | ||
1423 | * | ||
1424 | * Deallocate a regulator allocated with devm_regulator_get(). Normally | ||
1425 | * this function will not need to be called and the resource management | ||
1426 | * code will ensure that the resource is freed. | ||
1427 | */ | ||
1428 | void devm_regulator_put(struct regulator *regulator) | ||
1429 | { | ||
1430 | int rc; | ||
1431 | |||
1432 | rc = devres_destroy(regulator->dev, devm_regulator_release, | ||
1433 | devm_regulator_match, regulator); | ||
1434 | WARN_ON(rc); | ||
1435 | } | ||
1436 | EXPORT_SYMBOL_GPL(devm_regulator_put); | ||
1437 | |||
1390 | static int _regulator_can_change_status(struct regulator_dev *rdev) | 1438 | static int _regulator_can_change_status(struct regulator_dev *rdev) |
1391 | { | 1439 | { |
1392 | if (!rdev->constraints) | 1440 | if (!rdev->constraints) |
@@ -1842,8 +1890,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
1842 | if (ret < 0) | 1890 | if (ret < 0) |
1843 | return ret; | 1891 | return ret; |
1844 | old_selector = ret; | 1892 | old_selector = ret; |
1845 | delay = rdev->desc->ops->set_voltage_time_sel(rdev, | 1893 | ret = rdev->desc->ops->set_voltage_time_sel(rdev, |
1846 | old_selector, selector); | 1894 | old_selector, selector); |
1895 | if (ret < 0) | ||
1896 | rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret); | ||
1897 | else | ||
1898 | delay = ret; | ||
1847 | } | 1899 | } |
1848 | 1900 | ||
1849 | if (best_val != INT_MAX) { | 1901 | if (best_val != INT_MAX) { |
@@ -2394,13 +2446,59 @@ int regulator_bulk_get(struct device *dev, int num_consumers, | |||
2394 | return 0; | 2446 | return 0; |
2395 | 2447 | ||
2396 | err: | 2448 | err: |
2397 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | 2449 | while (--i >= 0) |
2398 | regulator_put(consumers[i].consumer); | 2450 | regulator_put(consumers[i].consumer); |
2399 | 2451 | ||
2400 | return ret; | 2452 | return ret; |
2401 | } | 2453 | } |
2402 | EXPORT_SYMBOL_GPL(regulator_bulk_get); | 2454 | EXPORT_SYMBOL_GPL(regulator_bulk_get); |
2403 | 2455 | ||
2456 | /** | ||
2457 | * devm_regulator_bulk_get - managed get multiple regulator consumers | ||
2458 | * | ||
2459 | * @dev: Device to supply | ||
2460 | * @num_consumers: Number of consumers to register | ||
2461 | * @consumers: Configuration of consumers; clients are stored here. | ||
2462 | * | ||
2463 | * @return 0 on success, an errno on failure. | ||
2464 | * | ||
2465 | * This helper function allows drivers to get several regulator | ||
2466 | * consumers in one operation with management, the regulators will | ||
2467 | * automatically be freed when the device is unbound. If any of the | ||
2468 | * regulators cannot be acquired then any regulators that were | ||
2469 | * allocated will be freed before returning to the caller. | ||
2470 | */ | ||
2471 | int devm_regulator_bulk_get(struct device *dev, int num_consumers, | ||
2472 | struct regulator_bulk_data *consumers) | ||
2473 | { | ||
2474 | int i; | ||
2475 | int ret; | ||
2476 | |||
2477 | for (i = 0; i < num_consumers; i++) | ||
2478 | consumers[i].consumer = NULL; | ||
2479 | |||
2480 | for (i = 0; i < num_consumers; i++) { | ||
2481 | consumers[i].consumer = devm_regulator_get(dev, | ||
2482 | consumers[i].supply); | ||
2483 | if (IS_ERR(consumers[i].consumer)) { | ||
2484 | ret = PTR_ERR(consumers[i].consumer); | ||
2485 | dev_err(dev, "Failed to get supply '%s': %d\n", | ||
2486 | consumers[i].supply, ret); | ||
2487 | consumers[i].consumer = NULL; | ||
2488 | goto err; | ||
2489 | } | ||
2490 | } | ||
2491 | |||
2492 | return 0; | ||
2493 | |||
2494 | err: | ||
2495 | for (i = 0; i < num_consumers && consumers[i].consumer; i++) | ||
2496 | devm_regulator_put(consumers[i].consumer); | ||
2497 | |||
2498 | return ret; | ||
2499 | } | ||
2500 | EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); | ||
2501 | |||
2404 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) | 2502 | static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) |
2405 | { | 2503 | { |
2406 | struct regulator_bulk_data *bulk = data; | 2504 | struct regulator_bulk_data *bulk = data; |
@@ -2444,12 +2542,9 @@ int regulator_bulk_enable(int num_consumers, | |||
2444 | return 0; | 2542 | return 0; |
2445 | 2543 | ||
2446 | err: | 2544 | err: |
2447 | for (i = 0; i < num_consumers; i++) | 2545 | pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); |
2448 | if (consumers[i].ret == 0) | 2546 | while (--i >= 0) |
2449 | regulator_disable(consumers[i].consumer); | 2547 | regulator_disable(consumers[i].consumer); |
2450 | else | ||
2451 | pr_err("Failed to enable %s: %d\n", | ||
2452 | consumers[i].supply, consumers[i].ret); | ||
2453 | 2548 | ||
2454 | return ret; | 2549 | return ret; |
2455 | } | 2550 | } |
@@ -2463,8 +2558,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable); | |||
2463 | * @return 0 on success, an errno on failure | 2558 | * @return 0 on success, an errno on failure |
2464 | * | 2559 | * |
2465 | * This convenience API allows consumers to disable multiple regulator | 2560 | * This convenience API allows consumers to disable multiple regulator |
2466 | * clients in a single API call. If any consumers cannot be enabled | 2561 | * clients in a single API call. If any consumers cannot be disabled |
2467 | * then any others that were disabled will be disabled again prior to | 2562 | * then any others that were disabled will be enabled again prior to |
2468 | * return. | 2563 | * return. |
2469 | */ | 2564 | */ |
2470 | int regulator_bulk_disable(int num_consumers, | 2565 | int regulator_bulk_disable(int num_consumers, |
@@ -2473,7 +2568,7 @@ int regulator_bulk_disable(int num_consumers, | |||
2473 | int i; | 2568 | int i; |
2474 | int ret; | 2569 | int ret; |
2475 | 2570 | ||
2476 | for (i = 0; i < num_consumers; i++) { | 2571 | for (i = num_consumers - 1; i >= 0; --i) { |
2477 | ret = regulator_disable(consumers[i].consumer); | 2572 | ret = regulator_disable(consumers[i].consumer); |
2478 | if (ret != 0) | 2573 | if (ret != 0) |
2479 | goto err; | 2574 | goto err; |
@@ -2483,7 +2578,7 @@ int regulator_bulk_disable(int num_consumers, | |||
2483 | 2578 | ||
2484 | err: | 2579 | err: |
2485 | pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); | 2580 | pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); |
2486 | for (--i; i >= 0; --i) | 2581 | for (++i; i < num_consumers; ++i) |
2487 | regulator_enable(consumers[i].consumer); | 2582 | regulator_enable(consumers[i].consumer); |
2488 | 2583 | ||
2489 | return ret; | 2584 | return ret; |
@@ -2710,11 +2805,9 @@ static int add_regulator_attributes(struct regulator_dev *rdev) | |||
2710 | 2805 | ||
2711 | static void rdev_init_debugfs(struct regulator_dev *rdev) | 2806 | static void rdev_init_debugfs(struct regulator_dev *rdev) |
2712 | { | 2807 | { |
2713 | #ifdef CONFIG_DEBUG_FS | ||
2714 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); | 2808 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); |
2715 | if (IS_ERR(rdev->debugfs) || !rdev->debugfs) { | 2809 | if (!rdev->debugfs) { |
2716 | rdev_warn(rdev, "Failed to create debugfs directory\n"); | 2810 | rdev_warn(rdev, "Failed to create debugfs directory\n"); |
2717 | rdev->debugfs = NULL; | ||
2718 | return; | 2811 | return; |
2719 | } | 2812 | } |
2720 | 2813 | ||
@@ -2722,7 +2815,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) | |||
2722 | &rdev->use_count); | 2815 | &rdev->use_count); |
2723 | debugfs_create_u32("open_count", 0444, rdev->debugfs, | 2816 | debugfs_create_u32("open_count", 0444, rdev->debugfs, |
2724 | &rdev->open_count); | 2817 | &rdev->open_count); |
2725 | #endif | ||
2726 | } | 2818 | } |
2727 | 2819 | ||
2728 | /** | 2820 | /** |
@@ -2855,7 +2947,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2855 | if (init_data) { | 2947 | if (init_data) { |
2856 | for (i = 0; i < init_data->num_consumer_supplies; i++) { | 2948 | for (i = 0; i < init_data->num_consumer_supplies; i++) { |
2857 | ret = set_consumer_device_supply(rdev, | 2949 | ret = set_consumer_device_supply(rdev, |
2858 | init_data->consumer_supplies[i].dev, | ||
2859 | init_data->consumer_supplies[i].dev_name, | 2950 | init_data->consumer_supplies[i].dev_name, |
2860 | init_data->consumer_supplies[i].supply); | 2951 | init_data->consumer_supplies[i].supply); |
2861 | if (ret < 0) { | 2952 | if (ret < 0) { |
@@ -2902,9 +2993,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2902 | return; | 2993 | return; |
2903 | 2994 | ||
2904 | mutex_lock(®ulator_list_mutex); | 2995 | mutex_lock(®ulator_list_mutex); |
2905 | #ifdef CONFIG_DEBUG_FS | ||
2906 | debugfs_remove_recursive(rdev->debugfs); | 2996 | debugfs_remove_recursive(rdev->debugfs); |
2907 | #endif | ||
2908 | flush_work_sync(&rdev->disable_work.work); | 2997 | flush_work_sync(&rdev->disable_work.work); |
2909 | WARN_ON(rdev->open_count); | 2998 | WARN_ON(rdev->open_count); |
2910 | unset_regulator_supplies(rdev); | 2999 | unset_regulator_supplies(rdev); |
@@ -3114,12 +3203,14 @@ static ssize_t supply_map_read_file(struct file *file, char __user *user_buf, | |||
3114 | 3203 | ||
3115 | return ret; | 3204 | return ret; |
3116 | } | 3205 | } |
3206 | #endif | ||
3117 | 3207 | ||
3118 | static const struct file_operations supply_map_fops = { | 3208 | static const struct file_operations supply_map_fops = { |
3209 | #ifdef CONFIG_DEBUG_FS | ||
3119 | .read = supply_map_read_file, | 3210 | .read = supply_map_read_file, |
3120 | .llseek = default_llseek, | 3211 | .llseek = default_llseek, |
3121 | }; | ||
3122 | #endif | 3212 | #endif |
3213 | }; | ||
3123 | 3214 | ||
3124 | static int __init regulator_init(void) | 3215 | static int __init regulator_init(void) |
3125 | { | 3216 | { |
@@ -3127,17 +3218,12 @@ static int __init regulator_init(void) | |||
3127 | 3218 | ||
3128 | ret = class_register(®ulator_class); | 3219 | ret = class_register(®ulator_class); |
3129 | 3220 | ||
3130 | #ifdef CONFIG_DEBUG_FS | ||
3131 | debugfs_root = debugfs_create_dir("regulator", NULL); | 3221 | debugfs_root = debugfs_create_dir("regulator", NULL); |
3132 | if (IS_ERR(debugfs_root) || !debugfs_root) { | 3222 | if (!debugfs_root) |
3133 | pr_warn("regulator: Failed to create debugfs directory\n"); | 3223 | pr_warn("regulator: Failed to create debugfs directory\n"); |
3134 | debugfs_root = NULL; | ||
3135 | } | ||
3136 | 3224 | ||
3137 | if (IS_ERR(debugfs_create_file("supply_map", 0444, debugfs_root, | 3225 | debugfs_create_file("supply_map", 0444, debugfs_root, NULL, |
3138 | NULL, &supply_map_fops))) | 3226 | &supply_map_fops); |
3139 | pr_warn("regulator: Failed to create supplies debugfs\n"); | ||
3140 | #endif | ||
3141 | 3227 | ||
3142 | regulator_dummy_init(); | 3228 | regulator_dummy_init(); |
3143 | 3229 | ||
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 8dbc54da7d70..1851f0929ef0 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c | |||
@@ -119,7 +119,7 @@ static int da903x_set_ldo_voltage(struct regulator_dev *rdev, | |||
119 | return -EINVAL; | 119 | return -EINVAL; |
120 | } | 120 | } |
121 | 121 | ||
122 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 122 | val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
123 | *selector = val; | 123 | *selector = val; |
124 | val <<= info->vol_shift; | 124 | val <<= info->vol_shift; |
125 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 125 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
@@ -202,7 +202,7 @@ static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, | |||
202 | return -EINVAL; | 202 | return -EINVAL; |
203 | } | 203 | } |
204 | 204 | ||
205 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 205 | val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
206 | *selector = val; | 206 | *selector = val; |
207 | val <<= info->vol_shift; | 207 | val <<= info->vol_shift; |
208 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 208 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
@@ -233,10 +233,10 @@ static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, | |||
233 | 233 | ||
234 | thresh = (info->max_uV + info->min_uV) / 2; | 234 | thresh = (info->max_uV + info->min_uV) / 2; |
235 | if (min_uV < thresh) { | 235 | if (min_uV < thresh) { |
236 | val = (thresh - min_uV + info->step_uV - 1) / info->step_uV; | 236 | val = DIV_ROUND_UP(thresh - min_uV, info->step_uV); |
237 | val |= 0x4; | 237 | val |= 0x4; |
238 | } else { | 238 | } else { |
239 | val = (min_uV - thresh + info->step_uV - 1) / info->step_uV; | 239 | val = DIV_ROUND_UP(min_uV - thresh, info->step_uV); |
240 | } | 240 | } |
241 | 241 | ||
242 | *selector = val; | 242 | *selector = val; |
@@ -281,7 +281,7 @@ static int da9034_set_dvc_voltage(struct regulator_dev *rdev, | |||
281 | return -EINVAL; | 281 | return -EINVAL; |
282 | } | 282 | } |
283 | 283 | ||
284 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 284 | val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
285 | *selector = val; | 285 | *selector = val; |
286 | val <<= info->vol_shift; | 286 | val <<= info->vol_shift; |
287 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 287 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
@@ -307,7 +307,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, | |||
307 | return -EINVAL; | 307 | return -EINVAL; |
308 | } | 308 | } |
309 | 309 | ||
310 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 310 | val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
311 | val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); | 311 | val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); |
312 | *selector = val; | 312 | *selector = val; |
313 | val <<= info->vol_shift; | 313 | val <<= info->vol_shift; |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 515443fcd26b..4bd25e75efa0 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
@@ -18,74 +18,11 @@ | |||
18 | #include <linux/regulator/machine.h> | 18 | #include <linux/regulator/machine.h> |
19 | #include <linux/regulator/db8500-prcmu.h> | 19 | #include <linux/regulator/db8500-prcmu.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | 21 | #include "dbx500-prcmu.h" | |
22 | /* | ||
23 | * power state reference count | ||
24 | */ | ||
25 | static int power_state_active_cnt; /* will initialize to zero */ | ||
26 | static DEFINE_SPINLOCK(power_state_active_lock); | ||
27 | |||
28 | static void power_state_active_enable(void) | ||
29 | { | ||
30 | unsigned long flags; | ||
31 | |||
32 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
33 | power_state_active_cnt++; | ||
34 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
35 | } | ||
36 | |||
37 | static int power_state_active_disable(void) | ||
38 | { | ||
39 | int ret = 0; | ||
40 | unsigned long flags; | ||
41 | |||
42 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
43 | if (power_state_active_cnt <= 0) { | ||
44 | pr_err("power state: unbalanced enable/disable calls\n"); | ||
45 | ret = -EINVAL; | ||
46 | goto out; | ||
47 | } | ||
48 | |||
49 | power_state_active_cnt--; | ||
50 | out: | ||
51 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Exported interface for CPUIdle only. This function is called when interrupts | ||
57 | * are turned off. Hence, no locking. | ||
58 | */ | ||
59 | int power_state_active_is_enabled(void) | ||
60 | { | ||
61 | return (power_state_active_cnt > 0); | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * struct db8500_regulator_info - db8500 regulator information | ||
66 | * @dev: device pointer | ||
67 | * @desc: regulator description | ||
68 | * @rdev: regulator device pointer | ||
69 | * @is_enabled: status of the regulator | ||
70 | * @epod_id: id for EPOD (power domain) | ||
71 | * @is_ramret: RAM retention switch for EPOD (power domain) | ||
72 | * @operating_point: operating point (only for vape, to be removed) | ||
73 | * | ||
74 | */ | ||
75 | struct db8500_regulator_info { | ||
76 | struct device *dev; | ||
77 | struct regulator_desc desc; | ||
78 | struct regulator_dev *rdev; | ||
79 | bool is_enabled; | ||
80 | u16 epod_id; | ||
81 | bool is_ramret; | ||
82 | bool exclude_from_power_state; | ||
83 | unsigned int operating_point; | ||
84 | }; | ||
85 | 22 | ||
86 | static int db8500_regulator_enable(struct regulator_dev *rdev) | 23 | static int db8500_regulator_enable(struct regulator_dev *rdev) |
87 | { | 24 | { |
88 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 25 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
89 | 26 | ||
90 | if (info == NULL) | 27 | if (info == NULL) |
91 | return -EINVAL; | 28 | return -EINVAL; |
@@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev) | |||
93 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", | 30 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", |
94 | info->desc.name); | 31 | info->desc.name); |
95 | 32 | ||
96 | info->is_enabled = true; | 33 | if (!info->is_enabled) { |
97 | if (!info->exclude_from_power_state) | 34 | info->is_enabled = true; |
98 | power_state_active_enable(); | 35 | if (!info->exclude_from_power_state) |
36 | power_state_active_enable(); | ||
37 | } | ||
99 | 38 | ||
100 | return 0; | 39 | return 0; |
101 | } | 40 | } |
102 | 41 | ||
103 | static int db8500_regulator_disable(struct regulator_dev *rdev) | 42 | static int db8500_regulator_disable(struct regulator_dev *rdev) |
104 | { | 43 | { |
105 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 44 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
106 | int ret = 0; | 45 | int ret = 0; |
107 | 46 | ||
108 | if (info == NULL) | 47 | if (info == NULL) |
@@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev) | |||
111 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", | 50 | dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", |
112 | info->desc.name); | 51 | info->desc.name); |
113 | 52 | ||
114 | info->is_enabled = false; | 53 | if (info->is_enabled) { |
115 | if (!info->exclude_from_power_state) | 54 | info->is_enabled = false; |
116 | ret = power_state_active_disable(); | 55 | if (!info->exclude_from_power_state) |
56 | ret = power_state_active_disable(); | ||
57 | } | ||
117 | 58 | ||
118 | return ret; | 59 | return ret; |
119 | } | 60 | } |
120 | 61 | ||
121 | static int db8500_regulator_is_enabled(struct regulator_dev *rdev) | 62 | static int db8500_regulator_is_enabled(struct regulator_dev *rdev) |
122 | { | 63 | { |
123 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 64 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
124 | 65 | ||
125 | if (info == NULL) | 66 | if (info == NULL) |
126 | return -EINVAL; | 67 | return -EINVAL; |
@@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret) | |||
197 | */ | 138 | */ |
198 | static int db8500_regulator_switch_enable(struct regulator_dev *rdev) | 139 | static int db8500_regulator_switch_enable(struct regulator_dev *rdev) |
199 | { | 140 | { |
200 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 141 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
201 | int ret; | 142 | int ret; |
202 | 143 | ||
203 | if (info == NULL) | 144 | if (info == NULL) |
@@ -221,7 +162,7 @@ out: | |||
221 | 162 | ||
222 | static int db8500_regulator_switch_disable(struct regulator_dev *rdev) | 163 | static int db8500_regulator_switch_disable(struct regulator_dev *rdev) |
223 | { | 164 | { |
224 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 165 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
225 | int ret; | 166 | int ret; |
226 | 167 | ||
227 | if (info == NULL) | 168 | if (info == NULL) |
@@ -245,7 +186,7 @@ out: | |||
245 | 186 | ||
246 | static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) | 187 | static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) |
247 | { | 188 | { |
248 | struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | 189 | struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); |
249 | 190 | ||
250 | if (info == NULL) | 191 | if (info == NULL) |
251 | return -EINVAL; | 192 | return -EINVAL; |
@@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = { | |||
266 | /* | 207 | /* |
267 | * Regulator information | 208 | * Regulator information |
268 | */ | 209 | */ |
269 | static struct db8500_regulator_info | 210 | static struct dbx500_regulator_info |
270 | db8500_regulator_info[DB8500_NUM_REGULATORS] = { | 211 | dbx500_regulator_info[DB8500_NUM_REGULATORS] = { |
271 | [DB8500_REGULATOR_VAPE] = { | 212 | [DB8500_REGULATOR_VAPE] = { |
272 | .desc = { | 213 | .desc = { |
273 | .name = "db8500-vape", | 214 | .name = "db8500-vape", |
@@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
476 | int i, err; | 417 | int i, err; |
477 | 418 | ||
478 | /* register all regulators */ | 419 | /* register all regulators */ |
479 | for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | 420 | for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { |
480 | struct db8500_regulator_info *info; | 421 | struct dbx500_regulator_info *info; |
481 | struct regulator_init_data *init_data = &db8500_init_data[i]; | 422 | struct regulator_init_data *init_data = &db8500_init_data[i]; |
482 | 423 | ||
483 | /* assign per-regulator data */ | 424 | /* assign per-regulator data */ |
484 | info = &db8500_regulator_info[i]; | 425 | info = &dbx500_regulator_info[i]; |
485 | info->dev = &pdev->dev; | 426 | info->dev = &pdev->dev; |
486 | 427 | ||
487 | /* register with the regulator framework */ | 428 | /* register with the regulator framework */ |
@@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
494 | 435 | ||
495 | /* if failing, unregister all earlier regulators */ | 436 | /* if failing, unregister all earlier regulators */ |
496 | while (--i >= 0) { | 437 | while (--i >= 0) { |
497 | info = &db8500_regulator_info[i]; | 438 | info = &dbx500_regulator_info[i]; |
498 | regulator_unregister(info->rdev); | 439 | regulator_unregister(info->rdev); |
499 | } | 440 | } |
500 | return err; | 441 | return err; |
@@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
503 | dev_dbg(rdev_get_dev(info->rdev), | 444 | dev_dbg(rdev_get_dev(info->rdev), |
504 | "regulator-%s-probed\n", info->desc.name); | 445 | "regulator-%s-probed\n", info->desc.name); |
505 | } | 446 | } |
447 | err = ux500_regulator_debug_init(pdev, | ||
448 | dbx500_regulator_info, | ||
449 | ARRAY_SIZE(dbx500_regulator_info)); | ||
506 | 450 | ||
507 | return 0; | 451 | return err; |
508 | } | 452 | } |
509 | 453 | ||
510 | static int __exit db8500_regulator_remove(struct platform_device *pdev) | 454 | static int __exit db8500_regulator_remove(struct platform_device *pdev) |
511 | { | 455 | { |
512 | int i; | 456 | int i; |
513 | 457 | ||
514 | for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | 458 | ux500_regulator_debug_exit(); |
515 | struct db8500_regulator_info *info; | 459 | |
516 | info = &db8500_regulator_info[i]; | 460 | for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { |
461 | struct dbx500_regulator_info *info; | ||
462 | info = &dbx500_regulator_info[i]; | ||
517 | 463 | ||
518 | dev_vdbg(rdev_get_dev(info->rdev), | 464 | dev_vdbg(rdev_get_dev(info->rdev), |
519 | "regulator-%s-remove\n", info->desc.name); | 465 | "regulator-%s-remove\n", info->desc.name); |
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c new file mode 100644 index 000000000000..f2e5ecdc5864 --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | * UX500 common part of Power domain regulators | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/regulator/driver.h> | ||
14 | #include <linux/debugfs.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | #include "dbx500-prcmu.h" | ||
19 | |||
20 | /* | ||
21 | * power state reference count | ||
22 | */ | ||
23 | static int power_state_active_cnt; /* will initialize to zero */ | ||
24 | static DEFINE_SPINLOCK(power_state_active_lock); | ||
25 | |||
26 | int power_state_active_get(void) | ||
27 | { | ||
28 | unsigned long flags; | ||
29 | int cnt; | ||
30 | |||
31 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
32 | cnt = power_state_active_cnt; | ||
33 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
34 | |||
35 | return cnt; | ||
36 | } | ||
37 | |||
38 | void power_state_active_enable(void) | ||
39 | { | ||
40 | unsigned long flags; | ||
41 | |||
42 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
43 | power_state_active_cnt++; | ||
44 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
45 | } | ||
46 | |||
47 | int power_state_active_disable(void) | ||
48 | { | ||
49 | int ret = 0; | ||
50 | unsigned long flags; | ||
51 | |||
52 | spin_lock_irqsave(&power_state_active_lock, flags); | ||
53 | if (power_state_active_cnt <= 0) { | ||
54 | pr_err("power state: unbalanced enable/disable calls\n"); | ||
55 | ret = -EINVAL; | ||
56 | goto out; | ||
57 | } | ||
58 | |||
59 | power_state_active_cnt--; | ||
60 | out: | ||
61 | spin_unlock_irqrestore(&power_state_active_lock, flags); | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | #ifdef CONFIG_REGULATOR_DEBUG | ||
66 | |||
67 | static struct ux500_regulator_debug { | ||
68 | struct dentry *dir; | ||
69 | struct dentry *status_file; | ||
70 | struct dentry *power_state_cnt_file; | ||
71 | struct dbx500_regulator_info *regulator_array; | ||
72 | int num_regulators; | ||
73 | u8 *state_before_suspend; | ||
74 | u8 *state_after_suspend; | ||
75 | } rdebug; | ||
76 | |||
77 | void ux500_regulator_suspend_debug(void) | ||
78 | { | ||
79 | int i; | ||
80 | for (i = 0; i < rdebug.num_regulators; i++) | ||
81 | rdebug.state_before_suspend[i] = | ||
82 | rdebug.regulator_array[i].is_enabled; | ||
83 | } | ||
84 | |||
85 | void ux500_regulator_resume_debug(void) | ||
86 | { | ||
87 | int i; | ||
88 | for (i = 0; i < rdebug.num_regulators; i++) | ||
89 | rdebug.state_after_suspend[i] = | ||
90 | rdebug.regulator_array[i].is_enabled; | ||
91 | } | ||
92 | |||
93 | static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p) | ||
94 | { | ||
95 | struct device *dev = s->private; | ||
96 | int err; | ||
97 | |||
98 | /* print power state count */ | ||
99 | err = seq_printf(s, "ux500-regulator power state count: %i\n", | ||
100 | power_state_active_get()); | ||
101 | if (err < 0) | ||
102 | dev_err(dev, "seq_printf overflow\n"); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int ux500_regulator_power_state_cnt_open(struct inode *inode, | ||
108 | struct file *file) | ||
109 | { | ||
110 | return single_open(file, ux500_regulator_power_state_cnt_print, | ||
111 | inode->i_private); | ||
112 | } | ||
113 | |||
114 | static const struct file_operations ux500_regulator_power_state_cnt_fops = { | ||
115 | .open = ux500_regulator_power_state_cnt_open, | ||
116 | .read = seq_read, | ||
117 | .llseek = seq_lseek, | ||
118 | .release = single_release, | ||
119 | .owner = THIS_MODULE, | ||
120 | }; | ||
121 | |||
122 | static int ux500_regulator_status_print(struct seq_file *s, void *p) | ||
123 | { | ||
124 | struct device *dev = s->private; | ||
125 | int err; | ||
126 | int i; | ||
127 | |||
128 | /* print dump header */ | ||
129 | err = seq_printf(s, "ux500-regulator status:\n"); | ||
130 | if (err < 0) | ||
131 | dev_err(dev, "seq_printf overflow\n"); | ||
132 | |||
133 | err = seq_printf(s, "%31s : %8s : %8s\n", "current", | ||
134 | "before", "after"); | ||
135 | if (err < 0) | ||
136 | dev_err(dev, "seq_printf overflow\n"); | ||
137 | |||
138 | for (i = 0; i < rdebug.num_regulators; i++) { | ||
139 | struct dbx500_regulator_info *info; | ||
140 | /* Access per-regulator data */ | ||
141 | info = &rdebug.regulator_array[i]; | ||
142 | |||
143 | /* print status */ | ||
144 | err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name, | ||
145 | info->is_enabled ? "enabled" : "disabled", | ||
146 | rdebug.state_before_suspend[i] ? "enabled" : "disabled", | ||
147 | rdebug.state_after_suspend[i] ? "enabled" : "disabled"); | ||
148 | if (err < 0) | ||
149 | dev_err(dev, "seq_printf overflow\n"); | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int ux500_regulator_status_open(struct inode *inode, struct file *file) | ||
156 | { | ||
157 | return single_open(file, ux500_regulator_status_print, | ||
158 | inode->i_private); | ||
159 | } | ||
160 | |||
161 | static const struct file_operations ux500_regulator_status_fops = { | ||
162 | .open = ux500_regulator_status_open, | ||
163 | .read = seq_read, | ||
164 | .llseek = seq_lseek, | ||
165 | .release = single_release, | ||
166 | .owner = THIS_MODULE, | ||
167 | }; | ||
168 | |||
169 | int __attribute__((weak)) dbx500_regulator_testcase( | ||
170 | struct dbx500_regulator_info *regulator_info, | ||
171 | int num_regulators) | ||
172 | { | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | int __devinit | ||
177 | ux500_regulator_debug_init(struct platform_device *pdev, | ||
178 | struct dbx500_regulator_info *regulator_info, | ||
179 | int num_regulators) | ||
180 | { | ||
181 | /* create directory */ | ||
182 | rdebug.dir = debugfs_create_dir("ux500-regulator", NULL); | ||
183 | if (!rdebug.dir) | ||
184 | goto exit_no_debugfs; | ||
185 | |||
186 | /* create "status" file */ | ||
187 | rdebug.status_file = debugfs_create_file("status", | ||
188 | S_IRUGO, rdebug.dir, &pdev->dev, | ||
189 | &ux500_regulator_status_fops); | ||
190 | if (!rdebug.status_file) | ||
191 | goto exit_destroy_dir; | ||
192 | |||
193 | /* create "power-state-count" file */ | ||
194 | rdebug.power_state_cnt_file = debugfs_create_file("power-state-count", | ||
195 | S_IRUGO, rdebug.dir, &pdev->dev, | ||
196 | &ux500_regulator_power_state_cnt_fops); | ||
197 | if (!rdebug.power_state_cnt_file) | ||
198 | goto exit_destroy_status; | ||
199 | |||
200 | rdebug.regulator_array = regulator_info; | ||
201 | rdebug.num_regulators = num_regulators; | ||
202 | |||
203 | rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); | ||
204 | if (!rdebug.state_before_suspend) { | ||
205 | dev_err(&pdev->dev, | ||
206 | "could not allocate memory for saving state\n"); | ||
207 | goto exit_destroy_power_state; | ||
208 | } | ||
209 | |||
210 | rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); | ||
211 | if (!rdebug.state_after_suspend) { | ||
212 | dev_err(&pdev->dev, | ||
213 | "could not allocate memory for saving state\n"); | ||
214 | goto exit_free; | ||
215 | } | ||
216 | |||
217 | dbx500_regulator_testcase(regulator_info, num_regulators); | ||
218 | return 0; | ||
219 | |||
220 | exit_free: | ||
221 | kfree(rdebug.state_before_suspend); | ||
222 | exit_destroy_power_state: | ||
223 | debugfs_remove(rdebug.power_state_cnt_file); | ||
224 | exit_destroy_status: | ||
225 | debugfs_remove(rdebug.status_file); | ||
226 | exit_destroy_dir: | ||
227 | debugfs_remove(rdebug.dir); | ||
228 | exit_no_debugfs: | ||
229 | dev_err(&pdev->dev, "failed to create debugfs entries.\n"); | ||
230 | return -ENOMEM; | ||
231 | } | ||
232 | |||
233 | int __devexit ux500_regulator_debug_exit(void) | ||
234 | { | ||
235 | debugfs_remove_recursive(rdebug.dir); | ||
236 | kfree(rdebug.state_after_suspend); | ||
237 | kfree(rdebug.state_before_suspend); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | #endif | ||
diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h new file mode 100644 index 000000000000..e763883a44f4 --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Bengt Jonsson <bengt.jonsson@stericsson.com> for ST-Ericsson, | ||
5 | * Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * License Terms: GNU General Public License v2 | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef DBX500_REGULATOR_H | ||
12 | #define DBX500_REGULATOR_H | ||
13 | |||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | /** | ||
17 | * struct dbx500_regulator_info - dbx500 regulator information | ||
18 | * @dev: device pointer | ||
19 | * @desc: regulator description | ||
20 | * @rdev: regulator device pointer | ||
21 | * @is_enabled: status of the regulator | ||
22 | * @epod_id: id for EPOD (power domain) | ||
23 | * @is_ramret: RAM retention switch for EPOD (power domain) | ||
24 | * @operating_point: operating point (only for vape, to be removed) | ||
25 | * | ||
26 | */ | ||
27 | struct dbx500_regulator_info { | ||
28 | struct device *dev; | ||
29 | struct regulator_desc desc; | ||
30 | struct regulator_dev *rdev; | ||
31 | bool is_enabled; | ||
32 | u16 epod_id; | ||
33 | bool is_ramret; | ||
34 | bool exclude_from_power_state; | ||
35 | unsigned int operating_point; | ||
36 | }; | ||
37 | |||
38 | void power_state_active_enable(void); | ||
39 | int power_state_active_disable(void); | ||
40 | |||
41 | |||
42 | #ifdef CONFIG_REGULATOR_DEBUG | ||
43 | int ux500_regulator_debug_init(struct platform_device *pdev, | ||
44 | struct dbx500_regulator_info *regulator_info, | ||
45 | int num_regulators); | ||
46 | |||
47 | int ux500_regulator_debug_exit(void); | ||
48 | #else | ||
49 | |||
50 | static inline int ux500_regulator_debug_init(struct platform_device *pdev, | ||
51 | struct dbx500_regulator_info *regulator_info, | ||
52 | int num_regulators) | ||
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static inline int ux500_regulator_debug_exit(void) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | #endif | ||
63 | #endif | ||
diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c new file mode 100644 index 000000000000..30d0a15b8949 --- /dev/null +++ b/drivers/regulator/fixed-helper.c | |||
@@ -0,0 +1,53 @@ | |||
1 | #include <linux/slab.h> | ||
2 | #include <linux/platform_device.h> | ||
3 | #include <linux/regulator/machine.h> | ||
4 | #include <linux/regulator/fixed.h> | ||
5 | |||
6 | struct fixed_regulator_data { | ||
7 | struct fixed_voltage_config cfg; | ||
8 | struct regulator_init_data init_data; | ||
9 | struct platform_device pdev; | ||
10 | }; | ||
11 | |||
12 | static void regulator_fixed_release(struct device *dev) | ||
13 | { | ||
14 | struct fixed_regulator_data *data = container_of(dev, | ||
15 | struct fixed_regulator_data, pdev.dev); | ||
16 | kfree(data); | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * regulator_register_fixed - register a no-op fixed regulator | ||
21 | * @name: supply name | ||
22 | * @id: platform device id | ||
23 | * @supplies: consumers for this regulator | ||
24 | * @num_supplies: number of consumers | ||
25 | */ | ||
26 | struct platform_device *regulator_register_fixed(int id, | ||
27 | struct regulator_consumer_supply *supplies, int num_supplies) | ||
28 | { | ||
29 | struct fixed_regulator_data *data; | ||
30 | |||
31 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
32 | if (!data) | ||
33 | return NULL; | ||
34 | |||
35 | data->cfg.supply_name = "dummy"; | ||
36 | data->cfg.microvolts = 0; | ||
37 | data->cfg.gpio = -EINVAL; | ||
38 | data->cfg.enabled_at_boot = 1; | ||
39 | data->cfg.init_data = &data->init_data; | ||
40 | |||
41 | data->init_data.constraints.always_on = 1; | ||
42 | data->init_data.consumer_supplies = supplies; | ||
43 | data->init_data.num_consumer_supplies = num_supplies; | ||
44 | |||
45 | data->pdev.name = "reg-fixed-voltage"; | ||
46 | data->pdev.id = id; | ||
47 | data->pdev.dev.platform_data = &data->cfg; | ||
48 | data->pdev.dev.release = regulator_fixed_release; | ||
49 | |||
50 | platform_device_register(&data->pdev); | ||
51 | |||
52 | return &data->pdev; | ||
53 | } | ||
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index e24e3a174c4b..40f38030b394 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
@@ -192,7 +192,9 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) | |||
192 | drvdata->desc.type = REGULATOR_VOLTAGE; | 192 | drvdata->desc.type = REGULATOR_VOLTAGE; |
193 | drvdata->desc.owner = THIS_MODULE; | 193 | drvdata->desc.owner = THIS_MODULE; |
194 | drvdata->desc.ops = &fixed_voltage_ops; | 194 | drvdata->desc.ops = &fixed_voltage_ops; |
195 | drvdata->desc.n_voltages = 1; | 195 | |
196 | if (config->microvolts) | ||
197 | drvdata->desc.n_voltages = 1; | ||
196 | 198 | ||
197 | drvdata->microvolts = config->microvolts; | 199 | drvdata->microvolts = config->microvolts; |
198 | drvdata->gpio = config->gpio; | 200 | drvdata->gpio = config->gpio; |
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index c1a456c4257c..775f5fd208c3 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c | |||
@@ -63,23 +63,15 @@ static int isl6271a_set_voltage(struct regulator_dev *dev, | |||
63 | unsigned *selector) | 63 | unsigned *selector) |
64 | { | 64 | { |
65 | struct isl_pmic *pmic = rdev_get_drvdata(dev); | 65 | struct isl_pmic *pmic = rdev_get_drvdata(dev); |
66 | int vsel, err, data; | 66 | int err, data; |
67 | 67 | ||
68 | if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX) | 68 | if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX) |
69 | return -EINVAL; | 69 | return -EINVAL; |
70 | if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX) | 70 | if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX) |
71 | return -EINVAL; | 71 | return -EINVAL; |
72 | 72 | ||
73 | /* Align to 50000 mV */ | 73 | data = DIV_ROUND_UP(minuV - ISL6271A_VOLTAGE_MIN, |
74 | vsel = minuV - (minuV % ISL6271A_VOLTAGE_STEP); | 74 | ISL6271A_VOLTAGE_STEP); |
75 | |||
76 | /* If the result fell out of [minuV,maxuV] range, put it back */ | ||
77 | if (vsel < minuV) | ||
78 | vsel += ISL6271A_VOLTAGE_STEP; | ||
79 | |||
80 | /* Convert the microvolts to data for the chip */ | ||
81 | data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP; | ||
82 | |||
83 | *selector = data; | 75 | *selector = data; |
84 | 76 | ||
85 | mutex_lock(&pmic->mtx); | 77 | mutex_lock(&pmic->mtx); |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 40e7a4db2853..282d2ee0604e 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
@@ -76,8 +76,8 @@ static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
76 | if (min_uV < max1586->min_uV) | 76 | if (min_uV < max1586->min_uV) |
77 | min_uV = max1586->min_uV; | 77 | min_uV = max1586->min_uV; |
78 | 78 | ||
79 | *selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL + | 79 | *selector = DIV_ROUND_UP((min_uV - max1586->min_uV) * |
80 | range_uV - 1) / range_uV; | 80 | MAX1586_V3_MAX_VSEL, range_uV); |
81 | if (max1586_v3_calc_voltage(max1586, *selector) > max_uV) | 81 | if (max1586_v3_calc_voltage(max1586, *selector) > max_uV) |
82 | return -EINVAL; | 82 | return -EINVAL; |
83 | 83 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index d0e1180ad961..824c650436ed 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -101,8 +101,7 @@ static int max8649_set_voltage(struct regulator_dev *rdev, | |||
101 | min_uV, max_uV); | 101 | min_uV, max_uV); |
102 | return -EINVAL; | 102 | return -EINVAL; |
103 | } | 103 | } |
104 | data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) | 104 | data = DIV_ROUND_UP(min_uV - MAX8649_DCDC_VMIN, MAX8649_DCDC_STEP); |
105 | / MAX8649_DCDC_STEP; | ||
106 | mask = MAX8649_VOL_MASK; | 105 | mask = MAX8649_VOL_MASK; |
107 | *selector = data & mask; | 106 | *selector = data & mask; |
108 | 107 | ||
@@ -270,7 +269,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, | |||
270 | ret); | 269 | ret); |
271 | goto out; | 270 | goto out; |
272 | } | 271 | } |
273 | dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret); | 272 | dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); |
274 | 273 | ||
275 | /* enable VID0 & VID1 */ | 274 | /* enable VID0 & VID1 */ |
276 | regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); | 275 | regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index a838e664569f..4c5b05311f47 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
@@ -153,14 +153,15 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
153 | if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV) | 153 | if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV) |
154 | return -EINVAL; | 154 | return -EINVAL; |
155 | 155 | ||
156 | selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1)) | 156 | selector = DIV_ROUND_UP(min_uV - MAX8660_DCDC_MIN_UV, |
157 | / MAX8660_DCDC_STEP; | 157 | MAX8660_DCDC_STEP); |
158 | *s = selector; | ||
159 | 158 | ||
160 | ret = max8660_dcdc_list(rdev, selector); | 159 | ret = max8660_dcdc_list(rdev, selector); |
161 | if (ret < 0 || ret > max_uV) | 160 | if (ret < 0 || ret > max_uV) |
162 | return -EINVAL; | 161 | return -EINVAL; |
163 | 162 | ||
163 | *s = selector; | ||
164 | |||
164 | reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; | 165 | reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; |
165 | ret = max8660_write(max8660, reg, 0, selector); | 166 | ret = max8660_write(max8660, reg, 0, selector); |
166 | if (ret) | 167 | if (ret) |
@@ -210,8 +211,9 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
210 | if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV) | 211 | if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV) |
211 | return -EINVAL; | 212 | return -EINVAL; |
212 | 213 | ||
213 | selector = (min_uV - (MAX8660_LDO5_MIN_UV - MAX8660_LDO5_STEP + 1)) | 214 | selector = DIV_ROUND_UP(min_uV - MAX8660_LDO5_MIN_UV, |
214 | / MAX8660_LDO5_STEP; | 215 | MAX8660_LDO5_STEP); |
216 | |||
215 | ret = max8660_ldo5_list(rdev, selector); | 217 | ret = max8660_ldo5_list(rdev, selector); |
216 | if (ret < 0 || ret > max_uV) | 218 | if (ret < 0 || ret > max_uV) |
217 | return -EINVAL; | 219 | return -EINVAL; |
@@ -287,8 +289,8 @@ static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, | |||
287 | if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV) | 289 | if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV) |
288 | return -EINVAL; | 290 | return -EINVAL; |
289 | 291 | ||
290 | selector = (min_uV - (MAX8660_LDO67_MIN_UV - MAX8660_LDO67_STEP + 1)) | 292 | selector = DIV_ROUND_UP(min_uV - MAX8660_LDO67_MIN_UV, |
291 | / MAX8660_LDO67_STEP; | 293 | MAX8660_LDO67_STEP); |
292 | 294 | ||
293 | ret = max8660_ldo67_list(rdev, selector); | 295 | ret = max8660_ldo67_list(rdev, selector); |
294 | if (ret < 0 || ret > max_uV) | 296 | if (ret < 0 || ret > max_uV) |
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index cc290d37c463..2f242f43096e 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c | |||
@@ -73,7 +73,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev, | |||
73 | min_uV, max_uV); | 73 | min_uV, max_uV); |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | } | 75 | } |
76 | data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 76 | data = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
77 | *selector = data; | 77 | *selector = data; |
78 | data <<= info->vol_shift; | 78 | data <<= info->vol_shift; |
79 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 79 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
@@ -140,7 +140,7 @@ static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV) | |||
140 | if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX) | 140 | if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX) |
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | 142 | ||
143 | data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP; | 143 | data = DIV_ROUND_UP(uV - SD1_DVM_VMIN, SD1_DVM_STEP); |
144 | data <<= SD1_DVM_SHIFT; | 144 | data <<= SD1_DVM_SHIFT; |
145 | mask = 3 << SD1_DVM_SHIFT; | 145 | mask = 3 << SD1_DVM_SHIFT; |
146 | 146 | ||
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index d26e8646277b..96579296f04d 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -130,15 +130,10 @@ static const struct voltage_map_desc *reg_voltage_map[] = { | |||
130 | [MAX8997_CHARGER_TOPOFF] = &topoff_current_map_desc, | 130 | [MAX8997_CHARGER_TOPOFF] = &topoff_current_map_desc, |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static inline int max8997_get_rid(struct regulator_dev *rdev) | ||
134 | { | ||
135 | return rdev_get_id(rdev); | ||
136 | } | ||
137 | |||
138 | static int max8997_list_voltage_safeout(struct regulator_dev *rdev, | 133 | static int max8997_list_voltage_safeout(struct regulator_dev *rdev, |
139 | unsigned int selector) | 134 | unsigned int selector) |
140 | { | 135 | { |
141 | int rid = max8997_get_rid(rdev); | 136 | int rid = rdev_get_id(rdev); |
142 | 137 | ||
143 | if (rid == MAX8997_ESAFEOUT1 || rid == MAX8997_ESAFEOUT2) { | 138 | if (rid == MAX8997_ESAFEOUT1 || rid == MAX8997_ESAFEOUT2) { |
144 | switch (selector) { | 139 | switch (selector) { |
@@ -161,7 +156,7 @@ static int max8997_list_voltage_safeout(struct regulator_dev *rdev, | |||
161 | static int max8997_list_voltage_charger_cv(struct regulator_dev *rdev, | 156 | static int max8997_list_voltage_charger_cv(struct regulator_dev *rdev, |
162 | unsigned int selector) | 157 | unsigned int selector) |
163 | { | 158 | { |
164 | int rid = max8997_get_rid(rdev); | 159 | int rid = rdev_get_id(rdev); |
165 | 160 | ||
166 | if (rid != MAX8997_CHARGER_CV) | 161 | if (rid != MAX8997_CHARGER_CV) |
167 | goto err; | 162 | goto err; |
@@ -184,7 +179,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev, | |||
184 | unsigned int selector) | 179 | unsigned int selector) |
185 | { | 180 | { |
186 | const struct voltage_map_desc *desc; | 181 | const struct voltage_map_desc *desc; |
187 | int rid = max8997_get_rid(rdev); | 182 | int rid = rdev_get_id(rdev); |
188 | int val; | 183 | int val; |
189 | 184 | ||
190 | if (rid >= ARRAY_SIZE(reg_voltage_map) || | 185 | if (rid >= ARRAY_SIZE(reg_voltage_map) || |
@@ -205,7 +200,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev, | |||
205 | static int max8997_get_enable_register(struct regulator_dev *rdev, | 200 | static int max8997_get_enable_register(struct regulator_dev *rdev, |
206 | int *reg, int *mask, int *pattern) | 201 | int *reg, int *mask, int *pattern) |
207 | { | 202 | { |
208 | int rid = max8997_get_rid(rdev); | 203 | int rid = rdev_get_id(rdev); |
209 | 204 | ||
210 | switch (rid) { | 205 | switch (rid) { |
211 | case MAX8997_LDO1 ... MAX8997_LDO21: | 206 | case MAX8997_LDO1 ... MAX8997_LDO21: |
@@ -325,7 +320,7 @@ static int max8997_reg_disable(struct regulator_dev *rdev) | |||
325 | static int max8997_get_voltage_register(struct regulator_dev *rdev, | 320 | static int max8997_get_voltage_register(struct regulator_dev *rdev, |
326 | int *_reg, int *_shift, int *_mask) | 321 | int *_reg, int *_shift, int *_mask) |
327 | { | 322 | { |
328 | int rid = max8997_get_rid(rdev); | 323 | int rid = rdev_get_id(rdev); |
329 | int reg, shift = 0, mask = 0x3f; | 324 | int reg, shift = 0, mask = 0x3f; |
330 | 325 | ||
331 | switch (rid) { | 326 | switch (rid) { |
@@ -386,7 +381,7 @@ static int max8997_get_voltage(struct regulator_dev *rdev) | |||
386 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 381 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
387 | struct i2c_client *i2c = max8997->iodev->i2c; | 382 | struct i2c_client *i2c = max8997->iodev->i2c; |
388 | int reg, shift, mask, ret; | 383 | int reg, shift, mask, ret; |
389 | int rid = max8997_get_rid(rdev); | 384 | int rid = rdev_get_id(rdev); |
390 | u8 val; | 385 | u8 val; |
391 | 386 | ||
392 | ret = max8997_get_voltage_register(rdev, ®, &shift, &mask); | 387 | ret = max8997_get_voltage_register(rdev, ®, &shift, &mask); |
@@ -446,7 +441,7 @@ static int max8997_set_voltage_charger_cv(struct regulator_dev *rdev, | |||
446 | { | 441 | { |
447 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 442 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
448 | struct i2c_client *i2c = max8997->iodev->i2c; | 443 | struct i2c_client *i2c = max8997->iodev->i2c; |
449 | int rid = max8997_get_rid(rdev); | 444 | int rid = rdev_get_id(rdev); |
450 | int lb, ub; | 445 | int lb, ub; |
451 | int reg, shift = 0, mask, ret = 0; | 446 | int reg, shift = 0, mask, ret = 0; |
452 | u8 val = 0x0; | 447 | u8 val = 0x0; |
@@ -503,7 +498,7 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, | |||
503 | struct i2c_client *i2c = max8997->iodev->i2c; | 498 | struct i2c_client *i2c = max8997->iodev->i2c; |
504 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; | 499 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; |
505 | const struct voltage_map_desc *desc; | 500 | const struct voltage_map_desc *desc; |
506 | int rid = max8997_get_rid(rdev); | 501 | int rid = rdev_get_id(rdev); |
507 | int reg, shift = 0, mask, ret; | 502 | int reg, shift = 0, mask, ret; |
508 | int i; | 503 | int i; |
509 | u8 org; | 504 | u8 org; |
@@ -564,7 +559,7 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev, | |||
564 | u8 new_val, int *best) | 559 | u8 new_val, int *best) |
565 | { | 560 | { |
566 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 561 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
567 | int rid = max8997_get_rid(rdev); | 562 | int rid = rdev_get_id(rdev); |
568 | u8 *buckx_val[3]; | 563 | u8 *buckx_val[3]; |
569 | bool buckx_gpiodvs[3]; | 564 | bool buckx_gpiodvs[3]; |
570 | int side_effect[8]; | 565 | int side_effect[8]; |
@@ -641,7 +636,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, | |||
641 | int min_uV, int max_uV, unsigned *selector) | 636 | int min_uV, int max_uV, unsigned *selector) |
642 | { | 637 | { |
643 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 638 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
644 | int rid = max8997_get_rid(rdev); | 639 | int rid = rdev_get_id(rdev); |
645 | const struct voltage_map_desc *desc; | 640 | const struct voltage_map_desc *desc; |
646 | int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg; | 641 | int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg; |
647 | bool gpio_dvs_mode = false; | 642 | bool gpio_dvs_mode = false; |
@@ -724,7 +719,7 @@ static int max8997_set_voltage_safeout(struct regulator_dev *rdev, | |||
724 | { | 719 | { |
725 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 720 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
726 | struct i2c_client *i2c = max8997->iodev->i2c; | 721 | struct i2c_client *i2c = max8997->iodev->i2c; |
727 | int rid = max8997_get_rid(rdev); | 722 | int rid = rdev_get_id(rdev); |
728 | int reg, shift = 0, mask, ret; | 723 | int reg, shift = 0, mask, ret; |
729 | int i = 0; | 724 | int i = 0; |
730 | u8 val; | 725 | u8 val; |
@@ -766,7 +761,7 @@ static int max8997_reg_disable_suspend(struct regulator_dev *rdev) | |||
766 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 761 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
767 | struct i2c_client *i2c = max8997->iodev->i2c; | 762 | struct i2c_client *i2c = max8997->iodev->i2c; |
768 | int ret, reg, mask, pattern; | 763 | int ret, reg, mask, pattern; |
769 | int rid = max8997_get_rid(rdev); | 764 | int rid = rdev_get_id(rdev); |
770 | 765 | ||
771 | ret = max8997_get_enable_register(rdev, ®, &mask, &pattern); | 766 | ret = max8997_get_enable_register(rdev, ®, &mask, &pattern); |
772 | if (ret) | 767 | if (ret) |
@@ -908,13 +903,13 @@ static struct regulator_desc regulators[] = { | |||
908 | }, | 903 | }, |
909 | regulator_desc_buck(7), | 904 | regulator_desc_buck(7), |
910 | { | 905 | { |
911 | .name = "EN32KHz AP", | 906 | .name = "EN32KHz_AP", |
912 | .id = MAX8997_EN32KHZ_AP, | 907 | .id = MAX8997_EN32KHZ_AP, |
913 | .ops = &max8997_fixedvolt_ops, | 908 | .ops = &max8997_fixedvolt_ops, |
914 | .type = REGULATOR_VOLTAGE, | 909 | .type = REGULATOR_VOLTAGE, |
915 | .owner = THIS_MODULE, | 910 | .owner = THIS_MODULE, |
916 | }, { | 911 | }, { |
917 | .name = "EN32KHz CP", | 912 | .name = "EN32KHz_CP", |
918 | .id = MAX8997_EN32KHZ_CP, | 913 | .id = MAX8997_EN32KHZ_CP, |
919 | .ops = &max8997_fixedvolt_ops, | 914 | .ops = &max8997_fixedvolt_ops, |
920 | .type = REGULATOR_VOLTAGE, | 915 | .type = REGULATOR_VOLTAGE, |
@@ -938,7 +933,7 @@ static struct regulator_desc regulators[] = { | |||
938 | .type = REGULATOR_VOLTAGE, | 933 | .type = REGULATOR_VOLTAGE, |
939 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
940 | }, { | 935 | }, { |
941 | .name = "CHARGER CV", | 936 | .name = "CHARGER_CV", |
942 | .id = MAX8997_CHARGER_CV, | 937 | .id = MAX8997_CHARGER_CV, |
943 | .ops = &max8997_fixedstate_ops, | 938 | .ops = &max8997_fixedstate_ops, |
944 | .type = REGULATOR_VOLTAGE, | 939 | .type = REGULATOR_VOLTAGE, |
@@ -950,7 +945,7 @@ static struct regulator_desc regulators[] = { | |||
950 | .type = REGULATOR_CURRENT, | 945 | .type = REGULATOR_CURRENT, |
951 | .owner = THIS_MODULE, | 946 | .owner = THIS_MODULE, |
952 | }, { | 947 | }, { |
953 | .name = "CHARGER TOPOFF", | 948 | .name = "CHARGER_TOPOFF", |
954 | .id = MAX8997_CHARGER_TOPOFF, | 949 | .id = MAX8997_CHARGER_TOPOFF, |
955 | .ops = &max8997_charger_fixedstate_ops, | 950 | .ops = &max8997_charger_fixedstate_ops, |
956 | .type = REGULATOR_CURRENT, | 951 | .type = REGULATOR_CURRENT, |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 2d38c2493a07..5890265eeacc 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -112,16 +112,11 @@ static const struct voltage_map_desc *ldo_voltage_map[] = { | |||
112 | &buck4_voltage_map_desc, /* BUCK4 */ | 112 | &buck4_voltage_map_desc, /* BUCK4 */ |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static inline int max8998_get_ldo(struct regulator_dev *rdev) | ||
116 | { | ||
117 | return rdev_get_id(rdev); | ||
118 | } | ||
119 | |||
120 | static int max8998_list_voltage(struct regulator_dev *rdev, | 115 | static int max8998_list_voltage(struct regulator_dev *rdev, |
121 | unsigned int selector) | 116 | unsigned int selector) |
122 | { | 117 | { |
123 | const struct voltage_map_desc *desc; | 118 | const struct voltage_map_desc *desc; |
124 | int ldo = max8998_get_ldo(rdev); | 119 | int ldo = rdev_get_id(rdev); |
125 | int val; | 120 | int val; |
126 | 121 | ||
127 | if (ldo >= ARRAY_SIZE(ldo_voltage_map)) | 122 | if (ldo >= ARRAY_SIZE(ldo_voltage_map)) |
@@ -141,7 +136,7 @@ static int max8998_list_voltage(struct regulator_dev *rdev, | |||
141 | static int max8998_get_enable_register(struct regulator_dev *rdev, | 136 | static int max8998_get_enable_register(struct regulator_dev *rdev, |
142 | int *reg, int *shift) | 137 | int *reg, int *shift) |
143 | { | 138 | { |
144 | int ldo = max8998_get_ldo(rdev); | 139 | int ldo = rdev_get_id(rdev); |
145 | 140 | ||
146 | switch (ldo) { | 141 | switch (ldo) { |
147 | case MAX8998_LDO2 ... MAX8998_LDO5: | 142 | case MAX8998_LDO2 ... MAX8998_LDO5: |
@@ -222,7 +217,7 @@ static int max8998_ldo_disable(struct regulator_dev *rdev) | |||
222 | static int max8998_get_voltage_register(struct regulator_dev *rdev, | 217 | static int max8998_get_voltage_register(struct regulator_dev *rdev, |
223 | int *_reg, int *_shift, int *_mask) | 218 | int *_reg, int *_shift, int *_mask) |
224 | { | 219 | { |
225 | int ldo = max8998_get_ldo(rdev); | 220 | int ldo = rdev_get_id(rdev); |
226 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | 221 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); |
227 | int reg, shift = 0, mask = 0xff; | 222 | int reg, shift = 0, mask = 0xff; |
228 | 223 | ||
@@ -310,7 +305,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, | |||
310 | struct i2c_client *i2c = max8998->iodev->i2c; | 305 | struct i2c_client *i2c = max8998->iodev->i2c; |
311 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; | 306 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; |
312 | const struct voltage_map_desc *desc; | 307 | const struct voltage_map_desc *desc; |
313 | int ldo = max8998_get_ldo(rdev); | 308 | int ldo = rdev_get_id(rdev); |
314 | int reg, shift = 0, mask, ret; | 309 | int reg, shift = 0, mask, ret; |
315 | int i = 0; | 310 | int i = 0; |
316 | 311 | ||
@@ -362,7 +357,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, | |||
362 | struct i2c_client *i2c = max8998->iodev->i2c; | 357 | struct i2c_client *i2c = max8998->iodev->i2c; |
363 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; | 358 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; |
364 | const struct voltage_map_desc *desc; | 359 | const struct voltage_map_desc *desc; |
365 | int buck = max8998_get_ldo(rdev); | 360 | int buck = rdev_get_id(rdev); |
366 | int reg, shift = 0, mask, ret; | 361 | int reg, shift = 0, mask, ret; |
367 | int difference = 0, i = 0, j = 0, previous_vol = 0; | 362 | int difference = 0, i = 0, j = 0, previous_vol = 0; |
368 | u8 val = 0; | 363 | u8 val = 0; |
@@ -829,7 +824,6 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
829 | buck12_voltage_map_desc.step*i | 824 | buck12_voltage_map_desc.step*i |
830 | < (pdata->buck2_voltage2 / 1000)) | 825 | < (pdata->buck2_voltage2 / 1000)) |
831 | i++; | 826 | i++; |
832 | printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
833 | max8998->buck2_vol[1] = i; | 827 | max8998->buck2_vol[1] = i; |
834 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); | 828 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); |
835 | if (ret) | 829 | if (ret) |
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 8e9b90ad88ae..6c0face87ffe 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -344,6 +344,9 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | |||
344 | 344 | ||
345 | dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); | 345 | dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); |
346 | 346 | ||
347 | if (!pdata) | ||
348 | return -EINVAL; | ||
349 | |||
347 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + | 350 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + |
348 | pdata->num_regulators * sizeof(priv->regulators[0]), | 351 | pdata->num_regulators * sizeof(priv->regulators[0]), |
349 | GFP_KERNEL); | 352 | GFP_KERNEL); |
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 1d1c31056297..6db46c632f13 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c | |||
@@ -142,6 +142,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, | |||
142 | case PCF50633_REGULATOR_LDO5: | 142 | case PCF50633_REGULATOR_LDO5: |
143 | case PCF50633_REGULATOR_LDO6: | 143 | case PCF50633_REGULATOR_LDO6: |
144 | case PCF50633_REGULATOR_HCLDO: | 144 | case PCF50633_REGULATOR_HCLDO: |
145 | case PCF50633_REGULATOR_MEMLDO: | ||
145 | volt_bits = ldo_voltage_bits(millivolts); | 146 | volt_bits = ldo_voltage_bits(millivolts); |
146 | break; | 147 | break; |
147 | default: | 148 | default: |
@@ -175,6 +176,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, | |||
175 | case PCF50633_REGULATOR_LDO5: | 176 | case PCF50633_REGULATOR_LDO5: |
176 | case PCF50633_REGULATOR_LDO6: | 177 | case PCF50633_REGULATOR_LDO6: |
177 | case PCF50633_REGULATOR_HCLDO: | 178 | case PCF50633_REGULATOR_HCLDO: |
179 | case PCF50633_REGULATOR_MEMLDO: | ||
178 | millivolts = ldo_voltage_value(bits); | 180 | millivolts = ldo_voltage_value(bits); |
179 | break; | 181 | break; |
180 | default: | 182 | default: |
@@ -217,9 +219,6 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, | |||
217 | case PCF50633_REGULATOR_AUTO: | 219 | case PCF50633_REGULATOR_AUTO: |
218 | index += 0x2f; | 220 | index += 0x2f; |
219 | break; | 221 | break; |
220 | case PCF50633_REGULATOR_HCLDO: | ||
221 | index += 0x01; | ||
222 | break; | ||
223 | default: | 222 | default: |
224 | break; | 223 | break; |
225 | } | 224 | } |
@@ -288,27 +287,27 @@ static struct regulator_ops pcf50633_regulator_ops = { | |||
288 | 287 | ||
289 | static struct regulator_desc regulators[] = { | 288 | static struct regulator_desc regulators[] = { |
290 | [PCF50633_REGULATOR_AUTO] = | 289 | [PCF50633_REGULATOR_AUTO] = |
291 | PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80), | 290 | PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81), |
292 | [PCF50633_REGULATOR_DOWN1] = | 291 | [PCF50633_REGULATOR_DOWN1] = |
293 | PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95), | 292 | PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96), |
294 | [PCF50633_REGULATOR_DOWN2] = | 293 | [PCF50633_REGULATOR_DOWN2] = |
295 | PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95), | 294 | PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96), |
296 | [PCF50633_REGULATOR_LDO1] = | 295 | [PCF50633_REGULATOR_LDO1] = |
297 | PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27), | 296 | PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28), |
298 | [PCF50633_REGULATOR_LDO2] = | 297 | [PCF50633_REGULATOR_LDO2] = |
299 | PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27), | 298 | PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28), |
300 | [PCF50633_REGULATOR_LDO3] = | 299 | [PCF50633_REGULATOR_LDO3] = |
301 | PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27), | 300 | PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28), |
302 | [PCF50633_REGULATOR_LDO4] = | 301 | [PCF50633_REGULATOR_LDO4] = |
303 | PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27), | 302 | PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28), |
304 | [PCF50633_REGULATOR_LDO5] = | 303 | [PCF50633_REGULATOR_LDO5] = |
305 | PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27), | 304 | PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28), |
306 | [PCF50633_REGULATOR_LDO6] = | 305 | [PCF50633_REGULATOR_LDO6] = |
307 | PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27), | 306 | PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28), |
308 | [PCF50633_REGULATOR_HCLDO] = | 307 | [PCF50633_REGULATOR_HCLDO] = |
309 | PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26), | 308 | PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28), |
310 | [PCF50633_REGULATOR_MEMLDO] = | 309 | [PCF50633_REGULATOR_MEMLDO] = |
311 | PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 0), | 310 | PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28), |
312 | }; | 311 | }; |
313 | 312 | ||
314 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) | 313 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c new file mode 100644 index 000000000000..58447db15de1 --- /dev/null +++ b/drivers/regulator/s5m8767.c | |||
@@ -0,0 +1,790 @@ | |||
1 | /* | ||
2 | * s5m8767.c | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/bug.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regulator/driver.h> | ||
22 | #include <linux/regulator/machine.h> | ||
23 | #include <linux/mfd/s5m87xx/s5m-core.h> | ||
24 | #include <linux/mfd/s5m87xx/s5m-pmic.h> | ||
25 | |||
26 | struct s5m8767_info { | ||
27 | struct device *dev; | ||
28 | struct s5m87xx_dev *iodev; | ||
29 | int num_regulators; | ||
30 | struct regulator_dev **rdev; | ||
31 | |||
32 | int ramp_delay; | ||
33 | bool buck2_ramp; | ||
34 | bool buck3_ramp; | ||
35 | bool buck4_ramp; | ||
36 | |||
37 | bool buck2_gpiodvs; | ||
38 | bool buck3_gpiodvs; | ||
39 | bool buck4_gpiodvs; | ||
40 | u8 buck2_vol[8]; | ||
41 | u8 buck3_vol[8]; | ||
42 | u8 buck4_vol[8]; | ||
43 | int buck_gpios[3]; | ||
44 | int buck_gpioindex; | ||
45 | }; | ||
46 | |||
47 | struct s5m_voltage_desc { | ||
48 | int max; | ||
49 | int min; | ||
50 | int step; | ||
51 | }; | ||
52 | |||
53 | static const struct s5m_voltage_desc buck_voltage_val1 = { | ||
54 | .max = 2225000, | ||
55 | .min = 650000, | ||
56 | .step = 6250, | ||
57 | }; | ||
58 | |||
59 | static const struct s5m_voltage_desc buck_voltage_val2 = { | ||
60 | .max = 1600000, | ||
61 | .min = 600000, | ||
62 | .step = 6250, | ||
63 | }; | ||
64 | |||
65 | static const struct s5m_voltage_desc buck_voltage_val3 = { | ||
66 | .max = 3000000, | ||
67 | .min = 750000, | ||
68 | .step = 12500, | ||
69 | }; | ||
70 | |||
71 | static const struct s5m_voltage_desc ldo_voltage_val1 = { | ||
72 | .max = 3950000, | ||
73 | .min = 800000, | ||
74 | .step = 50000, | ||
75 | }; | ||
76 | |||
77 | static const struct s5m_voltage_desc ldo_voltage_val2 = { | ||
78 | .max = 2375000, | ||
79 | .min = 800000, | ||
80 | .step = 25000, | ||
81 | }; | ||
82 | |||
83 | static const struct s5m_voltage_desc *reg_voltage_map[] = { | ||
84 | [S5M8767_LDO1] = &ldo_voltage_val2, | ||
85 | [S5M8767_LDO2] = &ldo_voltage_val2, | ||
86 | [S5M8767_LDO3] = &ldo_voltage_val1, | ||
87 | [S5M8767_LDO4] = &ldo_voltage_val1, | ||
88 | [S5M8767_LDO5] = &ldo_voltage_val1, | ||
89 | [S5M8767_LDO6] = &ldo_voltage_val2, | ||
90 | [S5M8767_LDO7] = &ldo_voltage_val2, | ||
91 | [S5M8767_LDO8] = &ldo_voltage_val2, | ||
92 | [S5M8767_LDO9] = &ldo_voltage_val1, | ||
93 | [S5M8767_LDO10] = &ldo_voltage_val1, | ||
94 | [S5M8767_LDO11] = &ldo_voltage_val1, | ||
95 | [S5M8767_LDO12] = &ldo_voltage_val1, | ||
96 | [S5M8767_LDO13] = &ldo_voltage_val1, | ||
97 | [S5M8767_LDO14] = &ldo_voltage_val1, | ||
98 | [S5M8767_LDO15] = &ldo_voltage_val2, | ||
99 | [S5M8767_LDO16] = &ldo_voltage_val1, | ||
100 | [S5M8767_LDO17] = &ldo_voltage_val1, | ||
101 | [S5M8767_LDO18] = &ldo_voltage_val1, | ||
102 | [S5M8767_LDO19] = &ldo_voltage_val1, | ||
103 | [S5M8767_LDO20] = &ldo_voltage_val1, | ||
104 | [S5M8767_LDO21] = &ldo_voltage_val1, | ||
105 | [S5M8767_LDO22] = &ldo_voltage_val1, | ||
106 | [S5M8767_LDO23] = &ldo_voltage_val1, | ||
107 | [S5M8767_LDO24] = &ldo_voltage_val1, | ||
108 | [S5M8767_LDO25] = &ldo_voltage_val1, | ||
109 | [S5M8767_LDO26] = &ldo_voltage_val1, | ||
110 | [S5M8767_LDO27] = &ldo_voltage_val1, | ||
111 | [S5M8767_LDO28] = &ldo_voltage_val1, | ||
112 | [S5M8767_BUCK1] = &buck_voltage_val1, | ||
113 | [S5M8767_BUCK2] = &buck_voltage_val2, | ||
114 | [S5M8767_BUCK3] = &buck_voltage_val2, | ||
115 | [S5M8767_BUCK4] = &buck_voltage_val2, | ||
116 | [S5M8767_BUCK5] = &buck_voltage_val1, | ||
117 | [S5M8767_BUCK6] = &buck_voltage_val1, | ||
118 | [S5M8767_BUCK7] = NULL, | ||
119 | [S5M8767_BUCK8] = NULL, | ||
120 | [S5M8767_BUCK9] = &buck_voltage_val3, | ||
121 | }; | ||
122 | |||
123 | static int s5m8767_list_voltage(struct regulator_dev *rdev, | ||
124 | unsigned int selector) | ||
125 | { | ||
126 | const struct s5m_voltage_desc *desc; | ||
127 | int reg_id = rdev_get_id(rdev); | ||
128 | int val; | ||
129 | |||
130 | if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) | ||
131 | return -EINVAL; | ||
132 | |||
133 | desc = reg_voltage_map[reg_id]; | ||
134 | if (desc == NULL) | ||
135 | return -EINVAL; | ||
136 | |||
137 | val = desc->min + desc->step * selector; | ||
138 | if (val > desc->max) | ||
139 | return -EINVAL; | ||
140 | |||
141 | return val; | ||
142 | } | ||
143 | |||
144 | static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) | ||
145 | { | ||
146 | int reg_id = rdev_get_id(rdev); | ||
147 | |||
148 | switch (reg_id) { | ||
149 | case S5M8767_LDO1 ... S5M8767_LDO2: | ||
150 | *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); | ||
151 | break; | ||
152 | case S5M8767_LDO3 ... S5M8767_LDO28: | ||
153 | *reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); | ||
154 | break; | ||
155 | case S5M8767_BUCK1: | ||
156 | *reg = S5M8767_REG_BUCK1CTRL1; | ||
157 | break; | ||
158 | case S5M8767_BUCK2 ... S5M8767_BUCK4: | ||
159 | *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9; | ||
160 | break; | ||
161 | case S5M8767_BUCK5: | ||
162 | *reg = S5M8767_REG_BUCK5CTRL1; | ||
163 | break; | ||
164 | case S5M8767_BUCK6 ... S5M8767_BUCK9: | ||
165 | *reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2; | ||
166 | break; | ||
167 | default: | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) | ||
175 | { | ||
176 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
177 | int ret, reg; | ||
178 | int mask = 0xc0, pattern = 0xc0; | ||
179 | u8 val; | ||
180 | |||
181 | ret = s5m8767_get_register(rdev, ®); | ||
182 | if (ret == -EINVAL) | ||
183 | return 1; | ||
184 | else if (ret) | ||
185 | return ret; | ||
186 | |||
187 | ret = s5m_reg_read(s5m8767->iodev, reg, &val); | ||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | return (val & mask) == pattern; | ||
192 | } | ||
193 | |||
194 | static int s5m8767_reg_enable(struct regulator_dev *rdev) | ||
195 | { | ||
196 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
197 | int ret, reg; | ||
198 | int mask = 0xc0, pattern = 0xc0; | ||
199 | |||
200 | ret = s5m8767_get_register(rdev, ®); | ||
201 | if (ret) | ||
202 | return ret; | ||
203 | |||
204 | return s5m_reg_update(s5m8767->iodev, reg, pattern, mask); | ||
205 | } | ||
206 | |||
207 | static int s5m8767_reg_disable(struct regulator_dev *rdev) | ||
208 | { | ||
209 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
210 | int ret, reg; | ||
211 | int mask = 0xc0, pattern = 0xc0; | ||
212 | |||
213 | ret = s5m8767_get_register(rdev, ®); | ||
214 | if (ret) | ||
215 | return ret; | ||
216 | |||
217 | return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask); | ||
218 | } | ||
219 | |||
220 | static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) | ||
221 | { | ||
222 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
223 | int reg_id = rdev_get_id(rdev); | ||
224 | int reg; | ||
225 | |||
226 | switch (reg_id) { | ||
227 | case S5M8767_LDO1 ... S5M8767_LDO2: | ||
228 | reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); | ||
229 | break; | ||
230 | case S5M8767_LDO3 ... S5M8767_LDO28: | ||
231 | reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); | ||
232 | break; | ||
233 | case S5M8767_BUCK1: | ||
234 | reg = S5M8767_REG_BUCK1CTRL2; | ||
235 | break; | ||
236 | case S5M8767_BUCK2: | ||
237 | reg = S5M8767_REG_BUCK2DVS1; | ||
238 | if (s5m8767->buck2_gpiodvs) | ||
239 | reg += s5m8767->buck_gpioindex; | ||
240 | break; | ||
241 | case S5M8767_BUCK3: | ||
242 | reg = S5M8767_REG_BUCK3DVS1; | ||
243 | if (s5m8767->buck3_gpiodvs) | ||
244 | reg += s5m8767->buck_gpioindex; | ||
245 | break; | ||
246 | case S5M8767_BUCK4: | ||
247 | reg = S5M8767_REG_BUCK4DVS1; | ||
248 | if (s5m8767->buck4_gpiodvs) | ||
249 | reg += s5m8767->buck_gpioindex; | ||
250 | break; | ||
251 | case S5M8767_BUCK5: | ||
252 | reg = S5M8767_REG_BUCK5CTRL2; | ||
253 | break; | ||
254 | case S5M8767_BUCK6 ... S5M8767_BUCK9: | ||
255 | reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2; | ||
256 | break; | ||
257 | default: | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | |||
261 | *_reg = reg; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int s5m8767_get_voltage_sel(struct regulator_dev *rdev) | ||
267 | { | ||
268 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
269 | int reg, mask, ret; | ||
270 | int reg_id = rdev_get_id(rdev); | ||
271 | u8 val; | ||
272 | |||
273 | ret = s5m8767_get_voltage_register(rdev, ®); | ||
274 | if (ret) | ||
275 | return ret; | ||
276 | |||
277 | mask = (reg_id < S5M8767_BUCK1) ? 0x3f : 0xff; | ||
278 | |||
279 | ret = s5m_reg_read(s5m8767->iodev, reg, &val); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | val &= mask; | ||
284 | |||
285 | return val; | ||
286 | } | ||
287 | |||
288 | static int s5m8767_convert_voltage_to_sel( | ||
289 | const struct s5m_voltage_desc *desc, | ||
290 | int min_vol, int max_vol) | ||
291 | { | ||
292 | int selector = 0; | ||
293 | |||
294 | if (desc == NULL) | ||
295 | return -EINVAL; | ||
296 | |||
297 | if (max_vol < desc->min || min_vol > desc->max) | ||
298 | return -EINVAL; | ||
299 | |||
300 | selector = (min_vol - desc->min) / desc->step; | ||
301 | |||
302 | if (desc->min + desc->step * selector > max_vol) | ||
303 | return -EINVAL; | ||
304 | |||
305 | return selector; | ||
306 | } | ||
307 | |||
308 | static int s5m8767_set_voltage(struct regulator_dev *rdev, | ||
309 | int min_uV, int max_uV, unsigned *selector) | ||
310 | { | ||
311 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
312 | const struct s5m_voltage_desc *desc; | ||
313 | int reg_id = rdev_get_id(rdev); | ||
314 | int reg, mask, ret; | ||
315 | int i; | ||
316 | u8 val; | ||
317 | |||
318 | switch (reg_id) { | ||
319 | case S5M8767_LDO1 ... S5M8767_LDO28: | ||
320 | mask = 0x3f; | ||
321 | break; | ||
322 | case S5M8767_BUCK1 ... S5M8767_BUCK6: | ||
323 | mask = 0xff; | ||
324 | break; | ||
325 | case S5M8767_BUCK7 ... S5M8767_BUCK8: | ||
326 | return -EINVAL; | ||
327 | case S5M8767_BUCK9: | ||
328 | mask = 0xff; | ||
329 | break; | ||
330 | default: | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | |||
334 | desc = reg_voltage_map[reg_id]; | ||
335 | |||
336 | i = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); | ||
337 | if (i < 0) | ||
338 | return i; | ||
339 | |||
340 | ret = s5m8767_get_voltage_register(rdev, ®); | ||
341 | if (ret) | ||
342 | return ret; | ||
343 | |||
344 | s5m_reg_read(s5m8767->iodev, reg, &val); | ||
345 | val = val & mask; | ||
346 | |||
347 | ret = s5m_reg_write(s5m8767->iodev, reg, val); | ||
348 | *selector = i; | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) | ||
354 | { | ||
355 | int temp_index = s5m8767->buck_gpioindex; | ||
356 | |||
357 | gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); | ||
358 | gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); | ||
359 | gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); | ||
360 | } | ||
361 | |||
362 | static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) | ||
363 | { | ||
364 | int temp_index = s5m8767->buck_gpioindex; | ||
365 | |||
366 | gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); | ||
367 | gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); | ||
368 | gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); | ||
369 | } | ||
370 | |||
371 | static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, | ||
372 | int min_uV, int max_uV, unsigned *selector) | ||
373 | { | ||
374 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
375 | int reg_id = rdev_get_id(rdev); | ||
376 | const struct s5m_voltage_desc *desc; | ||
377 | int new_val, old_val, i = 0; | ||
378 | |||
379 | if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6) | ||
380 | return -EINVAL; | ||
381 | |||
382 | switch (reg_id) { | ||
383 | case S5M8767_BUCK1: | ||
384 | return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); | ||
385 | case S5M8767_BUCK2 ... S5M8767_BUCK4: | ||
386 | break; | ||
387 | case S5M8767_BUCK5 ... S5M8767_BUCK6: | ||
388 | return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); | ||
389 | case S5M8767_BUCK9: | ||
390 | return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); | ||
391 | } | ||
392 | |||
393 | desc = reg_voltage_map[reg_id]; | ||
394 | new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); | ||
395 | if (new_val < 0) | ||
396 | return new_val; | ||
397 | |||
398 | switch (reg_id) { | ||
399 | case S5M8767_BUCK2: | ||
400 | if (s5m8767->buck2_gpiodvs) { | ||
401 | while (s5m8767->buck2_vol[i] != new_val) | ||
402 | i++; | ||
403 | } else | ||
404 | return s5m8767_set_voltage(rdev, min_uV, | ||
405 | max_uV, selector); | ||
406 | break; | ||
407 | case S5M8767_BUCK3: | ||
408 | if (s5m8767->buck3_gpiodvs) { | ||
409 | while (s5m8767->buck3_vol[i] != new_val) | ||
410 | i++; | ||
411 | } else | ||
412 | return s5m8767_set_voltage(rdev, min_uV, | ||
413 | max_uV, selector); | ||
414 | break; | ||
415 | case S5M8767_BUCK4: | ||
416 | if (s5m8767->buck3_gpiodvs) { | ||
417 | while (s5m8767->buck4_vol[i] != new_val) | ||
418 | i++; | ||
419 | } else | ||
420 | return s5m8767_set_voltage(rdev, min_uV, | ||
421 | max_uV, selector); | ||
422 | break; | ||
423 | } | ||
424 | |||
425 | old_val = s5m8767->buck_gpioindex; | ||
426 | s5m8767->buck_gpioindex = i; | ||
427 | |||
428 | if (i > old_val) | ||
429 | s5m8767_set_high(s5m8767); | ||
430 | else | ||
431 | s5m8767_set_low(s5m8767); | ||
432 | |||
433 | *selector = new_val; | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, | ||
438 | unsigned int old_sel, | ||
439 | unsigned int new_sel) | ||
440 | { | ||
441 | struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); | ||
442 | const struct s5m_voltage_desc *desc; | ||
443 | int reg_id = rdev_get_id(rdev); | ||
444 | |||
445 | desc = reg_voltage_map[reg_id]; | ||
446 | |||
447 | if (old_sel < new_sel) | ||
448 | return DIV_ROUND_UP(desc->step * (new_sel - old_sel), | ||
449 | s5m8767->ramp_delay * 1000); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static struct regulator_ops s5m8767_ldo_ops = { | ||
454 | .list_voltage = s5m8767_list_voltage, | ||
455 | .is_enabled = s5m8767_reg_is_enabled, | ||
456 | .enable = s5m8767_reg_enable, | ||
457 | .disable = s5m8767_reg_disable, | ||
458 | .get_voltage_sel = s5m8767_get_voltage_sel, | ||
459 | .set_voltage = s5m8767_set_voltage, | ||
460 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, | ||
461 | }; | ||
462 | |||
463 | static struct regulator_ops s5m8767_buck_ops = { | ||
464 | .list_voltage = s5m8767_list_voltage, | ||
465 | .is_enabled = s5m8767_reg_is_enabled, | ||
466 | .enable = s5m8767_reg_enable, | ||
467 | .disable = s5m8767_reg_disable, | ||
468 | .get_voltage_sel = s5m8767_get_voltage_sel, | ||
469 | .set_voltage = s5m8767_set_voltage_buck, | ||
470 | .set_voltage_time_sel = s5m8767_set_voltage_time_sel, | ||
471 | }; | ||
472 | |||
473 | #define regulator_desc_ldo(num) { \ | ||
474 | .name = "LDO"#num, \ | ||
475 | .id = S5M8767_LDO##num, \ | ||
476 | .ops = &s5m8767_ldo_ops, \ | ||
477 | .type = REGULATOR_VOLTAGE, \ | ||
478 | .owner = THIS_MODULE, \ | ||
479 | } | ||
480 | #define regulator_desc_buck(num) { \ | ||
481 | .name = "BUCK"#num, \ | ||
482 | .id = S5M8767_BUCK##num, \ | ||
483 | .ops = &s5m8767_buck_ops, \ | ||
484 | .type = REGULATOR_VOLTAGE, \ | ||
485 | .owner = THIS_MODULE, \ | ||
486 | } | ||
487 | |||
488 | static struct regulator_desc regulators[] = { | ||
489 | regulator_desc_ldo(1), | ||
490 | regulator_desc_ldo(2), | ||
491 | regulator_desc_ldo(3), | ||
492 | regulator_desc_ldo(4), | ||
493 | regulator_desc_ldo(5), | ||
494 | regulator_desc_ldo(6), | ||
495 | regulator_desc_ldo(7), | ||
496 | regulator_desc_ldo(8), | ||
497 | regulator_desc_ldo(9), | ||
498 | regulator_desc_ldo(10), | ||
499 | regulator_desc_ldo(11), | ||
500 | regulator_desc_ldo(12), | ||
501 | regulator_desc_ldo(13), | ||
502 | regulator_desc_ldo(14), | ||
503 | regulator_desc_ldo(15), | ||
504 | regulator_desc_ldo(16), | ||
505 | regulator_desc_ldo(17), | ||
506 | regulator_desc_ldo(18), | ||
507 | regulator_desc_ldo(19), | ||
508 | regulator_desc_ldo(20), | ||
509 | regulator_desc_ldo(21), | ||
510 | regulator_desc_ldo(22), | ||
511 | regulator_desc_ldo(23), | ||
512 | regulator_desc_ldo(24), | ||
513 | regulator_desc_ldo(25), | ||
514 | regulator_desc_ldo(26), | ||
515 | regulator_desc_ldo(27), | ||
516 | regulator_desc_ldo(28), | ||
517 | regulator_desc_buck(1), | ||
518 | regulator_desc_buck(2), | ||
519 | regulator_desc_buck(3), | ||
520 | regulator_desc_buck(4), | ||
521 | regulator_desc_buck(5), | ||
522 | regulator_desc_buck(6), | ||
523 | regulator_desc_buck(7), | ||
524 | regulator_desc_buck(8), | ||
525 | regulator_desc_buck(9), | ||
526 | }; | ||
527 | |||
528 | static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) | ||
529 | { | ||
530 | struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
531 | struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
532 | struct regulator_dev **rdev; | ||
533 | struct s5m8767_info *s5m8767; | ||
534 | int i, ret, size; | ||
535 | |||
536 | if (!pdata) { | ||
537 | dev_err(pdev->dev.parent, "Platform data not supplied\n"); | ||
538 | return -ENODEV; | ||
539 | } | ||
540 | |||
541 | if (pdata->buck2_gpiodvs) { | ||
542 | if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) { | ||
543 | dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); | ||
544 | return -EINVAL; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | if (pdata->buck3_gpiodvs) { | ||
549 | if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) { | ||
550 | dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); | ||
551 | return -EINVAL; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | if (pdata->buck4_gpiodvs) { | ||
556 | if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) { | ||
557 | dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | } | ||
561 | |||
562 | s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info), | ||
563 | GFP_KERNEL); | ||
564 | if (!s5m8767) | ||
565 | return -ENOMEM; | ||
566 | |||
567 | size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); | ||
568 | s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
569 | if (!s5m8767->rdev) | ||
570 | return -ENOMEM; | ||
571 | |||
572 | rdev = s5m8767->rdev; | ||
573 | s5m8767->dev = &pdev->dev; | ||
574 | s5m8767->iodev = iodev; | ||
575 | s5m8767->num_regulators = S5M8767_REG_MAX - 2; | ||
576 | platform_set_drvdata(pdev, s5m8767); | ||
577 | |||
578 | s5m8767->buck_gpioindex = pdata->buck_default_idx; | ||
579 | s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs; | ||
580 | s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs; | ||
581 | s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs; | ||
582 | s5m8767->buck_gpios[0] = pdata->buck_gpios[0]; | ||
583 | s5m8767->buck_gpios[1] = pdata->buck_gpios[1]; | ||
584 | s5m8767->buck_gpios[2] = pdata->buck_gpios[2]; | ||
585 | s5m8767->ramp_delay = pdata->buck_ramp_delay; | ||
586 | s5m8767->buck2_ramp = pdata->buck2_ramp_enable; | ||
587 | s5m8767->buck3_ramp = pdata->buck3_ramp_enable; | ||
588 | s5m8767->buck4_ramp = pdata->buck4_ramp_enable; | ||
589 | |||
590 | for (i = 0; i < 8; i++) { | ||
591 | if (s5m8767->buck2_gpiodvs) { | ||
592 | s5m8767->buck2_vol[i] = | ||
593 | s5m8767_convert_voltage_to_sel( | ||
594 | &buck_voltage_val2, | ||
595 | pdata->buck2_voltage[i], | ||
596 | pdata->buck2_voltage[i] + | ||
597 | buck_voltage_val2.step); | ||
598 | } | ||
599 | |||
600 | if (s5m8767->buck3_gpiodvs) { | ||
601 | s5m8767->buck3_vol[i] = | ||
602 | s5m8767_convert_voltage_to_sel( | ||
603 | &buck_voltage_val2, | ||
604 | pdata->buck3_voltage[i], | ||
605 | pdata->buck3_voltage[i] + | ||
606 | buck_voltage_val2.step); | ||
607 | } | ||
608 | |||
609 | if (s5m8767->buck4_gpiodvs) { | ||
610 | s5m8767->buck4_vol[i] = | ||
611 | s5m8767_convert_voltage_to_sel( | ||
612 | &buck_voltage_val2, | ||
613 | pdata->buck4_voltage[i], | ||
614 | pdata->buck4_voltage[i] + | ||
615 | buck_voltage_val2.step); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || | ||
620 | pdata->buck4_gpiodvs) { | ||
621 | if (gpio_is_valid(pdata->buck_gpios[0]) && | ||
622 | gpio_is_valid(pdata->buck_gpios[1]) && | ||
623 | gpio_is_valid(pdata->buck_gpios[2])) { | ||
624 | ret = gpio_request(pdata->buck_gpios[0], | ||
625 | "S5M8767 SET1"); | ||
626 | if (ret == -EBUSY) | ||
627 | dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n"); | ||
628 | |||
629 | ret = gpio_request(pdata->buck_gpios[1], | ||
630 | "S5M8767 SET2"); | ||
631 | if (ret == -EBUSY) | ||
632 | dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n"); | ||
633 | |||
634 | ret = gpio_request(pdata->buck_gpios[2], | ||
635 | "S5M8767 SET3"); | ||
636 | if (ret == -EBUSY) | ||
637 | dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n"); | ||
638 | /* SET1 GPIO */ | ||
639 | gpio_direction_output(pdata->buck_gpios[0], | ||
640 | (s5m8767->buck_gpioindex >> 2) & 0x1); | ||
641 | /* SET2 GPIO */ | ||
642 | gpio_direction_output(pdata->buck_gpios[1], | ||
643 | (s5m8767->buck_gpioindex >> 1) & 0x1); | ||
644 | /* SET3 GPIO */ | ||
645 | gpio_direction_output(pdata->buck_gpios[2], | ||
646 | (s5m8767->buck_gpioindex >> 0) & 0x1); | ||
647 | ret = 0; | ||
648 | } else { | ||
649 | dev_err(&pdev->dev, "GPIO NOT VALID\n"); | ||
650 | ret = -EINVAL; | ||
651 | return ret; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, | ||
656 | (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); | ||
657 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, | ||
658 | (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); | ||
659 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, | ||
660 | (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); | ||
661 | |||
662 | /* Initialize GPIO DVS registers */ | ||
663 | for (i = 0; i < 8; i++) { | ||
664 | if (s5m8767->buck2_gpiodvs) { | ||
665 | s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i, | ||
666 | s5m8767->buck2_vol[i]); | ||
667 | } | ||
668 | |||
669 | if (s5m8767->buck3_gpiodvs) { | ||
670 | s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i, | ||
671 | s5m8767->buck3_vol[i]); | ||
672 | } | ||
673 | |||
674 | if (s5m8767->buck4_gpiodvs) { | ||
675 | s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i, | ||
676 | s5m8767->buck4_vol[i]); | ||
677 | } | ||
678 | } | ||
679 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff); | ||
680 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff); | ||
681 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff); | ||
682 | |||
683 | if (s5m8767->buck2_ramp) | ||
684 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); | ||
685 | |||
686 | if (s5m8767->buck3_ramp) | ||
687 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04); | ||
688 | |||
689 | if (s5m8767->buck4_ramp) | ||
690 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02); | ||
691 | |||
692 | if (s5m8767->buck2_ramp || s5m8767->buck3_ramp | ||
693 | || s5m8767->buck4_ramp) { | ||
694 | switch (s5m8767->ramp_delay) { | ||
695 | case 15: | ||
696 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, | ||
697 | 0xc0, 0xf0); | ||
698 | break; | ||
699 | case 25: | ||
700 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, | ||
701 | 0xd0, 0xf0); | ||
702 | break; | ||
703 | case 50: | ||
704 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, | ||
705 | 0xe0, 0xf0); | ||
706 | break; | ||
707 | case 100: | ||
708 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, | ||
709 | 0xf0, 0xf0); | ||
710 | break; | ||
711 | default: | ||
712 | s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, | ||
713 | 0x90, 0xf0); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | for (i = 0; i < pdata->num_regulators; i++) { | ||
718 | const struct s5m_voltage_desc *desc; | ||
719 | int id = pdata->regulators[i].id; | ||
720 | |||
721 | desc = reg_voltage_map[id]; | ||
722 | if (desc) | ||
723 | regulators[id].n_voltages = | ||
724 | (desc->max - desc->min) / desc->step + 1; | ||
725 | |||
726 | rdev[i] = regulator_register(®ulators[id], s5m8767->dev, | ||
727 | pdata->regulators[i].initdata, s5m8767, NULL); | ||
728 | if (IS_ERR(rdev[i])) { | ||
729 | ret = PTR_ERR(rdev[i]); | ||
730 | dev_err(s5m8767->dev, "regulator init failed for %d\n", | ||
731 | id); | ||
732 | rdev[i] = NULL; | ||
733 | goto err; | ||
734 | } | ||
735 | } | ||
736 | |||
737 | return 0; | ||
738 | err: | ||
739 | for (i = 0; i < s5m8767->num_regulators; i++) | ||
740 | if (rdev[i]) | ||
741 | regulator_unregister(rdev[i]); | ||
742 | |||
743 | return ret; | ||
744 | } | ||
745 | |||
746 | static int __devexit s5m8767_pmic_remove(struct platform_device *pdev) | ||
747 | { | ||
748 | struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev); | ||
749 | struct regulator_dev **rdev = s5m8767->rdev; | ||
750 | int i; | ||
751 | |||
752 | for (i = 0; i < s5m8767->num_regulators; i++) | ||
753 | if (rdev[i]) | ||
754 | regulator_unregister(rdev[i]); | ||
755 | |||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static const struct platform_device_id s5m8767_pmic_id[] = { | ||
760 | { "s5m8767-pmic", 0}, | ||
761 | { }, | ||
762 | }; | ||
763 | MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id); | ||
764 | |||
765 | static struct platform_driver s5m8767_pmic_driver = { | ||
766 | .driver = { | ||
767 | .name = "s5m8767-pmic", | ||
768 | .owner = THIS_MODULE, | ||
769 | }, | ||
770 | .probe = s5m8767_pmic_probe, | ||
771 | .remove = __devexit_p(s5m8767_pmic_remove), | ||
772 | .id_table = s5m8767_pmic_id, | ||
773 | }; | ||
774 | |||
775 | static int __init s5m8767_pmic_init(void) | ||
776 | { | ||
777 | return platform_driver_register(&s5m8767_pmic_driver); | ||
778 | } | ||
779 | subsys_initcall(s5m8767_pmic_init); | ||
780 | |||
781 | static void __exit s5m8767_pmic_exit(void) | ||
782 | { | ||
783 | platform_driver_unregister(&s5m8767_pmic_driver); | ||
784 | } | ||
785 | module_exit(s5m8767_pmic_exit); | ||
786 | |||
787 | /* Module information */ | ||
788 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | ||
789 | MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver"); | ||
790 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c new file mode 100644 index 000000000000..e2ec73068ee2 --- /dev/null +++ b/drivers/regulator/tps62360-regulator.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * tps62360.c -- TI tps62360 | ||
3 | * | ||
4 | * Driver for processor core supply tps62360 and tps62361B | ||
5 | * | ||
6 | * Copyright (c) 2012, NVIDIA Corporation. | ||
7 | * | ||
8 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation version 2. | ||
13 | * | ||
14 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
15 | * whether express or implied; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
22 | * 02111-1307, USA | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/regulator/driver.h> | ||
31 | #include <linux/regulator/machine.h> | ||
32 | #include <linux/regulator/tps62360.h> | ||
33 | #include <linux/gpio.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/regmap.h> | ||
38 | |||
39 | /* Register definitions */ | ||
40 | #define REG_VSET0 0 | ||
41 | #define REG_VSET1 1 | ||
42 | #define REG_VSET2 2 | ||
43 | #define REG_VSET3 3 | ||
44 | #define REG_CONTROL 4 | ||
45 | #define REG_TEMP 5 | ||
46 | #define REG_RAMPCTRL 6 | ||
47 | #define REG_CHIPID 8 | ||
48 | |||
49 | enum chips {TPS62360, TPS62361}; | ||
50 | |||
51 | #define TPS62360_BASE_VOLTAGE 770 | ||
52 | #define TPS62360_N_VOLTAGES 64 | ||
53 | |||
54 | #define TPS62361_BASE_VOLTAGE 500 | ||
55 | #define TPS62361_N_VOLTAGES 128 | ||
56 | |||
57 | /* tps 62360 chip information */ | ||
58 | struct tps62360_chip { | ||
59 | const char *name; | ||
60 | struct device *dev; | ||
61 | struct regulator_desc desc; | ||
62 | struct i2c_client *client; | ||
63 | struct regulator_dev *rdev; | ||
64 | struct regmap *regmap; | ||
65 | int chip_id; | ||
66 | int vsel0_gpio; | ||
67 | int vsel1_gpio; | ||
68 | int voltage_base; | ||
69 | u8 voltage_reg_mask; | ||
70 | bool en_internal_pulldn; | ||
71 | bool en_force_pwm; | ||
72 | bool en_discharge; | ||
73 | bool valid_gpios; | ||
74 | int lru_index[4]; | ||
75 | int curr_vset_vsel[4]; | ||
76 | int curr_vset_id; | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * find_voltage_set_register: Find new voltage configuration register | ||
81 | * (VSET) id. | ||
82 | * The finding of the new VSET register will be based on the LRU mechanism. | ||
83 | * Each VSET register will have different voltage configured . This | ||
84 | * Function will look if any of the VSET register have requested voltage set | ||
85 | * or not. | ||
86 | * - If it is already there then it will make that register as most | ||
87 | * recently used and return as found so that caller need not to set | ||
88 | * the VSET register but need to set the proper gpios to select this | ||
89 | * VSET register. | ||
90 | * - If requested voltage is not found then it will use the least | ||
91 | * recently mechanism to get new VSET register for new configuration | ||
92 | * and will return not_found so that caller need to set new VSET | ||
93 | * register and then gpios (both). | ||
94 | */ | ||
95 | static bool find_voltage_set_register(struct tps62360_chip *tps, | ||
96 | int req_vsel, int *vset_reg_id) | ||
97 | { | ||
98 | int i; | ||
99 | bool found = false; | ||
100 | int new_vset_reg = tps->lru_index[3]; | ||
101 | int found_index = 3; | ||
102 | for (i = 0; i < 4; ++i) { | ||
103 | if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { | ||
104 | new_vset_reg = tps->lru_index[i]; | ||
105 | found_index = i; | ||
106 | found = true; | ||
107 | goto update_lru_index; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | update_lru_index: | ||
112 | for (i = found_index; i > 0; i--) | ||
113 | tps->lru_index[i] = tps->lru_index[i - 1]; | ||
114 | |||
115 | tps->lru_index[0] = new_vset_reg; | ||
116 | *vset_reg_id = new_vset_reg; | ||
117 | return found; | ||
118 | } | ||
119 | |||
120 | static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) | ||
121 | { | ||
122 | struct tps62360_chip *tps = rdev_get_drvdata(dev); | ||
123 | int vsel; | ||
124 | unsigned int data; | ||
125 | int ret; | ||
126 | |||
127 | ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); | ||
128 | if (ret < 0) { | ||
129 | dev_err(tps->dev, "%s: Error in reading register %d\n", | ||
130 | __func__, REG_VSET0 + tps->curr_vset_id); | ||
131 | return ret; | ||
132 | } | ||
133 | vsel = (int)data & tps->voltage_reg_mask; | ||
134 | return (tps->voltage_base + vsel * 10) * 1000; | ||
135 | } | ||
136 | |||
137 | static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, | ||
138 | int min_uV, int max_uV, unsigned *selector) | ||
139 | { | ||
140 | struct tps62360_chip *tps = rdev_get_drvdata(dev); | ||
141 | int vsel; | ||
142 | int ret; | ||
143 | bool found = false; | ||
144 | int new_vset_id = tps->curr_vset_id; | ||
145 | |||
146 | if (max_uV < min_uV) | ||
147 | return -EINVAL; | ||
148 | |||
149 | if (min_uV > | ||
150 | ((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000)) | ||
151 | return -EINVAL; | ||
152 | |||
153 | if (max_uV < tps->voltage_base * 1000) | ||
154 | return -EINVAL; | ||
155 | |||
156 | vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000); | ||
157 | if (selector) | ||
158 | *selector = (vsel & tps->voltage_reg_mask); | ||
159 | |||
160 | /* | ||
161 | * If gpios are available to select the VSET register then least | ||
162 | * recently used register for new configuration. | ||
163 | */ | ||
164 | if (tps->valid_gpios) | ||
165 | found = find_voltage_set_register(tps, vsel, &new_vset_id); | ||
166 | |||
167 | if (!found) { | ||
168 | ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, | ||
169 | tps->voltage_reg_mask, vsel); | ||
170 | if (ret < 0) { | ||
171 | dev_err(tps->dev, "%s: Error in updating register %d\n", | ||
172 | __func__, REG_VSET0 + new_vset_id); | ||
173 | return ret; | ||
174 | } | ||
175 | tps->curr_vset_id = new_vset_id; | ||
176 | tps->curr_vset_vsel[new_vset_id] = vsel; | ||
177 | } | ||
178 | |||
179 | /* Select proper VSET register vio gpios */ | ||
180 | if (tps->valid_gpios) { | ||
181 | gpio_set_value_cansleep(tps->vsel0_gpio, | ||
182 | new_vset_id & 0x1); | ||
183 | gpio_set_value_cansleep(tps->vsel1_gpio, | ||
184 | (new_vset_id >> 1) & 0x1); | ||
185 | } | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, | ||
190 | unsigned selector) | ||
191 | { | ||
192 | struct tps62360_chip *tps = rdev_get_drvdata(dev); | ||
193 | |||
194 | if (selector >= tps->desc.n_voltages) | ||
195 | return -EINVAL; | ||
196 | return (tps->voltage_base + selector * 10) * 1000; | ||
197 | } | ||
198 | |||
199 | static struct regulator_ops tps62360_dcdc_ops = { | ||
200 | .get_voltage = tps62360_dcdc_get_voltage, | ||
201 | .set_voltage = tps62360_dcdc_set_voltage, | ||
202 | .list_voltage = tps62360_dcdc_list_voltage, | ||
203 | }; | ||
204 | |||
205 | static int tps62360_init_force_pwm(struct tps62360_chip *tps, | ||
206 | struct tps62360_regulator_platform_data *pdata, | ||
207 | int vset_id) | ||
208 | { | ||
209 | unsigned int data; | ||
210 | int ret; | ||
211 | ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); | ||
212 | if (ret < 0) { | ||
213 | dev_err(tps->dev, "%s() fails in writing reg %d\n", | ||
214 | __func__, REG_VSET0 + vset_id); | ||
215 | return ret; | ||
216 | } | ||
217 | tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask; | ||
218 | if (pdata->en_force_pwm) | ||
219 | data |= BIT(7); | ||
220 | else | ||
221 | data &= ~BIT(7); | ||
222 | ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data); | ||
223 | if (ret < 0) | ||
224 | dev_err(tps->dev, "%s() fails in writing reg %d\n", | ||
225 | __func__, REG_VSET0 + vset_id); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static int tps62360_init_dcdc(struct tps62360_chip *tps, | ||
230 | struct tps62360_regulator_platform_data *pdata) | ||
231 | { | ||
232 | int ret; | ||
233 | int i; | ||
234 | |||
235 | /* Initailize internal pull up/down control */ | ||
236 | if (tps->en_internal_pulldn) | ||
237 | ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); | ||
238 | else | ||
239 | ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); | ||
240 | if (ret < 0) { | ||
241 | dev_err(tps->dev, "%s() fails in writing reg %d\n", | ||
242 | __func__, REG_CONTROL); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | /* Initailize force PWM mode */ | ||
247 | if (tps->valid_gpios) { | ||
248 | for (i = 0; i < 4; ++i) { | ||
249 | ret = tps62360_init_force_pwm(tps, pdata, i); | ||
250 | if (ret < 0) | ||
251 | return ret; | ||
252 | } | ||
253 | } else { | ||
254 | ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); | ||
255 | if (ret < 0) | ||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | /* Reset output discharge path to reduce power consumption */ | ||
260 | ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); | ||
261 | if (ret < 0) | ||
262 | dev_err(tps->dev, "%s() fails in updating reg %d\n", | ||
263 | __func__, REG_RAMPCTRL); | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | static const struct regmap_config tps62360_regmap_config = { | ||
268 | .reg_bits = 8, | ||
269 | .val_bits = 8, | ||
270 | }; | ||
271 | |||
272 | static int __devinit tps62360_probe(struct i2c_client *client, | ||
273 | const struct i2c_device_id *id) | ||
274 | { | ||
275 | struct tps62360_regulator_platform_data *pdata; | ||
276 | struct regulator_dev *rdev; | ||
277 | struct tps62360_chip *tps; | ||
278 | int ret; | ||
279 | int i; | ||
280 | |||
281 | pdata = client->dev.platform_data; | ||
282 | if (!pdata) { | ||
283 | dev_err(&client->dev, "%s() Err: Platform data not found\n", | ||
284 | __func__); | ||
285 | return -EIO; | ||
286 | } | ||
287 | |||
288 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
289 | if (!tps) { | ||
290 | dev_err(&client->dev, "%s() Err: Memory allocation fails\n", | ||
291 | __func__); | ||
292 | return -ENOMEM; | ||
293 | } | ||
294 | |||
295 | tps->en_force_pwm = pdata->en_force_pwm; | ||
296 | tps->en_discharge = pdata->en_discharge; | ||
297 | tps->en_internal_pulldn = pdata->en_internal_pulldn; | ||
298 | tps->vsel0_gpio = pdata->vsel0_gpio; | ||
299 | tps->vsel1_gpio = pdata->vsel1_gpio; | ||
300 | tps->client = client; | ||
301 | tps->dev = &client->dev; | ||
302 | tps->name = id->name; | ||
303 | tps->voltage_base = (id->driver_data == TPS62360) ? | ||
304 | TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE; | ||
305 | tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F; | ||
306 | |||
307 | tps->desc.name = id->name; | ||
308 | tps->desc.id = 0; | ||
309 | tps->desc.n_voltages = (id->driver_data == TPS62360) ? | ||
310 | TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES; | ||
311 | tps->desc.ops = &tps62360_dcdc_ops; | ||
312 | tps->desc.type = REGULATOR_VOLTAGE; | ||
313 | tps->desc.owner = THIS_MODULE; | ||
314 | tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config); | ||
315 | if (IS_ERR(tps->regmap)) { | ||
316 | ret = PTR_ERR(tps->regmap); | ||
317 | dev_err(&client->dev, "%s() Err: Failed to allocate register" | ||
318 | "map: %d\n", __func__, ret); | ||
319 | return ret; | ||
320 | } | ||
321 | i2c_set_clientdata(client, tps); | ||
322 | |||
323 | tps->curr_vset_id = (pdata->vsel1_def_state & 1) * 2 + | ||
324 | (pdata->vsel0_def_state & 1); | ||
325 | tps->lru_index[0] = tps->curr_vset_id; | ||
326 | tps->valid_gpios = false; | ||
327 | |||
328 | if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { | ||
329 | ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); | ||
330 | if (ret) { | ||
331 | dev_err(&client->dev, | ||
332 | "Err: Could not obtain vsel0 GPIO %d: %d\n", | ||
333 | tps->vsel0_gpio, ret); | ||
334 | goto err_gpio0; | ||
335 | } | ||
336 | ret = gpio_direction_output(tps->vsel0_gpio, | ||
337 | pdata->vsel0_def_state); | ||
338 | if (ret) { | ||
339 | dev_err(&client->dev, "Err: Could not set direction of" | ||
340 | "vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret); | ||
341 | gpio_free(tps->vsel0_gpio); | ||
342 | goto err_gpio0; | ||
343 | } | ||
344 | |||
345 | ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); | ||
346 | if (ret) { | ||
347 | dev_err(&client->dev, | ||
348 | "Err: Could not obtain vsel1 GPIO %d: %d\n", | ||
349 | tps->vsel1_gpio, ret); | ||
350 | goto err_gpio1; | ||
351 | } | ||
352 | ret = gpio_direction_output(tps->vsel1_gpio, | ||
353 | pdata->vsel1_def_state); | ||
354 | if (ret) { | ||
355 | dev_err(&client->dev, "Err: Could not set direction of" | ||
356 | "vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret); | ||
357 | gpio_free(tps->vsel1_gpio); | ||
358 | goto err_gpio1; | ||
359 | } | ||
360 | tps->valid_gpios = true; | ||
361 | |||
362 | /* | ||
363 | * Initialize the lru index with vset_reg id | ||
364 | * The index 0 will be most recently used and | ||
365 | * set with the tps->curr_vset_id */ | ||
366 | for (i = 0; i < 4; ++i) | ||
367 | tps->lru_index[i] = i; | ||
368 | tps->lru_index[0] = tps->curr_vset_id; | ||
369 | tps->lru_index[tps->curr_vset_id] = 0; | ||
370 | } | ||
371 | |||
372 | ret = tps62360_init_dcdc(tps, pdata); | ||
373 | if (ret < 0) { | ||
374 | dev_err(tps->dev, "%s() Err: Init fails with = %d\n", | ||
375 | __func__, ret); | ||
376 | goto err_init; | ||
377 | } | ||
378 | |||
379 | /* Register the regulators */ | ||
380 | rdev = regulator_register(&tps->desc, &client->dev, | ||
381 | &pdata->reg_init_data, tps, NULL); | ||
382 | if (IS_ERR(rdev)) { | ||
383 | dev_err(tps->dev, "%s() Err: Failed to register %s\n", | ||
384 | __func__, id->name); | ||
385 | ret = PTR_ERR(rdev); | ||
386 | goto err_init; | ||
387 | } | ||
388 | |||
389 | tps->rdev = rdev; | ||
390 | return 0; | ||
391 | |||
392 | err_init: | ||
393 | if (gpio_is_valid(tps->vsel1_gpio)) | ||
394 | gpio_free(tps->vsel1_gpio); | ||
395 | err_gpio1: | ||
396 | if (gpio_is_valid(tps->vsel0_gpio)) | ||
397 | gpio_free(tps->vsel0_gpio); | ||
398 | err_gpio0: | ||
399 | regmap_exit(tps->regmap); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * tps62360_remove - tps62360 driver i2c remove handler | ||
405 | * @client: i2c driver client device structure | ||
406 | * | ||
407 | * Unregister TPS driver as an i2c client device driver | ||
408 | */ | ||
409 | static int __devexit tps62360_remove(struct i2c_client *client) | ||
410 | { | ||
411 | struct tps62360_chip *tps = i2c_get_clientdata(client); | ||
412 | |||
413 | if (gpio_is_valid(tps->vsel1_gpio)) | ||
414 | gpio_free(tps->vsel1_gpio); | ||
415 | |||
416 | if (gpio_is_valid(tps->vsel0_gpio)) | ||
417 | gpio_free(tps->vsel0_gpio); | ||
418 | |||
419 | regulator_unregister(tps->rdev); | ||
420 | regmap_exit(tps->regmap); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static void tps62360_shutdown(struct i2c_client *client) | ||
425 | { | ||
426 | struct tps62360_chip *tps = i2c_get_clientdata(client); | ||
427 | int st; | ||
428 | |||
429 | if (!tps->en_discharge) | ||
430 | return; | ||
431 | |||
432 | /* Configure the output discharge path */ | ||
433 | st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); | ||
434 | if (st < 0) | ||
435 | dev_err(tps->dev, "%s() fails in updating reg %d\n", | ||
436 | __func__, REG_RAMPCTRL); | ||
437 | } | ||
438 | |||
439 | static const struct i2c_device_id tps62360_id[] = { | ||
440 | {.name = "tps62360", .driver_data = TPS62360}, | ||
441 | {.name = "tps62361", .driver_data = TPS62361}, | ||
442 | {}, | ||
443 | }; | ||
444 | |||
445 | MODULE_DEVICE_TABLE(i2c, tps62360_id); | ||
446 | |||
447 | static struct i2c_driver tps62360_i2c_driver = { | ||
448 | .driver = { | ||
449 | .name = "tps62360", | ||
450 | .owner = THIS_MODULE, | ||
451 | }, | ||
452 | .probe = tps62360_probe, | ||
453 | .remove = __devexit_p(tps62360_remove), | ||
454 | .shutdown = tps62360_shutdown, | ||
455 | .id_table = tps62360_id, | ||
456 | }; | ||
457 | |||
458 | static int __init tps62360_init(void) | ||
459 | { | ||
460 | return i2c_add_driver(&tps62360_i2c_driver); | ||
461 | } | ||
462 | subsys_initcall(tps62360_init); | ||
463 | |||
464 | static void __exit tps62360_cleanup(void) | ||
465 | { | ||
466 | i2c_del_driver(&tps62360_i2c_driver); | ||
467 | } | ||
468 | module_exit(tps62360_cleanup); | ||
469 | |||
470 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
471 | MODULE_DESCRIPTION("TPS62360 voltage regulator driver"); | ||
472 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 18d61a0529a9..43e4902d7af8 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -491,10 +491,6 @@ static int __devinit tps_65023_probe(struct i2c_client *client, | |||
491 | regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, | 491 | regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, |
492 | TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ); | 492 | TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ); |
493 | 493 | ||
494 | /* Enable setting output voltage by I2C */ | ||
495 | regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, | ||
496 | TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ); | ||
497 | |||
498 | return 0; | 494 | return 0; |
499 | 495 | ||
500 | fail: | 496 | fail: |
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 0b63ef71a5fe..832833fe8aad 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -238,16 +238,16 @@ static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) | |||
238 | return err; | 238 | return err; |
239 | } | 239 | } |
240 | 240 | ||
241 | static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) | 241 | static int tps6507x_pmic_is_enabled(struct regulator_dev *dev) |
242 | { | 242 | { |
243 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 243 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
244 | int data, dcdc = rdev_get_id(dev); | 244 | int data, rid = rdev_get_id(dev); |
245 | u8 shift; | 245 | u8 shift; |
246 | 246 | ||
247 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | 247 | if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) |
248 | return -EINVAL; | 248 | return -EINVAL; |
249 | 249 | ||
250 | shift = TPS6507X_MAX_REG_ID - dcdc; | 250 | shift = TPS6507X_MAX_REG_ID - rid; |
251 | data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); | 251 | data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); |
252 | 252 | ||
253 | if (data < 0) | 253 | if (data < 0) |
@@ -256,99 +256,65 @@ static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) | |||
256 | return (data & 1<<shift) ? 1 : 0; | 256 | return (data & 1<<shift) ? 1 : 0; |
257 | } | 257 | } |
258 | 258 | ||
259 | static int tps6507x_pmic_ldo_is_enabled(struct regulator_dev *dev) | 259 | static int tps6507x_pmic_enable(struct regulator_dev *dev) |
260 | { | 260 | { |
261 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 261 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
262 | int data, ldo = rdev_get_id(dev); | 262 | int rid = rdev_get_id(dev); |
263 | u8 shift; | 263 | u8 shift; |
264 | 264 | ||
265 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | 265 | if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) |
266 | return -EINVAL; | 266 | return -EINVAL; |
267 | 267 | ||
268 | shift = TPS6507X_MAX_REG_ID - ldo; | 268 | shift = TPS6507X_MAX_REG_ID - rid; |
269 | data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); | ||
270 | |||
271 | if (data < 0) | ||
272 | return data; | ||
273 | else | ||
274 | return (data & 1<<shift) ? 1 : 0; | ||
275 | } | ||
276 | |||
277 | static int tps6507x_pmic_dcdc_enable(struct regulator_dev *dev) | ||
278 | { | ||
279 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | ||
280 | int dcdc = rdev_get_id(dev); | ||
281 | u8 shift; | ||
282 | |||
283 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
284 | return -EINVAL; | ||
285 | |||
286 | shift = TPS6507X_MAX_REG_ID - dcdc; | ||
287 | return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | ||
288 | } | ||
289 | |||
290 | static int tps6507x_pmic_dcdc_disable(struct regulator_dev *dev) | ||
291 | { | ||
292 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | ||
293 | int dcdc = rdev_get_id(dev); | ||
294 | u8 shift; | ||
295 | |||
296 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
297 | return -EINVAL; | ||
298 | |||
299 | shift = TPS6507X_MAX_REG_ID - dcdc; | ||
300 | return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, | ||
301 | 1 << shift); | ||
302 | } | ||
303 | |||
304 | static int tps6507x_pmic_ldo_enable(struct regulator_dev *dev) | ||
305 | { | ||
306 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | ||
307 | int ldo = rdev_get_id(dev); | ||
308 | u8 shift; | ||
309 | |||
310 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
311 | return -EINVAL; | ||
312 | |||
313 | shift = TPS6507X_MAX_REG_ID - ldo; | ||
314 | return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | 269 | return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); |
315 | } | 270 | } |
316 | 271 | ||
317 | static int tps6507x_pmic_ldo_disable(struct regulator_dev *dev) | 272 | static int tps6507x_pmic_disable(struct regulator_dev *dev) |
318 | { | 273 | { |
319 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 274 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
320 | int ldo = rdev_get_id(dev); | 275 | int rid = rdev_get_id(dev); |
321 | u8 shift; | 276 | u8 shift; |
322 | 277 | ||
323 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | 278 | if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) |
324 | return -EINVAL; | 279 | return -EINVAL; |
325 | 280 | ||
326 | shift = TPS6507X_MAX_REG_ID - ldo; | 281 | shift = TPS6507X_MAX_REG_ID - rid; |
327 | return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, | 282 | return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, |
328 | 1 << shift); | 283 | 1 << shift); |
329 | } | 284 | } |
330 | 285 | ||
331 | static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev) | 286 | static int tps6507x_pmic_get_voltage(struct regulator_dev *dev) |
332 | { | 287 | { |
333 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 288 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
334 | int data, dcdc = rdev_get_id(dev); | 289 | int data, rid = rdev_get_id(dev); |
335 | u8 reg; | 290 | u8 reg, mask; |
336 | 291 | ||
337 | switch (dcdc) { | 292 | switch (rid) { |
338 | case TPS6507X_DCDC_1: | 293 | case TPS6507X_DCDC_1: |
339 | reg = TPS6507X_REG_DEFDCDC1; | 294 | reg = TPS6507X_REG_DEFDCDC1; |
295 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
340 | break; | 296 | break; |
341 | case TPS6507X_DCDC_2: | 297 | case TPS6507X_DCDC_2: |
342 | if (tps->info[dcdc]->defdcdc_default) | 298 | if (tps->info[rid]->defdcdc_default) |
343 | reg = TPS6507X_REG_DEFDCDC2_HIGH; | 299 | reg = TPS6507X_REG_DEFDCDC2_HIGH; |
344 | else | 300 | else |
345 | reg = TPS6507X_REG_DEFDCDC2_LOW; | 301 | reg = TPS6507X_REG_DEFDCDC2_LOW; |
302 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
346 | break; | 303 | break; |
347 | case TPS6507X_DCDC_3: | 304 | case TPS6507X_DCDC_3: |
348 | if (tps->info[dcdc]->defdcdc_default) | 305 | if (tps->info[rid]->defdcdc_default) |
349 | reg = TPS6507X_REG_DEFDCDC3_HIGH; | 306 | reg = TPS6507X_REG_DEFDCDC3_HIGH; |
350 | else | 307 | else |
351 | reg = TPS6507X_REG_DEFDCDC3_LOW; | 308 | reg = TPS6507X_REG_DEFDCDC3_LOW; |
309 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
310 | break; | ||
311 | case TPS6507X_LDO_1: | ||
312 | reg = TPS6507X_REG_LDO_CTRL1; | ||
313 | mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK; | ||
314 | break; | ||
315 | case TPS6507X_LDO_2: | ||
316 | reg = TPS6507X_REG_DEFLDO2; | ||
317 | mask = TPS6507X_REG_DEFLDO2_LDO2_MASK; | ||
352 | break; | 318 | break; |
353 | default: | 319 | default: |
354 | return -EINVAL; | 320 | return -EINVAL; |
@@ -358,193 +324,83 @@ static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev) | |||
358 | if (data < 0) | 324 | if (data < 0) |
359 | return data; | 325 | return data; |
360 | 326 | ||
361 | data &= TPS6507X_DEFDCDCX_DCDC_MASK; | 327 | data &= mask; |
362 | return tps->info[dcdc]->table[data] * 1000; | 328 | return tps->info[rid]->table[data] * 1000; |
363 | } | 329 | } |
364 | 330 | ||
365 | static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, | 331 | static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, |
366 | int min_uV, int max_uV, | 332 | unsigned selector) |
367 | unsigned *selector) | ||
368 | { | 333 | { |
369 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 334 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
370 | int data, vsel, dcdc = rdev_get_id(dev); | 335 | int data, rid = rdev_get_id(dev); |
371 | u8 reg; | 336 | u8 reg, mask; |
372 | 337 | ||
373 | switch (dcdc) { | 338 | switch (rid) { |
374 | case TPS6507X_DCDC_1: | 339 | case TPS6507X_DCDC_1: |
375 | reg = TPS6507X_REG_DEFDCDC1; | 340 | reg = TPS6507X_REG_DEFDCDC1; |
341 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
376 | break; | 342 | break; |
377 | case TPS6507X_DCDC_2: | 343 | case TPS6507X_DCDC_2: |
378 | if (tps->info[dcdc]->defdcdc_default) | 344 | if (tps->info[rid]->defdcdc_default) |
379 | reg = TPS6507X_REG_DEFDCDC2_HIGH; | 345 | reg = TPS6507X_REG_DEFDCDC2_HIGH; |
380 | else | 346 | else |
381 | reg = TPS6507X_REG_DEFDCDC2_LOW; | 347 | reg = TPS6507X_REG_DEFDCDC2_LOW; |
348 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
382 | break; | 349 | break; |
383 | case TPS6507X_DCDC_3: | 350 | case TPS6507X_DCDC_3: |
384 | if (tps->info[dcdc]->defdcdc_default) | 351 | if (tps->info[rid]->defdcdc_default) |
385 | reg = TPS6507X_REG_DEFDCDC3_HIGH; | 352 | reg = TPS6507X_REG_DEFDCDC3_HIGH; |
386 | else | 353 | else |
387 | reg = TPS6507X_REG_DEFDCDC3_LOW; | 354 | reg = TPS6507X_REG_DEFDCDC3_LOW; |
355 | mask = TPS6507X_DEFDCDCX_DCDC_MASK; | ||
356 | break; | ||
357 | case TPS6507X_LDO_1: | ||
358 | reg = TPS6507X_REG_LDO_CTRL1; | ||
359 | mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK; | ||
360 | break; | ||
361 | case TPS6507X_LDO_2: | ||
362 | reg = TPS6507X_REG_DEFLDO2; | ||
363 | mask = TPS6507X_REG_DEFLDO2_LDO2_MASK; | ||
388 | break; | 364 | break; |
389 | default: | 365 | default: |
390 | return -EINVAL; | 366 | return -EINVAL; |
391 | } | 367 | } |
392 | 368 | ||
393 | if (min_uV < tps->info[dcdc]->min_uV | ||
394 | || min_uV > tps->info[dcdc]->max_uV) | ||
395 | return -EINVAL; | ||
396 | if (max_uV < tps->info[dcdc]->min_uV | ||
397 | || max_uV > tps->info[dcdc]->max_uV) | ||
398 | return -EINVAL; | ||
399 | |||
400 | for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { | ||
401 | int mV = tps->info[dcdc]->table[vsel]; | ||
402 | int uV = mV * 1000; | ||
403 | |||
404 | /* Break at the first in-range value */ | ||
405 | if (min_uV <= uV && uV <= max_uV) | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | /* write to the register in case we found a match */ | ||
410 | if (vsel == tps->info[dcdc]->table_len) | ||
411 | return -EINVAL; | ||
412 | |||
413 | *selector = vsel; | ||
414 | |||
415 | data = tps6507x_pmic_reg_read(tps, reg); | ||
416 | if (data < 0) | ||
417 | return data; | ||
418 | |||
419 | data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; | ||
420 | data |= vsel; | ||
421 | |||
422 | return tps6507x_pmic_reg_write(tps, reg, data); | ||
423 | } | ||
424 | |||
425 | static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev) | ||
426 | { | ||
427 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | ||
428 | int data, ldo = rdev_get_id(dev); | ||
429 | u8 reg, mask; | ||
430 | |||
431 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
432 | return -EINVAL; | ||
433 | else { | ||
434 | reg = (ldo == TPS6507X_LDO_1 ? | ||
435 | TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); | ||
436 | mask = (ldo == TPS6507X_LDO_1 ? | ||
437 | TPS6507X_REG_LDO_CTRL1_LDO1_MASK : | ||
438 | TPS6507X_REG_DEFLDO2_LDO2_MASK); | ||
439 | } | ||
440 | |||
441 | data = tps6507x_pmic_reg_read(tps, reg); | ||
442 | if (data < 0) | ||
443 | return data; | ||
444 | |||
445 | data &= mask; | ||
446 | return tps->info[ldo]->table[data] * 1000; | ||
447 | } | ||
448 | |||
449 | static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, | ||
450 | int min_uV, int max_uV, | ||
451 | unsigned *selector) | ||
452 | { | ||
453 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | ||
454 | int data, vsel, ldo = rdev_get_id(dev); | ||
455 | u8 reg, mask; | ||
456 | |||
457 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
458 | return -EINVAL; | ||
459 | else { | ||
460 | reg = (ldo == TPS6507X_LDO_1 ? | ||
461 | TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); | ||
462 | mask = (ldo == TPS6507X_LDO_1 ? | ||
463 | TPS6507X_REG_LDO_CTRL1_LDO1_MASK : | ||
464 | TPS6507X_REG_DEFLDO2_LDO2_MASK); | ||
465 | } | ||
466 | |||
467 | if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) | ||
468 | return -EINVAL; | ||
469 | if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) | ||
470 | return -EINVAL; | ||
471 | |||
472 | for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { | ||
473 | int mV = tps->info[ldo]->table[vsel]; | ||
474 | int uV = mV * 1000; | ||
475 | |||
476 | /* Break at the first in-range value */ | ||
477 | if (min_uV <= uV && uV <= max_uV) | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | if (vsel == tps->info[ldo]->table_len) | ||
482 | return -EINVAL; | ||
483 | |||
484 | *selector = vsel; | ||
485 | |||
486 | data = tps6507x_pmic_reg_read(tps, reg); | 369 | data = tps6507x_pmic_reg_read(tps, reg); |
487 | if (data < 0) | 370 | if (data < 0) |
488 | return data; | 371 | return data; |
489 | 372 | ||
490 | data &= ~mask; | 373 | data &= ~mask; |
491 | data |= vsel; | 374 | data |= selector; |
492 | 375 | ||
493 | return tps6507x_pmic_reg_write(tps, reg, data); | 376 | return tps6507x_pmic_reg_write(tps, reg, data); |
494 | } | 377 | } |
495 | 378 | ||
496 | static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev, | 379 | static int tps6507x_pmic_list_voltage(struct regulator_dev *dev, |
497 | unsigned selector) | 380 | unsigned selector) |
498 | { | 381 | { |
499 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 382 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); |
500 | int dcdc = rdev_get_id(dev); | 383 | int rid = rdev_get_id(dev); |
501 | 384 | ||
502 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | 385 | if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2) |
503 | return -EINVAL; | 386 | return -EINVAL; |
504 | 387 | ||
505 | if (selector >= tps->info[dcdc]->table_len) | 388 | if (selector >= tps->info[rid]->table_len) |
506 | return -EINVAL; | 389 | return -EINVAL; |
507 | else | 390 | else |
508 | return tps->info[dcdc]->table[selector] * 1000; | 391 | return tps->info[rid]->table[selector] * 1000; |
509 | } | 392 | } |
510 | 393 | ||
511 | static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev, | 394 | static struct regulator_ops tps6507x_pmic_ops = { |
512 | unsigned selector) | 395 | .is_enabled = tps6507x_pmic_is_enabled, |
513 | { | 396 | .enable = tps6507x_pmic_enable, |
514 | struct tps6507x_pmic *tps = rdev_get_drvdata(dev); | 397 | .disable = tps6507x_pmic_disable, |
515 | int ldo = rdev_get_id(dev); | 398 | .get_voltage = tps6507x_pmic_get_voltage, |
516 | 399 | .set_voltage_sel = tps6507x_pmic_set_voltage_sel, | |
517 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | 400 | .list_voltage = tps6507x_pmic_list_voltage, |
518 | return -EINVAL; | ||
519 | |||
520 | if (selector >= tps->info[ldo]->table_len) | ||
521 | return -EINVAL; | ||
522 | else | ||
523 | return tps->info[ldo]->table[selector] * 1000; | ||
524 | } | ||
525 | |||
526 | /* Operations permitted on VDCDCx */ | ||
527 | static struct regulator_ops tps6507x_pmic_dcdc_ops = { | ||
528 | .is_enabled = tps6507x_pmic_dcdc_is_enabled, | ||
529 | .enable = tps6507x_pmic_dcdc_enable, | ||
530 | .disable = tps6507x_pmic_dcdc_disable, | ||
531 | .get_voltage = tps6507x_pmic_dcdc_get_voltage, | ||
532 | .set_voltage = tps6507x_pmic_dcdc_set_voltage, | ||
533 | .list_voltage = tps6507x_pmic_dcdc_list_voltage, | ||
534 | }; | 401 | }; |
535 | 402 | ||
536 | /* Operations permitted on LDOx */ | 403 | static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) |
537 | static struct regulator_ops tps6507x_pmic_ldo_ops = { | ||
538 | .is_enabled = tps6507x_pmic_ldo_is_enabled, | ||
539 | .enable = tps6507x_pmic_ldo_enable, | ||
540 | .disable = tps6507x_pmic_ldo_disable, | ||
541 | .get_voltage = tps6507x_pmic_ldo_get_voltage, | ||
542 | .set_voltage = tps6507x_pmic_ldo_set_voltage, | ||
543 | .list_voltage = tps6507x_pmic_ldo_list_voltage, | ||
544 | }; | ||
545 | |||
546 | static __devinit | ||
547 | int tps6507x_pmic_probe(struct platform_device *pdev) | ||
548 | { | 404 | { |
549 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 405 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
550 | struct tps_info *info = &tps6507x_pmic_regs[0]; | 406 | struct tps_info *info = &tps6507x_pmic_regs[0]; |
@@ -593,8 +449,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) | |||
593 | tps->desc[i].name = info->name; | 449 | tps->desc[i].name = info->name; |
594 | tps->desc[i].id = i; | 450 | tps->desc[i].id = i; |
595 | tps->desc[i].n_voltages = info->table_len; | 451 | tps->desc[i].n_voltages = info->table_len; |
596 | tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? | 452 | tps->desc[i].ops = &tps6507x_pmic_ops; |
597 | &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); | ||
598 | tps->desc[i].type = REGULATOR_VOLTAGE; | 453 | tps->desc[i].type = REGULATOR_VOLTAGE; |
599 | tps->desc[i].owner = THIS_MODULE; | 454 | tps->desc[i].owner = THIS_MODULE; |
600 | 455 | ||
@@ -648,22 +503,12 @@ static struct platform_driver tps6507x_pmic_driver = { | |||
648 | .remove = __devexit_p(tps6507x_pmic_remove), | 503 | .remove = __devexit_p(tps6507x_pmic_remove), |
649 | }; | 504 | }; |
650 | 505 | ||
651 | /** | ||
652 | * tps6507x_pmic_init | ||
653 | * | ||
654 | * Module init function | ||
655 | */ | ||
656 | static int __init tps6507x_pmic_init(void) | 506 | static int __init tps6507x_pmic_init(void) |
657 | { | 507 | { |
658 | return platform_driver_register(&tps6507x_pmic_driver); | 508 | return platform_driver_register(&tps6507x_pmic_driver); |
659 | } | 509 | } |
660 | subsys_initcall(tps6507x_pmic_init); | 510 | subsys_initcall(tps6507x_pmic_init); |
661 | 511 | ||
662 | /** | ||
663 | * tps6507x_pmic_cleanup | ||
664 | * | ||
665 | * Module exit function | ||
666 | */ | ||
667 | static void __exit tps6507x_pmic_cleanup(void) | 512 | static void __exit tps6507x_pmic_cleanup(void) |
668 | { | 513 | { |
669 | platform_driver_unregister(&tps6507x_pmic_driver); | 514 | platform_driver_unregister(&tps6507x_pmic_driver); |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c new file mode 100644 index 000000000000..e39521b42772 --- /dev/null +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -0,0 +1,378 @@ | |||
1 | /* | ||
2 | * tps65217-regulator.c | ||
3 | * | ||
4 | * Regulator driver for TPS65217 PMIC | ||
5 | * | ||
6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | #include <linux/regulator/driver.h> | ||
26 | #include <linux/regulator/machine.h> | ||
27 | #include <linux/mfd/tps65217.h> | ||
28 | |||
29 | #define TPS65217_REGULATOR(_name, _id, _ops, _n) \ | ||
30 | { \ | ||
31 | .name = _name, \ | ||
32 | .id = _id, \ | ||
33 | .ops = &_ops, \ | ||
34 | .n_voltages = _n, \ | ||
35 | .type = REGULATOR_VOLTAGE, \ | ||
36 | .owner = THIS_MODULE, \ | ||
37 | } \ | ||
38 | |||
39 | #define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \ | ||
40 | { \ | ||
41 | .name = _nm, \ | ||
42 | .min_uV = _min, \ | ||
43 | .max_uV = _max, \ | ||
44 | .vsel_to_uv = _f1, \ | ||
45 | .uv_to_vsel = _f2, \ | ||
46 | .table = _t, \ | ||
47 | .table_len = _n, \ | ||
48 | .enable_mask = _em, \ | ||
49 | .set_vout_reg = _vr, \ | ||
50 | .set_vout_mask = _vm, \ | ||
51 | } | ||
52 | |||
53 | static const int LDO1_VSEL_table[] = { | ||
54 | 1000000, 1100000, 1200000, 1250000, | ||
55 | 1300000, 1350000, 1400000, 1500000, | ||
56 | 1600000, 1800000, 2500000, 2750000, | ||
57 | 2800000, 3000000, 3100000, 3300000, | ||
58 | }; | ||
59 | |||
60 | static int tps65217_vsel_to_uv1(unsigned int vsel) | ||
61 | { | ||
62 | int uV = 0; | ||
63 | |||
64 | if (vsel > 63) | ||
65 | return -EINVAL; | ||
66 | |||
67 | if (vsel <= 24) | ||
68 | uV = vsel * 25000 + 900000; | ||
69 | else if (vsel <= 52) | ||
70 | uV = (vsel - 24) * 50000 + 1500000; | ||
71 | else if (vsel < 56) | ||
72 | uV = (vsel - 52) * 100000 + 2900000; | ||
73 | else | ||
74 | uV = 3300000; | ||
75 | |||
76 | return uV; | ||
77 | } | ||
78 | |||
79 | static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel) | ||
80 | { | ||
81 | if ((uV < 0) && (uV > 3300000)) | ||
82 | return -EINVAL; | ||
83 | |||
84 | if (uV <= 1500000) | ||
85 | *vsel = DIV_ROUND_UP(uV - 900000, 25000); | ||
86 | else if (uV <= 2900000) | ||
87 | *vsel = 24 + DIV_ROUND_UP(uV - 1500000, 50000); | ||
88 | else if (uV < 3300000) | ||
89 | *vsel = 52 + DIV_ROUND_UP(uV - 2900000, 100000); | ||
90 | else | ||
91 | *vsel = 56; | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int tps65217_vsel_to_uv2(unsigned int vsel) | ||
97 | { | ||
98 | int uV = 0; | ||
99 | |||
100 | if (vsel > 31) | ||
101 | return -EINVAL; | ||
102 | |||
103 | if (vsel <= 8) | ||
104 | uV = vsel * 50000 + 1500000; | ||
105 | else if (vsel <= 13) | ||
106 | uV = (vsel - 8) * 100000 + 1900000; | ||
107 | else | ||
108 | uV = (vsel - 13) * 50000 + 2400000; | ||
109 | |||
110 | return uV; | ||
111 | } | ||
112 | |||
113 | static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) | ||
114 | { | ||
115 | if ((uV < 0) && (uV > 3300000)) | ||
116 | return -EINVAL; | ||
117 | |||
118 | if (uV <= 1900000) | ||
119 | *vsel = DIV_ROUND_UP(uV - 1500000, 50000); | ||
120 | else if (uV <= 2400000) | ||
121 | *vsel = 8 + DIV_ROUND_UP(uV - 1900000, 100000); | ||
122 | else | ||
123 | *vsel = 13 + DIV_ROUND_UP(uV - 2400000, 50000); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static struct tps_info tps65217_pmic_regs[] = { | ||
129 | TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1, | ||
130 | tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN, | ||
131 | TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK), | ||
132 | TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1, | ||
133 | tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN, | ||
134 | TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK), | ||
135 | TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1, | ||
136 | tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN, | ||
137 | TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK), | ||
138 | TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table, | ||
139 | 16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1, | ||
140 | TPS65217_DEFLDO1_LDO1_MASK), | ||
141 | TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1, | ||
142 | tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN, | ||
143 | TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK), | ||
144 | TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2, | ||
145 | tps65217_uv_to_vsel2, NULL, 32, | ||
146 | TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, | ||
147 | TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK), | ||
148 | TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2, | ||
149 | tps65217_uv_to_vsel2, NULL, 32, | ||
150 | TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, | ||
151 | TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK), | ||
152 | }; | ||
153 | |||
154 | static int tps65217_pmic_is_enabled(struct regulator_dev *dev) | ||
155 | { | ||
156 | int ret; | ||
157 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
158 | unsigned int data, rid = rdev_get_id(dev); | ||
159 | |||
160 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
161 | return -EINVAL; | ||
162 | |||
163 | ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | |||
167 | return (data & tps->info[rid]->enable_mask) ? 1 : 0; | ||
168 | } | ||
169 | |||
170 | static int tps65217_pmic_enable(struct regulator_dev *dev) | ||
171 | { | ||
172 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
173 | unsigned int rid = rdev_get_id(dev); | ||
174 | |||
175 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
176 | return -EINVAL; | ||
177 | |||
178 | /* Enable the regulator and password protection is level 1 */ | ||
179 | return tps65217_set_bits(tps, TPS65217_REG_ENABLE, | ||
180 | tps->info[rid]->enable_mask, | ||
181 | tps->info[rid]->enable_mask, | ||
182 | TPS65217_PROTECT_L1); | ||
183 | } | ||
184 | |||
185 | static int tps65217_pmic_disable(struct regulator_dev *dev) | ||
186 | { | ||
187 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
188 | unsigned int rid = rdev_get_id(dev); | ||
189 | |||
190 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
191 | return -EINVAL; | ||
192 | |||
193 | /* Disable the regulator and password protection is level 1 */ | ||
194 | return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, | ||
195 | tps->info[rid]->enable_mask, TPS65217_PROTECT_L1); | ||
196 | } | ||
197 | |||
198 | static int tps65217_pmic_get_voltage_sel(struct regulator_dev *dev) | ||
199 | { | ||
200 | int ret; | ||
201 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
202 | unsigned int selector, rid = rdev_get_id(dev); | ||
203 | |||
204 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
205 | return -EINVAL; | ||
206 | |||
207 | ret = tps65217_reg_read(tps, tps->info[rid]->set_vout_reg, &selector); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | selector &= tps->info[rid]->set_vout_mask; | ||
212 | |||
213 | return selector; | ||
214 | } | ||
215 | |||
216 | static int tps65217_pmic_ldo1_set_voltage_sel(struct regulator_dev *dev, | ||
217 | unsigned selector) | ||
218 | { | ||
219 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
220 | int ldo = rdev_get_id(dev); | ||
221 | |||
222 | if (ldo != TPS65217_LDO_1) | ||
223 | return -EINVAL; | ||
224 | |||
225 | if (selector >= tps->info[ldo]->table_len) | ||
226 | return -EINVAL; | ||
227 | |||
228 | /* Set the voltage based on vsel value and write protect level is 2 */ | ||
229 | return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, | ||
230 | tps->info[ldo]->set_vout_mask, | ||
231 | selector, TPS65217_PROTECT_L2); | ||
232 | } | ||
233 | |||
234 | static int tps65217_pmic_set_voltage(struct regulator_dev *dev, | ||
235 | int min_uV, int max_uV, unsigned *selector) | ||
236 | { | ||
237 | int ret; | ||
238 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
239 | unsigned int rid = rdev_get_id(dev); | ||
240 | |||
241 | /* LDO1 implements set_voltage_sel callback */ | ||
242 | if (rid == TPS65217_LDO_1) | ||
243 | return -EINVAL; | ||
244 | |||
245 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
246 | return -EINVAL; | ||
247 | |||
248 | if (min_uV < tps->info[rid]->min_uV | ||
249 | || min_uV > tps->info[rid]->max_uV) | ||
250 | return -EINVAL; | ||
251 | |||
252 | if (max_uV < tps->info[rid]->min_uV | ||
253 | || max_uV > tps->info[rid]->max_uV) | ||
254 | return -EINVAL; | ||
255 | |||
256 | ret = tps->info[rid]->uv_to_vsel(min_uV, selector); | ||
257 | if (ret) | ||
258 | return ret; | ||
259 | |||
260 | /* Set the voltage based on vsel value and write protect level is 2 */ | ||
261 | ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg, | ||
262 | tps->info[rid]->set_vout_mask, | ||
263 | *selector, TPS65217_PROTECT_L2); | ||
264 | |||
265 | /* Set GO bit for DCDCx to initiate voltage transistion */ | ||
266 | switch (rid) { | ||
267 | case TPS65217_DCDC_1 ... TPS65217_DCDC_3: | ||
268 | ret = tps65217_set_bits(tps, TPS65217_REG_DEFSLEW, | ||
269 | TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO, | ||
270 | TPS65217_PROTECT_L2); | ||
271 | break; | ||
272 | } | ||
273 | |||
274 | return ret; | ||
275 | } | ||
276 | |||
277 | static int tps65217_pmic_list_voltage(struct regulator_dev *dev, | ||
278 | unsigned selector) | ||
279 | { | ||
280 | struct tps65217 *tps = rdev_get_drvdata(dev); | ||
281 | unsigned int rid = rdev_get_id(dev); | ||
282 | |||
283 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ||
284 | return -EINVAL; | ||
285 | |||
286 | if (selector >= tps->info[rid]->table_len) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (tps->info[rid]->table) | ||
290 | return tps->info[rid]->table[selector]; | ||
291 | |||
292 | return tps->info[rid]->vsel_to_uv(selector); | ||
293 | } | ||
294 | |||
295 | /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ | ||
296 | static struct regulator_ops tps65217_pmic_ops = { | ||
297 | .is_enabled = tps65217_pmic_is_enabled, | ||
298 | .enable = tps65217_pmic_enable, | ||
299 | .disable = tps65217_pmic_disable, | ||
300 | .get_voltage_sel = tps65217_pmic_get_voltage_sel, | ||
301 | .set_voltage = tps65217_pmic_set_voltage, | ||
302 | .list_voltage = tps65217_pmic_list_voltage, | ||
303 | }; | ||
304 | |||
305 | /* Operations permitted on LDO1 */ | ||
306 | static struct regulator_ops tps65217_pmic_ldo1_ops = { | ||
307 | .is_enabled = tps65217_pmic_is_enabled, | ||
308 | .enable = tps65217_pmic_enable, | ||
309 | .disable = tps65217_pmic_disable, | ||
310 | .get_voltage_sel = tps65217_pmic_get_voltage_sel, | ||
311 | .set_voltage_sel = tps65217_pmic_ldo1_set_voltage_sel, | ||
312 | .list_voltage = tps65217_pmic_list_voltage, | ||
313 | }; | ||
314 | |||
315 | static struct regulator_desc regulators[] = { | ||
316 | TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64), | ||
317 | TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64), | ||
318 | TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64), | ||
319 | TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, tps65217_pmic_ldo1_ops, 16), | ||
320 | TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, tps65217_pmic_ops, 64), | ||
321 | TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, tps65217_pmic_ops, 32), | ||
322 | TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, tps65217_pmic_ops, 32), | ||
323 | }; | ||
324 | |||
325 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | ||
326 | { | ||
327 | struct regulator_dev *rdev; | ||
328 | struct tps65217 *tps; | ||
329 | struct tps_info *info = &tps65217_pmic_regs[pdev->id]; | ||
330 | |||
331 | /* Already set by core driver */ | ||
332 | tps = dev_to_tps65217(pdev->dev.parent); | ||
333 | tps->info[pdev->id] = info; | ||
334 | |||
335 | rdev = regulator_register(®ulators[pdev->id], &pdev->dev, | ||
336 | pdev->dev.platform_data, tps, NULL); | ||
337 | if (IS_ERR(rdev)) | ||
338 | return PTR_ERR(rdev); | ||
339 | |||
340 | platform_set_drvdata(pdev, rdev); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) | ||
346 | { | ||
347 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
348 | |||
349 | platform_set_drvdata(pdev, NULL); | ||
350 | regulator_unregister(rdev); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static struct platform_driver tps65217_regulator_driver = { | ||
356 | .driver = { | ||
357 | .name = "tps65217-pmic", | ||
358 | }, | ||
359 | .probe = tps65217_regulator_probe, | ||
360 | .remove = __devexit_p(tps65217_regulator_remove), | ||
361 | }; | ||
362 | |||
363 | static int __init tps65217_regulator_init(void) | ||
364 | { | ||
365 | return platform_driver_register(&tps65217_regulator_driver); | ||
366 | } | ||
367 | subsys_initcall(tps65217_regulator_init); | ||
368 | |||
369 | static void __exit tps65217_regulator_exit(void) | ||
370 | { | ||
371 | platform_driver_unregister(&tps65217_regulator_driver); | ||
372 | } | ||
373 | module_exit(tps65217_regulator_exit); | ||
374 | |||
375 | MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>"); | ||
376 | MODULE_DESCRIPTION("TPS65217 voltage regulator driver"); | ||
377 | MODULE_ALIAS("platform:tps65217-pmic"); | ||
378 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 2e94686b6fe6..4a421be6d4f2 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c | |||
@@ -108,9 +108,7 @@ | |||
108 | #define N_DCDC 3 | 108 | #define N_DCDC 3 |
109 | #define N_LDO 2 | 109 | #define N_LDO 2 |
110 | #define N_SWITCH 2 | 110 | #define N_SWITCH 2 |
111 | #define N_REGULATORS (3 /* DCDC */ + \ | 111 | #define N_REGULATORS (N_DCDC + N_LDO + N_SWITCH) |
112 | 2 /* LDO */ + \ | ||
113 | 2 /* switch */) | ||
114 | 112 | ||
115 | #define FIXED_ILIMSEL BIT(0) | 113 | #define FIXED_ILIMSEL BIT(0) |
116 | #define FIXED_VOLTAGE BIT(1) | 114 | #define FIXED_VOLTAGE BIT(1) |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index c75fb20faa57..29b615ce3aff 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -383,7 +383,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) | |||
383 | int id = pdev->id; | 383 | int id = pdev->id; |
384 | int err; | 384 | int err; |
385 | 385 | ||
386 | dev_dbg(&pdev->dev, "Probing reulator %d\n", id); | 386 | dev_dbg(&pdev->dev, "Probing regulator %d\n", id); |
387 | 387 | ||
388 | ri = find_regulator_info(id); | 388 | ri = find_regulator_info(id); |
389 | if (ri == NULL) { | 389 | if (ri == NULL) { |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 40ecf5165899..4a37c2b6367f 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -26,6 +26,10 @@ | |||
26 | #include <linux/mfd/tps65910.h> | 26 | #include <linux/mfd/tps65910.h> |
27 | 27 | ||
28 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 | 28 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 |
29 | #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ | ||
30 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ | ||
31 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ | ||
32 | TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) | ||
29 | 33 | ||
30 | /* supported VIO voltages in milivolts */ | 34 | /* supported VIO voltages in milivolts */ |
31 | static const u16 VIO_VSEL_table[] = { | 35 | static const u16 VIO_VSEL_table[] = { |
@@ -83,161 +87,235 @@ struct tps_info { | |||
83 | const char *name; | 87 | const char *name; |
84 | unsigned min_uV; | 88 | unsigned min_uV; |
85 | unsigned max_uV; | 89 | unsigned max_uV; |
86 | u8 table_len; | 90 | u8 n_voltages; |
87 | const u16 *table; | 91 | const u16 *voltage_table; |
92 | int enable_time_us; | ||
88 | }; | 93 | }; |
89 | 94 | ||
90 | static struct tps_info tps65910_regs[] = { | 95 | static struct tps_info tps65910_regs[] = { |
91 | { | 96 | { |
92 | .name = "VRTC", | 97 | .name = "VRTC", |
98 | .enable_time_us = 2200, | ||
93 | }, | 99 | }, |
94 | { | 100 | { |
95 | .name = "VIO", | 101 | .name = "VIO", |
96 | .min_uV = 1500000, | 102 | .min_uV = 1500000, |
97 | .max_uV = 3300000, | 103 | .max_uV = 3300000, |
98 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | 104 | .n_voltages = ARRAY_SIZE(VIO_VSEL_table), |
99 | .table = VIO_VSEL_table, | 105 | .voltage_table = VIO_VSEL_table, |
106 | .enable_time_us = 350, | ||
100 | }, | 107 | }, |
101 | { | 108 | { |
102 | .name = "VDD1", | 109 | .name = "VDD1", |
103 | .min_uV = 600000, | 110 | .min_uV = 600000, |
104 | .max_uV = 4500000, | 111 | .max_uV = 4500000, |
112 | .enable_time_us = 350, | ||
105 | }, | 113 | }, |
106 | { | 114 | { |
107 | .name = "VDD2", | 115 | .name = "VDD2", |
108 | .min_uV = 600000, | 116 | .min_uV = 600000, |
109 | .max_uV = 4500000, | 117 | .max_uV = 4500000, |
118 | .enable_time_us = 350, | ||
110 | }, | 119 | }, |
111 | { | 120 | { |
112 | .name = "VDD3", | 121 | .name = "VDD3", |
113 | .min_uV = 5000000, | 122 | .min_uV = 5000000, |
114 | .max_uV = 5000000, | 123 | .max_uV = 5000000, |
115 | .table_len = ARRAY_SIZE(VDD3_VSEL_table), | 124 | .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), |
116 | .table = VDD3_VSEL_table, | 125 | .voltage_table = VDD3_VSEL_table, |
126 | .enable_time_us = 200, | ||
117 | }, | 127 | }, |
118 | { | 128 | { |
119 | .name = "VDIG1", | 129 | .name = "VDIG1", |
120 | .min_uV = 1200000, | 130 | .min_uV = 1200000, |
121 | .max_uV = 2700000, | 131 | .max_uV = 2700000, |
122 | .table_len = ARRAY_SIZE(VDIG1_VSEL_table), | 132 | .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), |
123 | .table = VDIG1_VSEL_table, | 133 | .voltage_table = VDIG1_VSEL_table, |
134 | .enable_time_us = 100, | ||
124 | }, | 135 | }, |
125 | { | 136 | { |
126 | .name = "VDIG2", | 137 | .name = "VDIG2", |
127 | .min_uV = 1000000, | 138 | .min_uV = 1000000, |
128 | .max_uV = 1800000, | 139 | .max_uV = 1800000, |
129 | .table_len = ARRAY_SIZE(VDIG2_VSEL_table), | 140 | .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), |
130 | .table = VDIG2_VSEL_table, | 141 | .voltage_table = VDIG2_VSEL_table, |
142 | .enable_time_us = 100, | ||
131 | }, | 143 | }, |
132 | { | 144 | { |
133 | .name = "VPLL", | 145 | .name = "VPLL", |
134 | .min_uV = 1000000, | 146 | .min_uV = 1000000, |
135 | .max_uV = 2500000, | 147 | .max_uV = 2500000, |
136 | .table_len = ARRAY_SIZE(VPLL_VSEL_table), | 148 | .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), |
137 | .table = VPLL_VSEL_table, | 149 | .voltage_table = VPLL_VSEL_table, |
150 | .enable_time_us = 100, | ||
138 | }, | 151 | }, |
139 | { | 152 | { |
140 | .name = "VDAC", | 153 | .name = "VDAC", |
141 | .min_uV = 1800000, | 154 | .min_uV = 1800000, |
142 | .max_uV = 2850000, | 155 | .max_uV = 2850000, |
143 | .table_len = ARRAY_SIZE(VDAC_VSEL_table), | 156 | .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), |
144 | .table = VDAC_VSEL_table, | 157 | .voltage_table = VDAC_VSEL_table, |
158 | .enable_time_us = 100, | ||
145 | }, | 159 | }, |
146 | { | 160 | { |
147 | .name = "VAUX1", | 161 | .name = "VAUX1", |
148 | .min_uV = 1800000, | 162 | .min_uV = 1800000, |
149 | .max_uV = 2850000, | 163 | .max_uV = 2850000, |
150 | .table_len = ARRAY_SIZE(VAUX1_VSEL_table), | 164 | .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), |
151 | .table = VAUX1_VSEL_table, | 165 | .voltage_table = VAUX1_VSEL_table, |
166 | .enable_time_us = 100, | ||
152 | }, | 167 | }, |
153 | { | 168 | { |
154 | .name = "VAUX2", | 169 | .name = "VAUX2", |
155 | .min_uV = 1800000, | 170 | .min_uV = 1800000, |
156 | .max_uV = 3300000, | 171 | .max_uV = 3300000, |
157 | .table_len = ARRAY_SIZE(VAUX2_VSEL_table), | 172 | .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), |
158 | .table = VAUX2_VSEL_table, | 173 | .voltage_table = VAUX2_VSEL_table, |
174 | .enable_time_us = 100, | ||
159 | }, | 175 | }, |
160 | { | 176 | { |
161 | .name = "VAUX33", | 177 | .name = "VAUX33", |
162 | .min_uV = 1800000, | 178 | .min_uV = 1800000, |
163 | .max_uV = 3300000, | 179 | .max_uV = 3300000, |
164 | .table_len = ARRAY_SIZE(VAUX33_VSEL_table), | 180 | .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), |
165 | .table = VAUX33_VSEL_table, | 181 | .voltage_table = VAUX33_VSEL_table, |
182 | .enable_time_us = 100, | ||
166 | }, | 183 | }, |
167 | { | 184 | { |
168 | .name = "VMMC", | 185 | .name = "VMMC", |
169 | .min_uV = 1800000, | 186 | .min_uV = 1800000, |
170 | .max_uV = 3300000, | 187 | .max_uV = 3300000, |
171 | .table_len = ARRAY_SIZE(VMMC_VSEL_table), | 188 | .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), |
172 | .table = VMMC_VSEL_table, | 189 | .voltage_table = VMMC_VSEL_table, |
190 | .enable_time_us = 100, | ||
173 | }, | 191 | }, |
174 | }; | 192 | }; |
175 | 193 | ||
176 | static struct tps_info tps65911_regs[] = { | 194 | static struct tps_info tps65911_regs[] = { |
177 | { | 195 | { |
196 | .name = "VRTC", | ||
197 | .enable_time_us = 2200, | ||
198 | }, | ||
199 | { | ||
178 | .name = "VIO", | 200 | .name = "VIO", |
179 | .min_uV = 1500000, | 201 | .min_uV = 1500000, |
180 | .max_uV = 3300000, | 202 | .max_uV = 3300000, |
181 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | 203 | .n_voltages = ARRAY_SIZE(VIO_VSEL_table), |
182 | .table = VIO_VSEL_table, | 204 | .voltage_table = VIO_VSEL_table, |
205 | .enable_time_us = 350, | ||
183 | }, | 206 | }, |
184 | { | 207 | { |
185 | .name = "VDD1", | 208 | .name = "VDD1", |
186 | .min_uV = 600000, | 209 | .min_uV = 600000, |
187 | .max_uV = 4500000, | 210 | .max_uV = 4500000, |
211 | .n_voltages = 73, | ||
212 | .enable_time_us = 350, | ||
188 | }, | 213 | }, |
189 | { | 214 | { |
190 | .name = "VDD2", | 215 | .name = "VDD2", |
191 | .min_uV = 600000, | 216 | .min_uV = 600000, |
192 | .max_uV = 4500000, | 217 | .max_uV = 4500000, |
218 | .n_voltages = 73, | ||
219 | .enable_time_us = 350, | ||
193 | }, | 220 | }, |
194 | { | 221 | { |
195 | .name = "VDDCTRL", | 222 | .name = "VDDCTRL", |
196 | .min_uV = 600000, | 223 | .min_uV = 600000, |
197 | .max_uV = 1400000, | 224 | .max_uV = 1400000, |
225 | .n_voltages = 65, | ||
226 | .enable_time_us = 900, | ||
198 | }, | 227 | }, |
199 | { | 228 | { |
200 | .name = "LDO1", | 229 | .name = "LDO1", |
201 | .min_uV = 1000000, | 230 | .min_uV = 1000000, |
202 | .max_uV = 3300000, | 231 | .max_uV = 3300000, |
232 | .n_voltages = 47, | ||
233 | .enable_time_us = 420, | ||
203 | }, | 234 | }, |
204 | { | 235 | { |
205 | .name = "LDO2", | 236 | .name = "LDO2", |
206 | .min_uV = 1000000, | 237 | .min_uV = 1000000, |
207 | .max_uV = 3300000, | 238 | .max_uV = 3300000, |
239 | .n_voltages = 47, | ||
240 | .enable_time_us = 420, | ||
208 | }, | 241 | }, |
209 | { | 242 | { |
210 | .name = "LDO3", | 243 | .name = "LDO3", |
211 | .min_uV = 1000000, | 244 | .min_uV = 1000000, |
212 | .max_uV = 3300000, | 245 | .max_uV = 3300000, |
246 | .n_voltages = 24, | ||
247 | .enable_time_us = 230, | ||
213 | }, | 248 | }, |
214 | { | 249 | { |
215 | .name = "LDO4", | 250 | .name = "LDO4", |
216 | .min_uV = 1000000, | 251 | .min_uV = 1000000, |
217 | .max_uV = 3300000, | 252 | .max_uV = 3300000, |
253 | .n_voltages = 47, | ||
254 | .enable_time_us = 230, | ||
218 | }, | 255 | }, |
219 | { | 256 | { |
220 | .name = "LDO5", | 257 | .name = "LDO5", |
221 | .min_uV = 1000000, | 258 | .min_uV = 1000000, |
222 | .max_uV = 3300000, | 259 | .max_uV = 3300000, |
260 | .n_voltages = 24, | ||
261 | .enable_time_us = 230, | ||
223 | }, | 262 | }, |
224 | { | 263 | { |
225 | .name = "LDO6", | 264 | .name = "LDO6", |
226 | .min_uV = 1000000, | 265 | .min_uV = 1000000, |
227 | .max_uV = 3300000, | 266 | .max_uV = 3300000, |
267 | .n_voltages = 24, | ||
268 | .enable_time_us = 230, | ||
228 | }, | 269 | }, |
229 | { | 270 | { |
230 | .name = "LDO7", | 271 | .name = "LDO7", |
231 | .min_uV = 1000000, | 272 | .min_uV = 1000000, |
232 | .max_uV = 3300000, | 273 | .max_uV = 3300000, |
274 | .n_voltages = 24, | ||
275 | .enable_time_us = 230, | ||
233 | }, | 276 | }, |
234 | { | 277 | { |
235 | .name = "LDO8", | 278 | .name = "LDO8", |
236 | .min_uV = 1000000, | 279 | .min_uV = 1000000, |
237 | .max_uV = 3300000, | 280 | .max_uV = 3300000, |
281 | .n_voltages = 24, | ||
282 | .enable_time_us = 230, | ||
238 | }, | 283 | }, |
239 | }; | 284 | }; |
240 | 285 | ||
286 | #define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) | ||
287 | static unsigned int tps65910_ext_sleep_control[] = { | ||
288 | 0, | ||
289 | EXT_CONTROL_REG_BITS(VIO, 1, 0), | ||
290 | EXT_CONTROL_REG_BITS(VDD1, 1, 1), | ||
291 | EXT_CONTROL_REG_BITS(VDD2, 1, 2), | ||
292 | EXT_CONTROL_REG_BITS(VDD3, 1, 3), | ||
293 | EXT_CONTROL_REG_BITS(VDIG1, 0, 1), | ||
294 | EXT_CONTROL_REG_BITS(VDIG2, 0, 2), | ||
295 | EXT_CONTROL_REG_BITS(VPLL, 0, 6), | ||
296 | EXT_CONTROL_REG_BITS(VDAC, 0, 7), | ||
297 | EXT_CONTROL_REG_BITS(VAUX1, 0, 3), | ||
298 | EXT_CONTROL_REG_BITS(VAUX2, 0, 4), | ||
299 | EXT_CONTROL_REG_BITS(VAUX33, 0, 5), | ||
300 | EXT_CONTROL_REG_BITS(VMMC, 0, 0), | ||
301 | }; | ||
302 | |||
303 | static unsigned int tps65911_ext_sleep_control[] = { | ||
304 | 0, | ||
305 | EXT_CONTROL_REG_BITS(VIO, 1, 0), | ||
306 | EXT_CONTROL_REG_BITS(VDD1, 1, 1), | ||
307 | EXT_CONTROL_REG_BITS(VDD2, 1, 2), | ||
308 | EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), | ||
309 | EXT_CONTROL_REG_BITS(LDO1, 0, 1), | ||
310 | EXT_CONTROL_REG_BITS(LDO2, 0, 2), | ||
311 | EXT_CONTROL_REG_BITS(LDO3, 0, 7), | ||
312 | EXT_CONTROL_REG_BITS(LDO4, 0, 6), | ||
313 | EXT_CONTROL_REG_BITS(LDO5, 0, 3), | ||
314 | EXT_CONTROL_REG_BITS(LDO6, 0, 0), | ||
315 | EXT_CONTROL_REG_BITS(LDO7, 0, 5), | ||
316 | EXT_CONTROL_REG_BITS(LDO8, 0, 4), | ||
317 | }; | ||
318 | |||
241 | struct tps65910_reg { | 319 | struct tps65910_reg { |
242 | struct regulator_desc *desc; | 320 | struct regulator_desc *desc; |
243 | struct tps65910 *mfd; | 321 | struct tps65910 *mfd; |
@@ -247,6 +325,8 @@ struct tps65910_reg { | |||
247 | int num_regulators; | 325 | int num_regulators; |
248 | int mode; | 326 | int mode; |
249 | int (*get_ctrl_reg)(int); | 327 | int (*get_ctrl_reg)(int); |
328 | unsigned int *ext_sleep_control; | ||
329 | unsigned int board_ext_control[TPS65910_NUM_REGS]; | ||
250 | }; | 330 | }; |
251 | 331 | ||
252 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) | 332 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) |
@@ -429,6 +509,12 @@ static int tps65910_disable(struct regulator_dev *dev) | |||
429 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | 509 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); |
430 | } | 510 | } |
431 | 511 | ||
512 | static int tps65910_enable_time(struct regulator_dev *dev) | ||
513 | { | ||
514 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
515 | int id = rdev_get_id(dev); | ||
516 | return pmic->info[id]->enable_time_us; | ||
517 | } | ||
432 | 518 | ||
433 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) | 519 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) |
434 | { | 520 | { |
@@ -467,7 +553,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |||
467 | if (value < 0) | 553 | if (value < 0) |
468 | return value; | 554 | return value; |
469 | 555 | ||
470 | if (value & LDO_ST_ON_BIT) | 556 | if (!(value & LDO_ST_ON_BIT)) |
471 | return REGULATOR_MODE_STANDBY; | 557 | return REGULATOR_MODE_STANDBY; |
472 | else if (value & LDO_ST_MODE_BIT) | 558 | else if (value & LDO_ST_MODE_BIT) |
473 | return REGULATOR_MODE_IDLE; | 559 | return REGULATOR_MODE_IDLE; |
@@ -475,10 +561,10 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |||
475 | return REGULATOR_MODE_NORMAL; | 561 | return REGULATOR_MODE_NORMAL; |
476 | } | 562 | } |
477 | 563 | ||
478 | static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | 564 | static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) |
479 | { | 565 | { |
480 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 566 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
481 | int id = rdev_get_id(dev), voltage = 0; | 567 | int id = rdev_get_id(dev); |
482 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; | 568 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; |
483 | 569 | ||
484 | switch (id) { | 570 | switch (id) { |
@@ -522,9 +608,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | |||
522 | srvsel = 3; | 608 | srvsel = 3; |
523 | if (srvsel > vselmax) | 609 | if (srvsel > vselmax) |
524 | srvsel = vselmax; | 610 | srvsel = vselmax; |
525 | srvsel -= 3; | 611 | return srvsel - 3; |
526 | |||
527 | voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
528 | } else { | 612 | } else { |
529 | 613 | ||
530 | /* normalise to valid range*/ | 614 | /* normalise to valid range*/ |
@@ -532,14 +616,9 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | |||
532 | opvsel = 3; | 616 | opvsel = 3; |
533 | if (opvsel > vselmax) | 617 | if (opvsel > vselmax) |
534 | opvsel = vselmax; | 618 | opvsel = vselmax; |
535 | opvsel -= 3; | 619 | return opvsel - 3; |
536 | |||
537 | voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
538 | } | 620 | } |
539 | 621 | return -EINVAL; | |
540 | voltage *= mult; | ||
541 | |||
542 | return voltage; | ||
543 | } | 622 | } |
544 | 623 | ||
545 | static int tps65910_get_voltage(struct regulator_dev *dev) | 624 | static int tps65910_get_voltage(struct regulator_dev *dev) |
@@ -572,7 +651,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) | |||
572 | return -EINVAL; | 651 | return -EINVAL; |
573 | } | 652 | } |
574 | 653 | ||
575 | voltage = pmic->info[id]->table[value] * 1000; | 654 | voltage = pmic->info[id]->voltage_table[value] * 1000; |
576 | 655 | ||
577 | return voltage; | 656 | return voltage; |
578 | } | 657 | } |
@@ -622,8 +701,9 @@ static int tps65911_get_voltage(struct regulator_dev *dev) | |||
622 | step_mv = 100; | 701 | step_mv = 100; |
623 | break; | 702 | break; |
624 | case TPS65910_REG_VIO: | 703 | case TPS65910_REG_VIO: |
625 | return pmic->info[id]->table[value] * 1000; | 704 | value &= LDO_SEL_MASK; |
626 | break; | 705 | value >>= LDO_SEL_SHIFT; |
706 | return pmic->info[id]->voltage_table[value] * 1000; | ||
627 | default: | 707 | default: |
628 | return -EINVAL; | 708 | return -EINVAL; |
629 | } | 709 | } |
@@ -631,8 +711,8 @@ static int tps65911_get_voltage(struct regulator_dev *dev) | |||
631 | return (LDO_MIN_VOLT + value * step_mv) * 1000; | 711 | return (LDO_MIN_VOLT + value * step_mv) * 1000; |
632 | } | 712 | } |
633 | 713 | ||
634 | static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | 714 | static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, |
635 | unsigned selector) | 715 | unsigned selector) |
636 | { | 716 | { |
637 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 717 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
638 | int id = rdev_get_id(dev), vsel; | 718 | int id = rdev_get_id(dev), vsel; |
@@ -669,7 +749,8 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | |||
669 | return 0; | 749 | return 0; |
670 | } | 750 | } |
671 | 751 | ||
672 | static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | 752 | static int tps65910_set_voltage_sel(struct regulator_dev *dev, |
753 | unsigned selector) | ||
673 | { | 754 | { |
674 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 755 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
675 | int reg, id = rdev_get_id(dev); | 756 | int reg, id = rdev_get_id(dev); |
@@ -695,7 +776,8 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | |||
695 | return -EINVAL; | 776 | return -EINVAL; |
696 | } | 777 | } |
697 | 778 | ||
698 | static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) | 779 | static int tps65911_set_voltage_sel(struct regulator_dev *dev, |
780 | unsigned selector) | ||
699 | { | 781 | { |
700 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 782 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
701 | int reg, id = rdev_get_id(dev); | 783 | int reg, id = rdev_get_id(dev); |
@@ -715,9 +797,11 @@ static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) | |||
715 | case TPS65911_REG_LDO6: | 797 | case TPS65911_REG_LDO6: |
716 | case TPS65911_REG_LDO7: | 798 | case TPS65911_REG_LDO7: |
717 | case TPS65911_REG_LDO8: | 799 | case TPS65911_REG_LDO8: |
718 | case TPS65910_REG_VIO: | ||
719 | return tps65910_modify_bits(pmic, reg, | 800 | return tps65910_modify_bits(pmic, reg, |
720 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); | 801 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); |
802 | case TPS65910_REG_VIO: | ||
803 | return tps65910_modify_bits(pmic, reg, | ||
804 | (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); | ||
721 | } | 805 | } |
722 | 806 | ||
723 | return -EINVAL; | 807 | return -EINVAL; |
@@ -756,10 +840,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev, | |||
756 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) | 840 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) |
757 | return -EINVAL; | 841 | return -EINVAL; |
758 | 842 | ||
759 | if (selector >= pmic->info[id]->table_len) | 843 | if (selector >= pmic->info[id]->n_voltages) |
760 | return -EINVAL; | 844 | return -EINVAL; |
761 | else | 845 | else |
762 | voltage = pmic->info[id]->table[selector] * 1000; | 846 | voltage = pmic->info[id]->voltage_table[selector] * 1000; |
763 | 847 | ||
764 | return voltage; | 848 | return voltage; |
765 | } | 849 | } |
@@ -795,7 +879,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) | |||
795 | step_mv = 100; | 879 | step_mv = 100; |
796 | break; | 880 | break; |
797 | case TPS65910_REG_VIO: | 881 | case TPS65910_REG_VIO: |
798 | return pmic->info[id]->table[selector] * 1000; | 882 | return pmic->info[id]->voltage_table[selector] * 1000; |
799 | default: | 883 | default: |
800 | return -EINVAL; | 884 | return -EINVAL; |
801 | } | 885 | } |
@@ -803,15 +887,42 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) | |||
803 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; | 887 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; |
804 | } | 888 | } |
805 | 889 | ||
890 | static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, | ||
891 | unsigned int old_selector, unsigned int new_selector) | ||
892 | { | ||
893 | int id = rdev_get_id(dev); | ||
894 | int old_volt, new_volt; | ||
895 | |||
896 | old_volt = tps65910_list_voltage_dcdc(dev, old_selector); | ||
897 | if (old_volt < 0) | ||
898 | return old_volt; | ||
899 | |||
900 | new_volt = tps65910_list_voltage_dcdc(dev, new_selector); | ||
901 | if (new_volt < 0) | ||
902 | return new_volt; | ||
903 | |||
904 | /* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */ | ||
905 | switch (id) { | ||
906 | case TPS65910_REG_VDD1: | ||
907 | case TPS65910_REG_VDD2: | ||
908 | return DIV_ROUND_UP(abs(old_volt - new_volt), 12500); | ||
909 | case TPS65911_REG_VDDCTRL: | ||
910 | return DIV_ROUND_UP(abs(old_volt - new_volt), 5000); | ||
911 | } | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
806 | /* Regulator ops (except VRTC) */ | 915 | /* Regulator ops (except VRTC) */ |
807 | static struct regulator_ops tps65910_ops_dcdc = { | 916 | static struct regulator_ops tps65910_ops_dcdc = { |
808 | .is_enabled = tps65910_is_enabled, | 917 | .is_enabled = tps65910_is_enabled, |
809 | .enable = tps65910_enable, | 918 | .enable = tps65910_enable, |
810 | .disable = tps65910_disable, | 919 | .disable = tps65910_disable, |
920 | .enable_time = tps65910_enable_time, | ||
811 | .set_mode = tps65910_set_mode, | 921 | .set_mode = tps65910_set_mode, |
812 | .get_mode = tps65910_get_mode, | 922 | .get_mode = tps65910_get_mode, |
813 | .get_voltage = tps65910_get_voltage_dcdc, | 923 | .get_voltage_sel = tps65910_get_voltage_dcdc_sel, |
814 | .set_voltage_sel = tps65910_set_voltage_dcdc, | 924 | .set_voltage_sel = tps65910_set_voltage_dcdc_sel, |
925 | .set_voltage_time_sel = tps65910_set_voltage_dcdc_time_sel, | ||
815 | .list_voltage = tps65910_list_voltage_dcdc, | 926 | .list_voltage = tps65910_list_voltage_dcdc, |
816 | }; | 927 | }; |
817 | 928 | ||
@@ -819,6 +930,7 @@ static struct regulator_ops tps65910_ops_vdd3 = { | |||
819 | .is_enabled = tps65910_is_enabled, | 930 | .is_enabled = tps65910_is_enabled, |
820 | .enable = tps65910_enable, | 931 | .enable = tps65910_enable, |
821 | .disable = tps65910_disable, | 932 | .disable = tps65910_disable, |
933 | .enable_time = tps65910_enable_time, | ||
822 | .set_mode = tps65910_set_mode, | 934 | .set_mode = tps65910_set_mode, |
823 | .get_mode = tps65910_get_mode, | 935 | .get_mode = tps65910_get_mode, |
824 | .get_voltage = tps65910_get_voltage_vdd3, | 936 | .get_voltage = tps65910_get_voltage_vdd3, |
@@ -829,10 +941,11 @@ static struct regulator_ops tps65910_ops = { | |||
829 | .is_enabled = tps65910_is_enabled, | 941 | .is_enabled = tps65910_is_enabled, |
830 | .enable = tps65910_enable, | 942 | .enable = tps65910_enable, |
831 | .disable = tps65910_disable, | 943 | .disable = tps65910_disable, |
944 | .enable_time = tps65910_enable_time, | ||
832 | .set_mode = tps65910_set_mode, | 945 | .set_mode = tps65910_set_mode, |
833 | .get_mode = tps65910_get_mode, | 946 | .get_mode = tps65910_get_mode, |
834 | .get_voltage = tps65910_get_voltage, | 947 | .get_voltage = tps65910_get_voltage, |
835 | .set_voltage_sel = tps65910_set_voltage, | 948 | .set_voltage_sel = tps65910_set_voltage_sel, |
836 | .list_voltage = tps65910_list_voltage, | 949 | .list_voltage = tps65910_list_voltage, |
837 | }; | 950 | }; |
838 | 951 | ||
@@ -840,13 +953,147 @@ static struct regulator_ops tps65911_ops = { | |||
840 | .is_enabled = tps65910_is_enabled, | 953 | .is_enabled = tps65910_is_enabled, |
841 | .enable = tps65910_enable, | 954 | .enable = tps65910_enable, |
842 | .disable = tps65910_disable, | 955 | .disable = tps65910_disable, |
956 | .enable_time = tps65910_enable_time, | ||
843 | .set_mode = tps65910_set_mode, | 957 | .set_mode = tps65910_set_mode, |
844 | .get_mode = tps65910_get_mode, | 958 | .get_mode = tps65910_get_mode, |
845 | .get_voltage = tps65911_get_voltage, | 959 | .get_voltage = tps65911_get_voltage, |
846 | .set_voltage_sel = tps65911_set_voltage, | 960 | .set_voltage_sel = tps65911_set_voltage_sel, |
847 | .list_voltage = tps65911_list_voltage, | 961 | .list_voltage = tps65911_list_voltage, |
848 | }; | 962 | }; |
849 | 963 | ||
964 | static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | ||
965 | int id, int ext_sleep_config) | ||
966 | { | ||
967 | struct tps65910 *mfd = pmic->mfd; | ||
968 | u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; | ||
969 | u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); | ||
970 | int ret; | ||
971 | |||
972 | /* | ||
973 | * Regulator can not be control from multiple external input EN1, EN2 | ||
974 | * and EN3 together. | ||
975 | */ | ||
976 | if (ext_sleep_config & EXT_SLEEP_CONTROL) { | ||
977 | int en_count; | ||
978 | en_count = ((ext_sleep_config & | ||
979 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); | ||
980 | en_count += ((ext_sleep_config & | ||
981 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); | ||
982 | en_count += ((ext_sleep_config & | ||
983 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); | ||
984 | en_count += ((ext_sleep_config & | ||
985 | TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0); | ||
986 | if (en_count > 1) { | ||
987 | dev_err(mfd->dev, | ||
988 | "External sleep control flag is not proper\n"); | ||
989 | return -EINVAL; | ||
990 | } | ||
991 | } | ||
992 | |||
993 | pmic->board_ext_control[id] = ext_sleep_config; | ||
994 | |||
995 | /* External EN1 control */ | ||
996 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) | ||
997 | ret = tps65910_set_bits(mfd, | ||
998 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | ||
999 | else | ||
1000 | ret = tps65910_clear_bits(mfd, | ||
1001 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | ||
1002 | if (ret < 0) { | ||
1003 | dev_err(mfd->dev, | ||
1004 | "Error in configuring external control EN1\n"); | ||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | /* External EN2 control */ | ||
1009 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) | ||
1010 | ret = tps65910_set_bits(mfd, | ||
1011 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | ||
1012 | else | ||
1013 | ret = tps65910_clear_bits(mfd, | ||
1014 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | ||
1015 | if (ret < 0) { | ||
1016 | dev_err(mfd->dev, | ||
1017 | "Error in configuring external control EN2\n"); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | /* External EN3 control for TPS65910 LDO only */ | ||
1022 | if ((tps65910_chip_id(mfd) == TPS65910) && | ||
1023 | (id >= TPS65910_REG_VDIG1)) { | ||
1024 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) | ||
1025 | ret = tps65910_set_bits(mfd, | ||
1026 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | ||
1027 | else | ||
1028 | ret = tps65910_clear_bits(mfd, | ||
1029 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | ||
1030 | if (ret < 0) { | ||
1031 | dev_err(mfd->dev, | ||
1032 | "Error in configuring external control EN3\n"); | ||
1033 | return ret; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | /* Return if no external control is selected */ | ||
1038 | if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { | ||
1039 | /* Clear all sleep controls */ | ||
1040 | ret = tps65910_clear_bits(mfd, | ||
1041 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | ||
1042 | if (!ret) | ||
1043 | ret = tps65910_clear_bits(mfd, | ||
1044 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1045 | if (ret < 0) | ||
1046 | dev_err(mfd->dev, | ||
1047 | "Error in configuring SLEEP register\n"); | ||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | /* | ||
1052 | * For regulator that has separate operational and sleep register make | ||
1053 | * sure that operational is used and clear sleep register to turn | ||
1054 | * regulator off when external control is inactive | ||
1055 | */ | ||
1056 | if ((id == TPS65910_REG_VDD1) || | ||
1057 | (id == TPS65910_REG_VDD2) || | ||
1058 | ((id == TPS65911_REG_VDDCTRL) && | ||
1059 | (tps65910_chip_id(mfd) == TPS65911))) { | ||
1060 | int op_reg_add = pmic->get_ctrl_reg(id) + 1; | ||
1061 | int sr_reg_add = pmic->get_ctrl_reg(id) + 2; | ||
1062 | int opvsel = tps65910_reg_read(pmic, op_reg_add); | ||
1063 | int srvsel = tps65910_reg_read(pmic, sr_reg_add); | ||
1064 | if (opvsel & VDD1_OP_CMD_MASK) { | ||
1065 | u8 reg_val = srvsel & VDD1_OP_SEL_MASK; | ||
1066 | ret = tps65910_reg_write(pmic, op_reg_add, reg_val); | ||
1067 | if (ret < 0) { | ||
1068 | dev_err(mfd->dev, | ||
1069 | "Error in configuring op register\n"); | ||
1070 | return ret; | ||
1071 | } | ||
1072 | } | ||
1073 | ret = tps65910_reg_write(pmic, sr_reg_add, 0); | ||
1074 | if (ret < 0) { | ||
1075 | dev_err(mfd->dev, "Error in settting sr register\n"); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | } | ||
1079 | |||
1080 | ret = tps65910_clear_bits(mfd, | ||
1081 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | ||
1082 | if (!ret) { | ||
1083 | if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) | ||
1084 | ret = tps65910_set_bits(mfd, | ||
1085 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1086 | else | ||
1087 | ret = tps65910_clear_bits(mfd, | ||
1088 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1089 | } | ||
1090 | if (ret < 0) | ||
1091 | dev_err(mfd->dev, | ||
1092 | "Error in configuring SLEEP register\n"); | ||
1093 | |||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
850 | static __devinit int tps65910_probe(struct platform_device *pdev) | 1097 | static __devinit int tps65910_probe(struct platform_device *pdev) |
851 | { | 1098 | { |
852 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | 1099 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
@@ -877,11 +1124,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
877 | case TPS65910: | 1124 | case TPS65910: |
878 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; | 1125 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; |
879 | pmic->num_regulators = ARRAY_SIZE(tps65910_regs); | 1126 | pmic->num_regulators = ARRAY_SIZE(tps65910_regs); |
1127 | pmic->ext_sleep_control = tps65910_ext_sleep_control; | ||
880 | info = tps65910_regs; | 1128 | info = tps65910_regs; |
881 | break; | 1129 | break; |
882 | case TPS65911: | 1130 | case TPS65911: |
883 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; | 1131 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; |
884 | pmic->num_regulators = ARRAY_SIZE(tps65911_regs); | 1132 | pmic->num_regulators = ARRAY_SIZE(tps65911_regs); |
1133 | pmic->ext_sleep_control = tps65911_ext_sleep_control; | ||
885 | info = tps65911_regs; | 1134 | info = tps65911_regs; |
886 | break; | 1135 | break; |
887 | default: | 1136 | default: |
@@ -926,7 +1175,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
926 | 1175 | ||
927 | pmic->desc[i].name = info->name; | 1176 | pmic->desc[i].name = info->name; |
928 | pmic->desc[i].id = i; | 1177 | pmic->desc[i].id = i; |
929 | pmic->desc[i].n_voltages = info->table_len; | 1178 | pmic->desc[i].n_voltages = info->n_voltages; |
930 | 1179 | ||
931 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { | 1180 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { |
932 | pmic->desc[i].ops = &tps65910_ops_dcdc; | 1181 | pmic->desc[i].ops = &tps65910_ops_dcdc; |
@@ -944,6 +1193,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
944 | pmic->desc[i].ops = &tps65911_ops; | 1193 | pmic->desc[i].ops = &tps65911_ops; |
945 | } | 1194 | } |
946 | 1195 | ||
1196 | err = tps65910_set_ext_sleep_config(pmic, i, | ||
1197 | pmic_plat_data->regulator_ext_sleep_control[i]); | ||
1198 | /* | ||
1199 | * Failing on regulator for configuring externally control | ||
1200 | * is not a serious issue, just throw warning. | ||
1201 | */ | ||
1202 | if (err < 0) | ||
1203 | dev_warn(tps65910->dev, | ||
1204 | "Failed to initialise ext control config\n"); | ||
1205 | |||
947 | pmic->desc[i].type = REGULATOR_VOLTAGE; | 1206 | pmic->desc[i].type = REGULATOR_VOLTAGE; |
948 | pmic->desc[i].owner = THIS_MODULE; | 1207 | pmic->desc[i].owner = THIS_MODULE; |
949 | 1208 | ||
@@ -990,6 +1249,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev) | |||
990 | return 0; | 1249 | return 0; |
991 | } | 1250 | } |
992 | 1251 | ||
1252 | static void tps65910_shutdown(struct platform_device *pdev) | ||
1253 | { | ||
1254 | struct tps65910_reg *pmic = platform_get_drvdata(pdev); | ||
1255 | int i; | ||
1256 | |||
1257 | /* | ||
1258 | * Before bootloader jumps to kernel, it makes sure that required | ||
1259 | * external control signals are in desired state so that given rails | ||
1260 | * can be configure accordingly. | ||
1261 | * If rails are configured to be controlled from external control | ||
1262 | * then before shutting down/rebooting the system, the external | ||
1263 | * control configuration need to be remove from the rails so that | ||
1264 | * its output will be available as per register programming even | ||
1265 | * if external controls are removed. This is require when the POR | ||
1266 | * value of the control signals are not in active state and before | ||
1267 | * bootloader initializes it, the system requires the rail output | ||
1268 | * to be active for booting. | ||
1269 | */ | ||
1270 | for (i = 0; i < pmic->num_regulators; i++) { | ||
1271 | int err; | ||
1272 | if (!pmic->rdev[i]) | ||
1273 | continue; | ||
1274 | |||
1275 | err = tps65910_set_ext_sleep_config(pmic, i, 0); | ||
1276 | if (err < 0) | ||
1277 | dev_err(&pdev->dev, | ||
1278 | "Error in clearing external control\n"); | ||
1279 | } | ||
1280 | } | ||
1281 | |||
993 | static struct platform_driver tps65910_driver = { | 1282 | static struct platform_driver tps65910_driver = { |
994 | .driver = { | 1283 | .driver = { |
995 | .name = "tps65910-pmic", | 1284 | .name = "tps65910-pmic", |
@@ -997,6 +1286,7 @@ static struct platform_driver tps65910_driver = { | |||
997 | }, | 1286 | }, |
998 | .probe = tps65910_probe, | 1287 | .probe = tps65910_probe, |
999 | .remove = __devexit_p(tps65910_remove), | 1288 | .remove = __devexit_p(tps65910_remove), |
1289 | .shutdown = tps65910_shutdown, | ||
1000 | }; | 1290 | }; |
1001 | 1291 | ||
1002 | static int __init tps65910_init(void) | 1292 | static int __init tps65910_init(void) |
@@ -1012,6 +1302,6 @@ static void __exit tps65910_cleanup(void) | |||
1012 | module_exit(tps65910_cleanup); | 1302 | module_exit(tps65910_cleanup); |
1013 | 1303 | ||
1014 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | 1304 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); |
1015 | MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); | 1305 | MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver"); |
1016 | MODULE_LICENSE("GPL v2"); | 1306 | MODULE_LICENSE("GPL v2"); |
1017 | MODULE_ALIAS("platform:tps65910-pmic"); | 1307 | MODULE_ALIAS("platform:tps65910-pmic"); |
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index da00d88f94b7..b36799b1f530 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c | |||
@@ -114,10 +114,7 @@ struct tps65912_reg { | |||
114 | struct mutex io_lock; | 114 | struct mutex io_lock; |
115 | int mode; | 115 | int mode; |
116 | int (*get_ctrl_reg)(int); | 116 | int (*get_ctrl_reg)(int); |
117 | int dcdc1_range; | 117 | int dcdc_range[TPS65912_NUM_DCDC]; |
118 | int dcdc2_range; | ||
119 | int dcdc3_range; | ||
120 | int dcdc4_range; | ||
121 | int pwm_mode_reg; | 118 | int pwm_mode_reg; |
122 | int eco_reg; | 119 | int eco_reg; |
123 | }; | 120 | }; |
@@ -125,46 +122,31 @@ struct tps65912_reg { | |||
125 | static int tps65912_get_range(struct tps65912_reg *pmic, int id) | 122 | static int tps65912_get_range(struct tps65912_reg *pmic, int id) |
126 | { | 123 | { |
127 | struct tps65912 *mfd = pmic->mfd; | 124 | struct tps65912 *mfd = pmic->mfd; |
128 | 125 | int range; | |
129 | if (id > TPS65912_REG_DCDC4) | ||
130 | return 0; | ||
131 | 126 | ||
132 | switch (id) { | 127 | switch (id) { |
133 | case TPS65912_REG_DCDC1: | 128 | case TPS65912_REG_DCDC1: |
134 | pmic->dcdc1_range = tps65912_reg_read(mfd, | 129 | range = tps65912_reg_read(mfd, TPS65912_DCDC1_LIMIT); |
135 | TPS65912_DCDC1_LIMIT); | 130 | break; |
136 | if (pmic->dcdc1_range < 0) | ||
137 | return pmic->dcdc1_range; | ||
138 | pmic->dcdc1_range = (pmic->dcdc1_range & | ||
139 | DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT; | ||
140 | return pmic->dcdc1_range; | ||
141 | case TPS65912_REG_DCDC2: | 131 | case TPS65912_REG_DCDC2: |
142 | pmic->dcdc2_range = tps65912_reg_read(mfd, | 132 | range = tps65912_reg_read(mfd, TPS65912_DCDC2_LIMIT); |
143 | TPS65912_DCDC2_LIMIT); | 133 | break; |
144 | if (pmic->dcdc2_range < 0) | ||
145 | return pmic->dcdc2_range; | ||
146 | pmic->dcdc2_range = (pmic->dcdc2_range & | ||
147 | DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT; | ||
148 | return pmic->dcdc2_range; | ||
149 | case TPS65912_REG_DCDC3: | 134 | case TPS65912_REG_DCDC3: |
150 | pmic->dcdc3_range = tps65912_reg_read(mfd, | 135 | range = tps65912_reg_read(mfd, TPS65912_DCDC3_LIMIT); |
151 | TPS65912_DCDC3_LIMIT); | 136 | break; |
152 | if (pmic->dcdc3_range < 0) | ||
153 | return pmic->dcdc3_range; | ||
154 | pmic->dcdc3_range = (pmic->dcdc3_range & | ||
155 | DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT; | ||
156 | return pmic->dcdc3_range; | ||
157 | case TPS65912_REG_DCDC4: | 137 | case TPS65912_REG_DCDC4: |
158 | pmic->dcdc4_range = tps65912_reg_read(mfd, | 138 | range = tps65912_reg_read(mfd, TPS65912_DCDC4_LIMIT); |
159 | TPS65912_DCDC4_LIMIT); | 139 | break; |
160 | if (pmic->dcdc4_range < 0) | ||
161 | return pmic->dcdc4_range; | ||
162 | pmic->dcdc4_range = (pmic->dcdc4_range & | ||
163 | DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT; | ||
164 | return pmic->dcdc4_range; | ||
165 | default: | 140 | default: |
166 | return 0; | 141 | return 0; |
167 | } | 142 | } |
143 | |||
144 | if (range >= 0) | ||
145 | range = (range & DCDC_LIMIT_RANGE_MASK) | ||
146 | >> DCDC_LIMIT_RANGE_SHIFT; | ||
147 | |||
148 | pmic->dcdc_range[id] = range; | ||
149 | return range; | ||
168 | } | 150 | } |
169 | 151 | ||
170 | static unsigned long tps65912_vsel_to_uv_range0(u8 vsel) | 152 | static unsigned long tps65912_vsel_to_uv_range0(u8 vsel) |
@@ -219,146 +201,30 @@ static unsigned long tps65912_vsel_to_uv_ldo(u8 vsel) | |||
219 | 201 | ||
220 | static int tps65912_get_ctrl_register(int id) | 202 | static int tps65912_get_ctrl_register(int id) |
221 | { | 203 | { |
222 | switch (id) { | 204 | if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) |
223 | case TPS65912_REG_DCDC1: | 205 | return id * 3 + TPS65912_DCDC1_AVS; |
224 | return TPS65912_DCDC1_AVS; | 206 | else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) |
225 | case TPS65912_REG_DCDC2: | 207 | return id - TPS65912_REG_LDO5 + TPS65912_LDO5; |
226 | return TPS65912_DCDC2_AVS; | 208 | else |
227 | case TPS65912_REG_DCDC3: | ||
228 | return TPS65912_DCDC3_AVS; | ||
229 | case TPS65912_REG_DCDC4: | ||
230 | return TPS65912_DCDC4_AVS; | ||
231 | case TPS65912_REG_LDO1: | ||
232 | return TPS65912_LDO1_AVS; | ||
233 | case TPS65912_REG_LDO2: | ||
234 | return TPS65912_LDO2_AVS; | ||
235 | case TPS65912_REG_LDO3: | ||
236 | return TPS65912_LDO3_AVS; | ||
237 | case TPS65912_REG_LDO4: | ||
238 | return TPS65912_LDO4_AVS; | ||
239 | case TPS65912_REG_LDO5: | ||
240 | return TPS65912_LDO5; | ||
241 | case TPS65912_REG_LDO6: | ||
242 | return TPS65912_LDO6; | ||
243 | case TPS65912_REG_LDO7: | ||
244 | return TPS65912_LDO7; | ||
245 | case TPS65912_REG_LDO8: | ||
246 | return TPS65912_LDO8; | ||
247 | case TPS65912_REG_LDO9: | ||
248 | return TPS65912_LDO9; | ||
249 | case TPS65912_REG_LDO10: | ||
250 | return TPS65912_LDO10; | ||
251 | default: | ||
252 | return -EINVAL; | 209 | return -EINVAL; |
253 | } | ||
254 | } | 210 | } |
255 | 211 | ||
256 | static int tps65912_get_dcdc_sel_register(struct tps65912_reg *pmic, int id) | 212 | static int tps65912_get_sel_register(struct tps65912_reg *pmic, int id) |
257 | { | 213 | { |
258 | struct tps65912 *mfd = pmic->mfd; | 214 | struct tps65912 *mfd = pmic->mfd; |
259 | int opvsel = 0, sr = 0; | 215 | int opvsel; |
260 | u8 reg = 0; | 216 | u8 reg = 0; |
261 | 217 | ||
262 | if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_DCDC4) | 218 | if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) { |
263 | return -EINVAL; | 219 | opvsel = tps65912_reg_read(mfd, id * 3 + TPS65912_DCDC1_OP); |
264 | 220 | if (opvsel & OP_SELREG_MASK) | |
265 | switch (id) { | 221 | reg = id * 3 + TPS65912_DCDC1_AVS; |
266 | case TPS65912_REG_DCDC1: | ||
267 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC1_OP); | ||
268 | sr = ((opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT); | ||
269 | if (sr) | ||
270 | reg = TPS65912_DCDC1_AVS; | ||
271 | else | ||
272 | reg = TPS65912_DCDC1_OP; | ||
273 | break; | ||
274 | case TPS65912_REG_DCDC2: | ||
275 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC2_OP); | ||
276 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
277 | if (sr) | ||
278 | reg = TPS65912_DCDC2_AVS; | ||
279 | else | ||
280 | reg = TPS65912_DCDC2_OP; | ||
281 | break; | ||
282 | case TPS65912_REG_DCDC3: | ||
283 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC3_OP); | ||
284 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
285 | if (sr) | ||
286 | reg = TPS65912_DCDC3_AVS; | ||
287 | else | ||
288 | reg = TPS65912_DCDC3_OP; | ||
289 | break; | ||
290 | case TPS65912_REG_DCDC4: | ||
291 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC4_OP); | ||
292 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
293 | if (sr) | ||
294 | reg = TPS65912_DCDC4_AVS; | ||
295 | else | 222 | else |
296 | reg = TPS65912_DCDC4_OP; | 223 | reg = id * 3 + TPS65912_DCDC1_OP; |
297 | break; | 224 | } else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) { |
298 | } | 225 | reg = id - TPS65912_REG_LDO5 + TPS65912_LDO5; |
299 | return reg; | 226 | } else { |
300 | } | ||
301 | |||
302 | static int tps65912_get_ldo_sel_register(struct tps65912_reg *pmic, int id) | ||
303 | { | ||
304 | struct tps65912 *mfd = pmic->mfd; | ||
305 | int opvsel = 0, sr = 0; | ||
306 | u8 reg = 0; | ||
307 | |||
308 | if (id < TPS65912_REG_LDO1 || id > TPS65912_REG_LDO10) | ||
309 | return -EINVAL; | 227 | return -EINVAL; |
310 | |||
311 | switch (id) { | ||
312 | case TPS65912_REG_LDO1: | ||
313 | opvsel = tps65912_reg_read(mfd, TPS65912_LDO1_OP); | ||
314 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
315 | if (sr) | ||
316 | reg = TPS65912_LDO1_AVS; | ||
317 | else | ||
318 | reg = TPS65912_LDO1_OP; | ||
319 | break; | ||
320 | case TPS65912_REG_LDO2: | ||
321 | opvsel = tps65912_reg_read(mfd, TPS65912_LDO2_OP); | ||
322 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
323 | if (sr) | ||
324 | reg = TPS65912_LDO2_AVS; | ||
325 | else | ||
326 | reg = TPS65912_LDO2_OP; | ||
327 | break; | ||
328 | case TPS65912_REG_LDO3: | ||
329 | opvsel = tps65912_reg_read(mfd, TPS65912_LDO3_OP); | ||
330 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
331 | if (sr) | ||
332 | reg = TPS65912_LDO3_AVS; | ||
333 | else | ||
334 | reg = TPS65912_LDO3_OP; | ||
335 | break; | ||
336 | case TPS65912_REG_LDO4: | ||
337 | opvsel = tps65912_reg_read(mfd, TPS65912_LDO4_OP); | ||
338 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | ||
339 | if (sr) | ||
340 | reg = TPS65912_LDO4_AVS; | ||
341 | else | ||
342 | reg = TPS65912_LDO4_OP; | ||
343 | break; | ||
344 | case TPS65912_REG_LDO5: | ||
345 | reg = TPS65912_LDO5; | ||
346 | break; | ||
347 | case TPS65912_REG_LDO6: | ||
348 | reg = TPS65912_LDO6; | ||
349 | break; | ||
350 | case TPS65912_REG_LDO7: | ||
351 | reg = TPS65912_LDO7; | ||
352 | break; | ||
353 | case TPS65912_REG_LDO8: | ||
354 | reg = TPS65912_LDO8; | ||
355 | break; | ||
356 | case TPS65912_REG_LDO9: | ||
357 | reg = TPS65912_LDO9; | ||
358 | break; | ||
359 | case TPS65912_REG_LDO10: | ||
360 | reg = TPS65912_LDO10; | ||
361 | break; | ||
362 | } | 228 | } |
363 | 229 | ||
364 | return reg; | 230 | return reg; |
@@ -506,151 +372,83 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev) | |||
506 | return mode; | 372 | return mode; |
507 | } | 373 | } |
508 | 374 | ||
509 | static int tps65912_get_voltage_dcdc(struct regulator_dev *dev) | 375 | static int tps65912_list_voltage_dcdc(struct regulator_dev *dev, |
376 | unsigned selector) | ||
510 | { | 377 | { |
511 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | 378 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); |
512 | struct tps65912 *mfd = pmic->mfd; | 379 | int range, voltage = 0, id = rdev_get_id(dev); |
513 | int id = rdev_get_id(dev), voltage = 0, range; | ||
514 | int opvsel = 0, avsel = 0, sr, vsel; | ||
515 | 380 | ||
516 | switch (id) { | 381 | if (id > TPS65912_REG_DCDC4) |
517 | case TPS65912_REG_DCDC1: | ||
518 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC1_OP); | ||
519 | avsel = tps65912_reg_read(mfd, TPS65912_DCDC1_AVS); | ||
520 | range = pmic->dcdc1_range; | ||
521 | break; | ||
522 | case TPS65912_REG_DCDC2: | ||
523 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC2_OP); | ||
524 | avsel = tps65912_reg_read(mfd, TPS65912_DCDC2_AVS); | ||
525 | range = pmic->dcdc2_range; | ||
526 | break; | ||
527 | case TPS65912_REG_DCDC3: | ||
528 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC3_OP); | ||
529 | avsel = tps65912_reg_read(mfd, TPS65912_DCDC3_AVS); | ||
530 | range = pmic->dcdc3_range; | ||
531 | break; | ||
532 | case TPS65912_REG_DCDC4: | ||
533 | opvsel = tps65912_reg_read(mfd, TPS65912_DCDC4_OP); | ||
534 | avsel = tps65912_reg_read(mfd, TPS65912_DCDC4_AVS); | ||
535 | range = pmic->dcdc4_range; | ||
536 | break; | ||
537 | default: | ||
538 | return -EINVAL; | 382 | return -EINVAL; |
539 | } | ||
540 | 383 | ||
541 | sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; | 384 | range = pmic->dcdc_range[id]; |
542 | if (sr) | ||
543 | vsel = avsel; | ||
544 | else | ||
545 | vsel = opvsel; | ||
546 | vsel &= 0x3F; | ||
547 | 385 | ||
548 | switch (range) { | 386 | switch (range) { |
549 | case 0: | 387 | case 0: |
550 | /* 0.5 - 1.2875V in 12.5mV steps */ | 388 | /* 0.5 - 1.2875V in 12.5mV steps */ |
551 | voltage = tps65912_vsel_to_uv_range0(vsel); | 389 | voltage = tps65912_vsel_to_uv_range0(selector); |
552 | break; | 390 | break; |
553 | case 1: | 391 | case 1: |
554 | /* 0.7 - 1.4875V in 12.5mV steps */ | 392 | /* 0.7 - 1.4875V in 12.5mV steps */ |
555 | voltage = tps65912_vsel_to_uv_range1(vsel); | 393 | voltage = tps65912_vsel_to_uv_range1(selector); |
556 | break; | 394 | break; |
557 | case 2: | 395 | case 2: |
558 | /* 0.5 - 2.075V in 25mV steps */ | 396 | /* 0.5 - 2.075V in 25mV steps */ |
559 | voltage = tps65912_vsel_to_uv_range2(vsel); | 397 | voltage = tps65912_vsel_to_uv_range2(selector); |
560 | break; | 398 | break; |
561 | case 3: | 399 | case 3: |
562 | /* 0.5 - 3.8V in 50mV steps */ | 400 | /* 0.5 - 3.8V in 50mV steps */ |
563 | voltage = tps65912_vsel_to_uv_range3(vsel); | 401 | voltage = tps65912_vsel_to_uv_range3(selector); |
564 | break; | 402 | break; |
565 | } | 403 | } |
566 | return voltage; | 404 | return voltage; |
567 | } | 405 | } |
568 | 406 | ||
569 | static int tps65912_set_voltage_dcdc(struct regulator_dev *dev, | 407 | static int tps65912_get_voltage_dcdc(struct regulator_dev *dev) |
570 | unsigned selector) | ||
571 | { | 408 | { |
572 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | 409 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); |
573 | struct tps65912 *mfd = pmic->mfd; | 410 | struct tps65912 *mfd = pmic->mfd; |
574 | int id = rdev_get_id(dev); | 411 | int id = rdev_get_id(dev); |
575 | int value; | 412 | int reg, vsel; |
576 | u8 reg; | ||
577 | |||
578 | reg = tps65912_get_dcdc_sel_register(pmic, id); | ||
579 | value = tps65912_reg_read(mfd, reg); | ||
580 | value &= 0xC0; | ||
581 | return tps65912_reg_write(mfd, reg, selector | value); | ||
582 | } | ||
583 | 413 | ||
584 | static int tps65912_get_voltage_ldo(struct regulator_dev *dev) | 414 | reg = tps65912_get_sel_register(pmic, id); |
585 | { | 415 | if (reg < 0) |
586 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | 416 | return reg; |
587 | struct tps65912 *mfd = pmic->mfd; | ||
588 | int id = rdev_get_id(dev); | ||
589 | int vsel = 0; | ||
590 | u8 reg; | ||
591 | 417 | ||
592 | reg = tps65912_get_ldo_sel_register(pmic, id); | ||
593 | vsel = tps65912_reg_read(mfd, reg); | 418 | vsel = tps65912_reg_read(mfd, reg); |
594 | vsel &= 0x3F; | 419 | vsel &= 0x3F; |
595 | 420 | ||
596 | return tps65912_vsel_to_uv_ldo(vsel); | 421 | return tps65912_list_voltage_dcdc(dev, vsel); |
597 | } | 422 | } |
598 | 423 | ||
599 | static int tps65912_set_voltage_ldo(struct regulator_dev *dev, | 424 | static int tps65912_set_voltage_sel(struct regulator_dev *dev, |
600 | unsigned selector) | 425 | unsigned selector) |
601 | { | 426 | { |
602 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | 427 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); |
603 | struct tps65912 *mfd = pmic->mfd; | 428 | struct tps65912 *mfd = pmic->mfd; |
604 | int id = rdev_get_id(dev), reg, value; | 429 | int id = rdev_get_id(dev); |
430 | int value; | ||
431 | u8 reg; | ||
605 | 432 | ||
606 | reg = tps65912_get_ldo_sel_register(pmic, id); | 433 | reg = tps65912_get_sel_register(pmic, id); |
607 | value = tps65912_reg_read(mfd, reg); | 434 | value = tps65912_reg_read(mfd, reg); |
608 | value &= 0xC0; | 435 | value &= 0xC0; |
609 | return tps65912_reg_write(mfd, reg, selector | value); | 436 | return tps65912_reg_write(mfd, reg, selector | value); |
610 | } | 437 | } |
611 | 438 | ||
612 | static int tps65912_list_voltage_dcdc(struct regulator_dev *dev, | 439 | static int tps65912_get_voltage_ldo(struct regulator_dev *dev) |
613 | unsigned selector) | ||
614 | { | 440 | { |
615 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); | 441 | struct tps65912_reg *pmic = rdev_get_drvdata(dev); |
616 | int range, voltage = 0, id = rdev_get_id(dev); | 442 | struct tps65912 *mfd = pmic->mfd; |
443 | int id = rdev_get_id(dev); | ||
444 | int vsel = 0; | ||
445 | u8 reg; | ||
617 | 446 | ||
618 | switch (id) { | 447 | reg = tps65912_get_sel_register(pmic, id); |
619 | case TPS65912_REG_DCDC1: | 448 | vsel = tps65912_reg_read(mfd, reg); |
620 | range = pmic->dcdc1_range; | 449 | vsel &= 0x3F; |
621 | break; | ||
622 | case TPS65912_REG_DCDC2: | ||
623 | range = pmic->dcdc2_range; | ||
624 | break; | ||
625 | case TPS65912_REG_DCDC3: | ||
626 | range = pmic->dcdc3_range; | ||
627 | break; | ||
628 | case TPS65912_REG_DCDC4: | ||
629 | range = pmic->dcdc4_range; | ||
630 | break; | ||
631 | default: | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | 450 | ||
635 | switch (range) { | 451 | return tps65912_vsel_to_uv_ldo(vsel); |
636 | case 0: | ||
637 | /* 0.5 - 1.2875V in 12.5mV steps */ | ||
638 | voltage = tps65912_vsel_to_uv_range0(selector); | ||
639 | break; | ||
640 | case 1: | ||
641 | /* 0.7 - 1.4875V in 12.5mV steps */ | ||
642 | voltage = tps65912_vsel_to_uv_range1(selector); | ||
643 | break; | ||
644 | case 2: | ||
645 | /* 0.5 - 2.075V in 25mV steps */ | ||
646 | voltage = tps65912_vsel_to_uv_range2(selector); | ||
647 | break; | ||
648 | case 3: | ||
649 | /* 0.5 - 3.8V in 50mV steps */ | ||
650 | voltage = tps65912_vsel_to_uv_range3(selector); | ||
651 | break; | ||
652 | } | ||
653 | return voltage; | ||
654 | } | 452 | } |
655 | 453 | ||
656 | static int tps65912_list_voltage_ldo(struct regulator_dev *dev, | 454 | static int tps65912_list_voltage_ldo(struct regulator_dev *dev, |
@@ -672,7 +470,7 @@ static struct regulator_ops tps65912_ops_dcdc = { | |||
672 | .set_mode = tps65912_set_mode, | 470 | .set_mode = tps65912_set_mode, |
673 | .get_mode = tps65912_get_mode, | 471 | .get_mode = tps65912_get_mode, |
674 | .get_voltage = tps65912_get_voltage_dcdc, | 472 | .get_voltage = tps65912_get_voltage_dcdc, |
675 | .set_voltage_sel = tps65912_set_voltage_dcdc, | 473 | .set_voltage_sel = tps65912_set_voltage_sel, |
676 | .list_voltage = tps65912_list_voltage_dcdc, | 474 | .list_voltage = tps65912_list_voltage_dcdc, |
677 | }; | 475 | }; |
678 | 476 | ||
@@ -682,7 +480,7 @@ static struct regulator_ops tps65912_ops_ldo = { | |||
682 | .enable = tps65912_reg_enable, | 480 | .enable = tps65912_reg_enable, |
683 | .disable = tps65912_reg_disable, | 481 | .disable = tps65912_reg_disable, |
684 | .get_voltage = tps65912_get_voltage_ldo, | 482 | .get_voltage = tps65912_get_voltage_ldo, |
685 | .set_voltage_sel = tps65912_set_voltage_ldo, | 483 | .set_voltage_sel = tps65912_set_voltage_sel, |
686 | .list_voltage = tps65912_list_voltage_ldo, | 484 | .list_voltage = tps65912_list_voltage_ldo, |
687 | }; | 485 | }; |
688 | 486 | ||
@@ -770,22 +568,12 @@ static struct platform_driver tps65912_driver = { | |||
770 | .remove = __devexit_p(tps65912_remove), | 568 | .remove = __devexit_p(tps65912_remove), |
771 | }; | 569 | }; |
772 | 570 | ||
773 | /** | ||
774 | * tps65912_init | ||
775 | * | ||
776 | * Module init function | ||
777 | */ | ||
778 | static int __init tps65912_init(void) | 571 | static int __init tps65912_init(void) |
779 | { | 572 | { |
780 | return platform_driver_register(&tps65912_driver); | 573 | return platform_driver_register(&tps65912_driver); |
781 | } | 574 | } |
782 | subsys_initcall(tps65912_init); | 575 | subsys_initcall(tps65912_init); |
783 | 576 | ||
784 | /** | ||
785 | * tps65912_cleanup | ||
786 | * | ||
787 | * Module exit function | ||
788 | */ | ||
789 | static void __exit tps65912_cleanup(void) | 577 | static void __exit tps65912_cleanup(void) |
790 | { | 578 | { |
791 | platform_driver_unregister(&tps65912_driver); | 579 | platform_driver_unregister(&tps65912_driver); |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 181a2cfe180c..9cdfc389ca26 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -14,8 +14,11 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/of.h> | ||
18 | #include <linux/of_device.h> | ||
17 | #include <linux/regulator/driver.h> | 19 | #include <linux/regulator/driver.h> |
18 | #include <linux/regulator/machine.h> | 20 | #include <linux/regulator/machine.h> |
21 | #include <linux/regulator/of_regulator.h> | ||
19 | #include <linux/i2c/twl.h> | 22 | #include <linux/i2c/twl.h> |
20 | 23 | ||
21 | 24 | ||
@@ -58,6 +61,16 @@ struct twlreg_info { | |||
58 | 61 | ||
59 | /* chip specific features */ | 62 | /* chip specific features */ |
60 | unsigned long features; | 63 | unsigned long features; |
64 | |||
65 | /* | ||
66 | * optional override functions for voltage set/get | ||
67 | * these are currently only used for SMPS regulators | ||
68 | */ | ||
69 | int (*get_voltage)(void *data); | ||
70 | int (*set_voltage)(void *data, int target_uV); | ||
71 | |||
72 | /* data passed from board for external get/set voltage */ | ||
73 | void *data; | ||
61 | }; | 74 | }; |
62 | 75 | ||
63 | 76 | ||
@@ -522,15 +535,25 @@ twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
522 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 535 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
523 | int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); | 536 | int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); |
524 | 537 | ||
525 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030, | 538 | if (info->set_voltage) { |
526 | vsel); | 539 | return info->set_voltage(info->data, min_uV); |
540 | } else { | ||
541 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, | ||
542 | VREG_VOLTAGE_SMPS_4030, vsel); | ||
543 | } | ||
544 | |||
527 | return 0; | 545 | return 0; |
528 | } | 546 | } |
529 | 547 | ||
530 | static int twl4030smps_get_voltage(struct regulator_dev *rdev) | 548 | static int twl4030smps_get_voltage(struct regulator_dev *rdev) |
531 | { | 549 | { |
532 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 550 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
533 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | 551 | int vsel; |
552 | |||
553 | if (info->get_voltage) | ||
554 | return info->get_voltage(info->data); | ||
555 | |||
556 | vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | ||
534 | VREG_VOLTAGE_SMPS_4030); | 557 | VREG_VOLTAGE_SMPS_4030); |
535 | 558 | ||
536 | return vsel * 12500 + 600000; | 559 | return vsel * 12500 + 600000; |
@@ -541,6 +564,32 @@ static struct regulator_ops twl4030smps_ops = { | |||
541 | .get_voltage = twl4030smps_get_voltage, | 564 | .get_voltage = twl4030smps_get_voltage, |
542 | }; | 565 | }; |
543 | 566 | ||
567 | static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV, | ||
568 | int max_uV, unsigned *selector) | ||
569 | { | ||
570 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
571 | |||
572 | if (info->set_voltage) | ||
573 | return info->set_voltage(info->data, min_uV); | ||
574 | |||
575 | return -ENODEV; | ||
576 | } | ||
577 | |||
578 | static int twl6030coresmps_get_voltage(struct regulator_dev *rdev) | ||
579 | { | ||
580 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
581 | |||
582 | if (info->get_voltage) | ||
583 | return info->get_voltage(info->data); | ||
584 | |||
585 | return -ENODEV; | ||
586 | } | ||
587 | |||
588 | static struct regulator_ops twl6030coresmps_ops = { | ||
589 | .set_voltage = twl6030coresmps_set_voltage, | ||
590 | .get_voltage = twl6030coresmps_get_voltage, | ||
591 | }; | ||
592 | |||
544 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | 593 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) |
545 | { | 594 | { |
546 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 595 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
@@ -755,12 +804,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
755 | case 0: | 804 | case 0: |
756 | if (min_uV == 0) | 805 | if (min_uV == 0) |
757 | vsel = 0; | 806 | vsel = 0; |
758 | else if ((min_uV >= 600000) && (max_uV <= 1300000)) { | 807 | else if ((min_uV >= 600000) && (min_uV <= 1300000)) { |
808 | int calc_uV; | ||
759 | vsel = (min_uV - 600000) / 125; | 809 | vsel = (min_uV - 600000) / 125; |
760 | if (vsel % 100) | 810 | if (vsel % 100) |
761 | vsel += 100; | 811 | vsel += 100; |
762 | vsel /= 100; | 812 | vsel /= 100; |
763 | vsel++; | 813 | vsel++; |
814 | calc_uV = twl6030smps_list_voltage(rdev, vsel); | ||
815 | if (calc_uV > max_uV) | ||
816 | return -EINVAL; | ||
764 | } | 817 | } |
765 | /* Values 1..57 for vsel are linear and can be calculated | 818 | /* Values 1..57 for vsel are linear and can be calculated |
766 | * values 58..62 are non linear. | 819 | * values 58..62 are non linear. |
@@ -781,12 +834,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
781 | case SMPS_OFFSET_EN: | 834 | case SMPS_OFFSET_EN: |
782 | if (min_uV == 0) | 835 | if (min_uV == 0) |
783 | vsel = 0; | 836 | vsel = 0; |
784 | else if ((min_uV >= 700000) && (max_uV <= 1420000)) { | 837 | else if ((min_uV >= 700000) && (min_uV <= 1420000)) { |
838 | int calc_uV; | ||
785 | vsel = (min_uV - 700000) / 125; | 839 | vsel = (min_uV - 700000) / 125; |
786 | if (vsel % 100) | 840 | if (vsel % 100) |
787 | vsel += 100; | 841 | vsel += 100; |
788 | vsel /= 100; | 842 | vsel /= 100; |
789 | vsel++; | 843 | vsel++; |
844 | calc_uV = twl6030smps_list_voltage(rdev, vsel); | ||
845 | if (calc_uV > max_uV) | ||
846 | return -EINVAL; | ||
790 | } | 847 | } |
791 | /* Values 1..57 for vsel are linear and can be calculated | 848 | /* Values 1..57 for vsel are linear and can be calculated |
792 | * values 58..62 are non linear. | 849 | * values 58..62 are non linear. |
@@ -819,7 +876,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
819 | if (min_uV == 0) | 876 | if (min_uV == 0) |
820 | vsel = 0; | 877 | vsel = 0; |
821 | else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { | 878 | else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { |
822 | vsel = (min_uV - 1852000) / 386; | 879 | vsel = (min_uV - 2161000) / 386; |
823 | if (vsel % 100) | 880 | if (vsel % 100) |
824 | vsel += 100; | 881 | vsel += 100; |
825 | vsel /= 100; | 882 | vsel /= 100; |
@@ -866,7 +923,8 @@ static struct regulator_ops twlsmps_ops = { | |||
866 | TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ | 923 | TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ |
867 | 0x0, TWL6030, twl6030fixed_ops) | 924 | 0x0, TWL6030, twl6030fixed_ops) |
868 | 925 | ||
869 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ | 926 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ |
927 | static struct twlreg_info TWL4030_INFO_##label = { \ | ||
870 | .base = offset, \ | 928 | .base = offset, \ |
871 | .id = num, \ | 929 | .id = num, \ |
872 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ | 930 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ |
@@ -884,7 +942,7 @@ static struct regulator_ops twlsmps_ops = { | |||
884 | } | 942 | } |
885 | 943 | ||
886 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ | 944 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ |
887 | { \ | 945 | static struct twlreg_info TWL4030_INFO_##label = { \ |
888 | .base = offset, \ | 946 | .base = offset, \ |
889 | .id = num, \ | 947 | .id = num, \ |
890 | .delay = turnon_delay, \ | 948 | .delay = turnon_delay, \ |
@@ -898,7 +956,19 @@ static struct regulator_ops twlsmps_ops = { | |||
898 | }, \ | 956 | }, \ |
899 | } | 957 | } |
900 | 958 | ||
901 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ | 959 | #define TWL6030_ADJUSTABLE_SMPS(label) \ |
960 | static struct twlreg_info TWL6030_INFO_##label = { \ | ||
961 | .desc = { \ | ||
962 | .name = #label, \ | ||
963 | .id = TWL6030_REG_##label, \ | ||
964 | .ops = &twl6030coresmps_ops, \ | ||
965 | .type = REGULATOR_VOLTAGE, \ | ||
966 | .owner = THIS_MODULE, \ | ||
967 | }, \ | ||
968 | } | ||
969 | |||
970 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ | ||
971 | static struct twlreg_info TWL6030_INFO_##label = { \ | ||
902 | .base = offset, \ | 972 | .base = offset, \ |
903 | .min_mV = min_mVolts, \ | 973 | .min_mV = min_mVolts, \ |
904 | .max_mV = max_mVolts, \ | 974 | .max_mV = max_mVolts, \ |
@@ -912,7 +982,8 @@ static struct regulator_ops twlsmps_ops = { | |||
912 | }, \ | 982 | }, \ |
913 | } | 983 | } |
914 | 984 | ||
915 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ | 985 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ |
986 | static struct twlreg_info TWL6025_INFO_##label = { \ | ||
916 | .base = offset, \ | 987 | .base = offset, \ |
917 | .min_mV = min_mVolts, \ | 988 | .min_mV = min_mVolts, \ |
918 | .max_mV = max_mVolts, \ | 989 | .max_mV = max_mVolts, \ |
@@ -927,7 +998,8 @@ static struct regulator_ops twlsmps_ops = { | |||
927 | } | 998 | } |
928 | 999 | ||
929 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ | 1000 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ |
930 | family, operations) { \ | 1001 | family, operations) \ |
1002 | static struct twlreg_info TWLFIXED_INFO_##label = { \ | ||
931 | .base = offset, \ | 1003 | .base = offset, \ |
932 | .id = num, \ | 1004 | .id = num, \ |
933 | .min_mV = mVolts, \ | 1005 | .min_mV = mVolts, \ |
@@ -943,7 +1015,8 @@ static struct regulator_ops twlsmps_ops = { | |||
943 | }, \ | 1015 | }, \ |
944 | } | 1016 | } |
945 | 1017 | ||
946 | #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) { \ | 1018 | #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \ |
1019 | static struct twlreg_info TWLRES_INFO_##label = { \ | ||
947 | .base = offset, \ | 1020 | .base = offset, \ |
948 | .delay = turnon_delay, \ | 1021 | .delay = turnon_delay, \ |
949 | .desc = { \ | 1022 | .desc = { \ |
@@ -955,7 +1028,8 @@ static struct regulator_ops twlsmps_ops = { | |||
955 | }, \ | 1028 | }, \ |
956 | } | 1029 | } |
957 | 1030 | ||
958 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) { \ | 1031 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ |
1032 | static struct twlreg_info TWLSMPS_INFO_##label = { \ | ||
959 | .base = offset, \ | 1033 | .base = offset, \ |
960 | .min_mV = 600, \ | 1034 | .min_mV = 600, \ |
961 | .max_mV = 2100, \ | 1035 | .max_mV = 2100, \ |
@@ -973,59 +1047,59 @@ static struct regulator_ops twlsmps_ops = { | |||
973 | * We list regulators here if systems need some level of | 1047 | * We list regulators here if systems need some level of |
974 | * software control over them after boot. | 1048 | * software control over them after boot. |
975 | */ | 1049 | */ |
976 | static struct twlreg_info twl_regs[] = { | 1050 | TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08); |
977 | TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08), | 1051 | TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08); |
978 | TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08), | 1052 | TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08); |
979 | TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08), | 1053 | TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08); |
980 | TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08), | 1054 | TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08); |
981 | TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08), | 1055 | TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08); |
982 | TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08), | 1056 | TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08); |
983 | TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08), | 1057 | TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00); |
984 | TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00), | 1058 | TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08); |
985 | TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08), | 1059 | TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00); |
986 | TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00), | 1060 | TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08); |
987 | TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08), | 1061 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08); |
988 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08), | 1062 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08); |
989 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), | 1063 | TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08); |
990 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), | 1064 | TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08); |
991 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), | 1065 | /* VUSBCP is managed *only* by the USB subchip */ |
992 | TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08), | 1066 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ |
993 | TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08), | 1067 | /* Turnon-delay and remap configuration values for 6030 are not |
994 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), | 1068 | verified since the specification is not public */ |
995 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), | 1069 | TWL6030_ADJUSTABLE_SMPS(VDD1); |
996 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08), | 1070 | TWL6030_ADJUSTABLE_SMPS(VDD2); |
997 | /* VUSBCP is managed *only* by the USB subchip */ | 1071 | TWL6030_ADJUSTABLE_SMPS(VDD3); |
998 | 1072 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300); | |
999 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ | 1073 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300); |
1000 | /* Turnon-delay and remap configuration values for 6030 are not | 1074 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300); |
1001 | verified since the specification is not public */ | 1075 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300); |
1002 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300), | 1076 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300); |
1003 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300), | 1077 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300); |
1004 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300), | 1078 | /* 6025 are renamed compared to 6030 versions */ |
1005 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300), | 1079 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300); |
1006 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300), | 1080 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300); |
1007 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300), | 1081 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300); |
1008 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0), | 1082 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300); |
1009 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0), | 1083 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300); |
1010 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0), | 1084 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); |
1011 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0), | 1085 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
1012 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0), | 1086 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
1013 | 1087 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | |
1014 | /* 6025 are renamed compared to 6030 versions */ | 1088 | TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08); |
1015 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300), | 1089 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
1016 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300), | 1090 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
1017 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300), | 1091 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
1018 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300), | 1092 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08); |
1019 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300), | 1093 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0); |
1020 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300), | 1094 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0); |
1021 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300), | 1095 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); |
1022 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300), | 1096 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
1023 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300), | 1097 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
1024 | 1098 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | |
1025 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34), | 1099 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0); |
1026 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10), | 1100 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
1027 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16), | 1101 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
1028 | }; | 1102 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
1029 | 1103 | ||
1030 | static u8 twl_get_smps_offset(void) | 1104 | static u8 twl_get_smps_offset(void) |
1031 | { | 1105 | { |
@@ -1045,29 +1119,116 @@ static u8 twl_get_smps_mult(void) | |||
1045 | return value; | 1119 | return value; |
1046 | } | 1120 | } |
1047 | 1121 | ||
1122 | #define TWL_OF_MATCH(comp, family, label) \ | ||
1123 | { \ | ||
1124 | .compatible = comp, \ | ||
1125 | .data = &family##_INFO_##label, \ | ||
1126 | } | ||
1127 | |||
1128 | #define TWL4030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL4030, label) | ||
1129 | #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label) | ||
1130 | #define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label) | ||
1131 | #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label) | ||
1132 | #define TWLRES_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLRES, label) | ||
1133 | #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label) | ||
1134 | |||
1135 | static const struct of_device_id twl_of_match[] __devinitconst = { | ||
1136 | TWL4030_OF_MATCH("ti,twl4030-vaux1", VAUX1), | ||
1137 | TWL4030_OF_MATCH("ti,twl4030-vaux2", VAUX2_4030), | ||
1138 | TWL4030_OF_MATCH("ti,twl5030-vaux2", VAUX2), | ||
1139 | TWL4030_OF_MATCH("ti,twl4030-vaux3", VAUX3), | ||
1140 | TWL4030_OF_MATCH("ti,twl4030-vaux4", VAUX4), | ||
1141 | TWL4030_OF_MATCH("ti,twl4030-vmmc1", VMMC1), | ||
1142 | TWL4030_OF_MATCH("ti,twl4030-vmmc2", VMMC2), | ||
1143 | TWL4030_OF_MATCH("ti,twl4030-vpll1", VPLL1), | ||
1144 | TWL4030_OF_MATCH("ti,twl4030-vpll2", VPLL2), | ||
1145 | TWL4030_OF_MATCH("ti,twl4030-vsim", VSIM), | ||
1146 | TWL4030_OF_MATCH("ti,twl4030-vdac", VDAC), | ||
1147 | TWL4030_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | ||
1148 | TWL4030_OF_MATCH("ti,twl4030-vio", VIO), | ||
1149 | TWL4030_OF_MATCH("ti,twl4030-vdd1", VDD1), | ||
1150 | TWL4030_OF_MATCH("ti,twl4030-vdd2", VDD2), | ||
1151 | TWL6030_OF_MATCH("ti,twl6030-vdd1", VDD1), | ||
1152 | TWL6030_OF_MATCH("ti,twl6030-vdd2", VDD2), | ||
1153 | TWL6030_OF_MATCH("ti,twl6030-vdd3", VDD3), | ||
1154 | TWL6030_OF_MATCH("ti,twl6030-vaux1", VAUX1_6030), | ||
1155 | TWL6030_OF_MATCH("ti,twl6030-vaux2", VAUX2_6030), | ||
1156 | TWL6030_OF_MATCH("ti,twl6030-vaux3", VAUX3_6030), | ||
1157 | TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC), | ||
1158 | TWL6030_OF_MATCH("ti,twl6030-vpp", VPP), | ||
1159 | TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM), | ||
1160 | TWL6025_OF_MATCH("ti,twl6025-ldo2", LDO2), | ||
1161 | TWL6025_OF_MATCH("ti,twl6025-ldo4", LDO4), | ||
1162 | TWL6025_OF_MATCH("ti,twl6025-ldo3", LDO3), | ||
1163 | TWL6025_OF_MATCH("ti,twl6025-ldo5", LDO5), | ||
1164 | TWL6025_OF_MATCH("ti,twl6025-ldo1", LDO1), | ||
1165 | TWL6025_OF_MATCH("ti,twl6025-ldo7", LDO7), | ||
1166 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | ||
1167 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | ||
1168 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | ||
1169 | TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | ||
1170 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | ||
1171 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | ||
1172 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | ||
1173 | TWLFIXED_OF_MATCH("ti,twl4030-vusb3v1", VUSB3V1), | ||
1174 | TWLFIXED_OF_MATCH("ti,twl6030-vana", VANA), | ||
1175 | TWLFIXED_OF_MATCH("ti,twl6030-vcxio", VCXIO), | ||
1176 | TWLFIXED_OF_MATCH("ti,twl6030-vdac", VDAC), | ||
1177 | TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB), | ||
1178 | TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8), | ||
1179 | TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1), | ||
1180 | TWLRES_OF_MATCH("ti,twl6030-clk32kg", CLK32KG), | ||
1181 | TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3), | ||
1182 | TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4), | ||
1183 | TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO), | ||
1184 | {}, | ||
1185 | }; | ||
1186 | MODULE_DEVICE_TABLE(of, twl_of_match); | ||
1187 | |||
1048 | static int __devinit twlreg_probe(struct platform_device *pdev) | 1188 | static int __devinit twlreg_probe(struct platform_device *pdev) |
1049 | { | 1189 | { |
1050 | int i; | 1190 | int i, id; |
1051 | struct twlreg_info *info; | 1191 | struct twlreg_info *info; |
1052 | struct regulator_init_data *initdata; | 1192 | struct regulator_init_data *initdata; |
1053 | struct regulation_constraints *c; | 1193 | struct regulation_constraints *c; |
1054 | struct regulator_dev *rdev; | 1194 | struct regulator_dev *rdev; |
1055 | 1195 | struct twl_regulator_driver_data *drvdata; | |
1056 | for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { | 1196 | const struct of_device_id *match; |
1057 | if (twl_regs[i].desc.id != pdev->id) | 1197 | |
1058 | continue; | 1198 | match = of_match_device(twl_of_match, &pdev->dev); |
1059 | info = twl_regs + i; | 1199 | if (match) { |
1060 | break; | 1200 | info = match->data; |
1201 | id = info->desc.id; | ||
1202 | initdata = of_get_regulator_init_data(&pdev->dev, | ||
1203 | pdev->dev.of_node); | ||
1204 | drvdata = NULL; | ||
1205 | } else { | ||
1206 | id = pdev->id; | ||
1207 | initdata = pdev->dev.platform_data; | ||
1208 | for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { | ||
1209 | info = twl_of_match[i].data; | ||
1210 | if (!info || info->desc.id != id) | ||
1211 | continue; | ||
1212 | break; | ||
1213 | } | ||
1214 | drvdata = initdata->driver_data; | ||
1215 | if (!drvdata) | ||
1216 | return -EINVAL; | ||
1061 | } | 1217 | } |
1218 | |||
1062 | if (!info) | 1219 | if (!info) |
1063 | return -ENODEV; | 1220 | return -ENODEV; |
1064 | 1221 | ||
1065 | initdata = pdev->dev.platform_data; | ||
1066 | if (!initdata) | 1222 | if (!initdata) |
1067 | return -EINVAL; | 1223 | return -EINVAL; |
1068 | 1224 | ||
1069 | /* copy the features into regulator data */ | 1225 | if (drvdata) { |
1070 | info->features = (unsigned long)initdata->driver_data; | 1226 | /* copy the driver data into regulator data */ |
1227 | info->features = drvdata->features; | ||
1228 | info->data = drvdata->data; | ||
1229 | info->set_voltage = drvdata->set_voltage; | ||
1230 | info->get_voltage = drvdata->get_voltage; | ||
1231 | } | ||
1071 | 1232 | ||
1072 | /* Constrain board-specific capabilities according to what | 1233 | /* Constrain board-specific capabilities according to what |
1073 | * this driver and the chip itself can actually do. | 1234 | * this driver and the chip itself can actually do. |
@@ -1077,7 +1238,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1077 | c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | 1238 | c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE |
1078 | | REGULATOR_CHANGE_MODE | 1239 | | REGULATOR_CHANGE_MODE |
1079 | | REGULATOR_CHANGE_STATUS; | 1240 | | REGULATOR_CHANGE_STATUS; |
1080 | switch (pdev->id) { | 1241 | switch (id) { |
1081 | case TWL4030_REG_VIO: | 1242 | case TWL4030_REG_VIO: |
1082 | case TWL4030_REG_VDD1: | 1243 | case TWL4030_REG_VDD1: |
1083 | case TWL4030_REG_VDD2: | 1244 | case TWL4030_REG_VDD2: |
@@ -1091,7 +1252,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1091 | break; | 1252 | break; |
1092 | } | 1253 | } |
1093 | 1254 | ||
1094 | switch (pdev->id) { | 1255 | switch (id) { |
1095 | case TWL6025_REG_SMPS3: | 1256 | case TWL6025_REG_SMPS3: |
1096 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) | 1257 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) |
1097 | info->flags |= SMPS_EXTENDED_EN; | 1258 | info->flags |= SMPS_EXTENDED_EN; |
@@ -1112,7 +1273,8 @@ static int __devinit twlreg_probe(struct platform_device *pdev) | |||
1112 | break; | 1273 | break; |
1113 | } | 1274 | } |
1114 | 1275 | ||
1115 | rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, NULL); | 1276 | rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, |
1277 | pdev->dev.of_node); | ||
1116 | if (IS_ERR(rdev)) { | 1278 | if (IS_ERR(rdev)) { |
1117 | dev_err(&pdev->dev, "can't register %s, %ld\n", | 1279 | dev_err(&pdev->dev, "can't register %s, %ld\n", |
1118 | info->desc.name, PTR_ERR(rdev)); | 1280 | info->desc.name, PTR_ERR(rdev)); |
@@ -1149,8 +1311,11 @@ static struct platform_driver twlreg_driver = { | |||
1149 | /* NOTE: short name, to work around driver model truncation of | 1311 | /* NOTE: short name, to work around driver model truncation of |
1150 | * "twl_regulator.12" (and friends) to "twl_regulator.1". | 1312 | * "twl_regulator.12" (and friends) to "twl_regulator.1". |
1151 | */ | 1313 | */ |
1152 | .driver.name = "twl_reg", | 1314 | .driver = { |
1153 | .driver.owner = THIS_MODULE, | 1315 | .name = "twl_reg", |
1316 | .owner = THIS_MODULE, | ||
1317 | .of_match_table = of_match_ptr(twl_of_match), | ||
1318 | }, | ||
1154 | }; | 1319 | }; |
1155 | 1320 | ||
1156 | static int __init twlreg_init(void) | 1321 | static int __init twlreg_init(void) |
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 6894009d815a..ab1e183a74b5 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
@@ -186,7 +186,7 @@ static int wm8350_isink_get_current(struct regulator_dev *rdev) | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | return (isink_cur[val] + 50) / 100; | 189 | return DIV_ROUND_CLOSEST(isink_cur[val], 100); |
190 | } | 190 | } |
191 | 191 | ||
192 | /* turn on ISINK followed by DCDC */ | 192 | /* turn on ISINK followed by DCDC */ |
@@ -1544,7 +1544,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, | |||
1544 | return -ENOMEM; | 1544 | return -ENOMEM; |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | led->isink_consumer.dev = &pdev->dev; | 1547 | led->isink_consumer.dev_name = dev_name(&pdev->dev); |
1548 | led->isink_consumer.supply = "led_isink"; | 1548 | led->isink_consumer.supply = "led_isink"; |
1549 | led->isink_init.num_consumer_supplies = 1; | 1549 | led->isink_init.num_consumer_supplies = 1; |
1550 | led->isink_init.consumer_supplies = &led->isink_consumer; | 1550 | led->isink_init.consumer_supplies = &led->isink_consumer; |
@@ -1559,7 +1559,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, | |||
1559 | return ret; | 1559 | return ret; |
1560 | } | 1560 | } |
1561 | 1561 | ||
1562 | led->dcdc_consumer.dev = &pdev->dev; | 1562 | led->dcdc_consumer.dev_name = dev_name(&pdev->dev); |
1563 | led->dcdc_consumer.supply = "led_vcc"; | 1563 | led->dcdc_consumer.supply = "led_vcc"; |
1564 | led->dcdc_init.num_consumer_supplies = 1; | 1564 | led->dcdc_init.num_consumer_supplies = 1; |
1565 | led->dcdc_init.consumer_supplies = &led->dcdc_consumer; | 1565 | led->dcdc_init.consumer_supplies = &led->dcdc_consumer; |
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 706f39563a7b..8477153780b6 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c | |||
@@ -78,14 +78,14 @@ static int wm8400_ldo_set_voltage(struct regulator_dev *dev, | |||
78 | 78 | ||
79 | if (min_uV < 1700000) { | 79 | if (min_uV < 1700000) { |
80 | /* Steps of 50mV from 900mV; */ | 80 | /* Steps of 50mV from 900mV; */ |
81 | val = (min_uV - 850001) / 50000; | 81 | val = DIV_ROUND_UP(min_uV - 900000, 50000); |
82 | 82 | ||
83 | if ((val * 50000) + 900000 > max_uV) | 83 | if ((val * 50000) + 900000 > max_uV) |
84 | return -EINVAL; | 84 | return -EINVAL; |
85 | BUG_ON((val * 50000) + 900000 < min_uV); | 85 | BUG_ON((val * 50000) + 900000 < min_uV); |
86 | } else { | 86 | } else { |
87 | /* Steps of 100mV from 1700mV */ | 87 | /* Steps of 100mV from 1700mV */ |
88 | val = ((min_uV - 1600001) / 100000); | 88 | val = DIV_ROUND_UP(min_uV - 1700000, 100000); |
89 | 89 | ||
90 | if ((val * 100000) + 1700000 > max_uV) | 90 | if ((val * 100000) + 1700000 > max_uV) |
91 | return -EINVAL; | 91 | return -EINVAL; |
@@ -168,7 +168,7 @@ static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, | |||
168 | if (min_uV < 850000) | 168 | if (min_uV < 850000) |
169 | return -EINVAL; | 169 | return -EINVAL; |
170 | 170 | ||
171 | val = (min_uV - 825001) / 25000; | 171 | val = DIV_ROUND_UP(min_uV - 850000, 25000); |
172 | 172 | ||
173 | if (850000 + (25000 * val) > max_uV) | 173 | if (850000 + (25000 * val) > max_uV) |
174 | return -EINVAL; | 174 | return -EINVAL; |
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 435e335d6e67..75ed402d9f43 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
@@ -241,7 +241,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) | |||
241 | if (!pdata) | 241 | if (!pdata) |
242 | return -ENODEV; | 242 | return -ENODEV; |
243 | 243 | ||
244 | ldo = kzalloc(sizeof(struct wm8994_ldo), GFP_KERNEL); | 244 | ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL); |
245 | if (ldo == NULL) { | 245 | if (ldo == NULL) { |
246 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | 246 | dev_err(&pdev->dev, "Unable to allocate private data\n"); |
247 | return -ENOMEM; | 247 | return -ENOMEM; |
@@ -285,7 +285,6 @@ err_gpio: | |||
285 | if (gpio_is_valid(ldo->enable)) | 285 | if (gpio_is_valid(ldo->enable)) |
286 | gpio_free(ldo->enable); | 286 | gpio_free(ldo->enable); |
287 | err: | 287 | err: |
288 | kfree(ldo); | ||
289 | return ret; | 288 | return ret; |
290 | } | 289 | } |
291 | 290 | ||
@@ -298,7 +297,6 @@ static __devexit int wm8994_ldo_remove(struct platform_device *pdev) | |||
298 | regulator_unregister(ldo->regulator); | 297 | regulator_unregister(ldo->regulator); |
299 | if (gpio_is_valid(ldo->enable)) | 298 | if (gpio_is_valid(ldo->enable)) |
300 | gpio_free(ldo->enable); | 299 | gpio_free(ldo->enable); |
301 | kfree(ldo); | ||
302 | 300 | ||
303 | return 0; | 301 | return 0; |
304 | } | 302 | } |