diff options
35 files changed, 3035 insertions, 894 deletions
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..ab06474e5eb6 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -10,43 +10,49 @@ 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/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.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 b06a2399587c..82505fcb8d43 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/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 80ecafef1bc3..62dcd0a432bb 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
@@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) | |||
254 | 254 | ||
255 | return num; | 255 | return num; |
256 | } | 256 | } |
257 | EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt); | ||
257 | 258 | ||
258 | struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( | 259 | struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( |
259 | struct platform_device *pdev, struct mc13xxx_regulator *regulators, | 260 | struct platform_device *pdev, struct mc13xxx_regulator *regulators, |
@@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( | |||
291 | 292 | ||
292 | return data; | 293 | return data; |
293 | } | 294 | } |
295 | EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt); | ||
294 | #endif | 296 | #endif |
295 | 297 | ||
296 | MODULE_LICENSE("GPL v2"); | 298 | MODULE_LICENSE("GPL v2"); |
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 70b7b1f4f000..60846e00c167 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 5c15ba01e9c7..3d1370f9bc7f 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/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 | } |
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index d0cb12eba402..76700b5eee92 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h | |||
@@ -768,6 +768,12 @@ | |||
768 | /* Max number of TPS65910/11 regulators */ | 768 | /* Max number of TPS65910/11 regulators */ |
769 | #define TPS65910_NUM_REGS 13 | 769 | #define TPS65910_NUM_REGS 13 |
770 | 770 | ||
771 | /* External sleep controls through EN1/EN2/EN3/SLEEP inputs */ | ||
772 | #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 | ||
773 | #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2 | ||
774 | #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4 | ||
775 | #define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x8 | ||
776 | |||
771 | /** | 777 | /** |
772 | * struct tps65910_board | 778 | * struct tps65910_board |
773 | * Board platform data may be used to initialize regulators. | 779 | * Board platform data may be used to initialize regulators. |
@@ -779,6 +785,7 @@ struct tps65910_board { | |||
779 | int irq_base; | 785 | int irq_base; |
780 | int vmbch_threshold; | 786 | int vmbch_threshold; |
781 | int vmbch2_threshold; | 787 | int vmbch2_threshold; |
788 | unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS]; | ||
782 | struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; | 789 | struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; |
783 | }; | 790 | }; |
784 | 791 | ||
diff --git a/include/linux/regulator/tps62360.h b/include/linux/regulator/tps62360.h new file mode 100644 index 000000000000..6a5c1b2c751e --- /dev/null +++ b/include/linux/regulator/tps62360.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * tps62360.h -- TI tps62360 | ||
3 | * | ||
4 | * Interface for regulator driver for TI TPS62360 Processor core supply | ||
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 modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef __LINUX_REGULATOR_TPS62360_H | ||
27 | #define __LINUX_REGULATOR_TPS62360_H | ||
28 | |||
29 | #include <linux/regulator/machine.h> | ||
30 | |||
31 | /* | ||
32 | * struct tps62360_regulator_platform_data - tps62360 regulator platform data. | ||
33 | * | ||
34 | * @reg_init_data: The regulator init data. | ||
35 | * @en_force_pwm: Enable force pwm or not. | ||
36 | * @en_discharge: Enable discharge the output capacitor via internal | ||
37 | * register. | ||
38 | * @en_internal_pulldn: internal pull down enable or not. | ||
39 | * @vsel0_gpio: Gpio number for vsel0. It should be -1 if this is tied with | ||
40 | * fixed logic. | ||
41 | * @vsel1_gpio: Gpio number for vsel1. It should be -1 if this is tied with | ||
42 | * fixed logic. | ||
43 | * @vsel0_def_state: Default state of vsel0. 1 if it is high else 0. | ||
44 | * @vsel1_def_state: Default state of vsel1. 1 if it is high else 0. | ||
45 | */ | ||
46 | struct tps62360_regulator_platform_data { | ||
47 | struct regulator_init_data reg_init_data; | ||
48 | bool en_force_pwm; | ||
49 | bool en_discharge; | ||
50 | bool en_internal_pulldn; | ||
51 | int vsel0_gpio; | ||
52 | int vsel1_gpio; | ||
53 | int vsel0_def_state; | ||
54 | int vsel1_def_state; | ||
55 | }; | ||
56 | |||
57 | #endif /* __LINUX_REGULATOR_TPS62360_H */ | ||